├── .gitignore ├── LICENSE ├── README.md ├── package-lock.json ├── package.json ├── packages ├── async-storage │ ├── README.md │ ├── package.json │ └── src │ │ ├── core.js │ │ ├── core.macos.js │ │ ├── core.native.js │ │ ├── core.sketch.js │ │ ├── core.web.js │ │ ├── core.windows.js │ │ └── index.js ├── core │ ├── README.md │ ├── lib │ │ └── index.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── @types │ │ │ └── react-primitives │ │ │ │ └── index.d.ts │ │ ├── Core.ts │ │ ├── index.ts │ │ └── modules │ │ │ └── Platform │ │ │ ├── Platform.ts │ │ │ ├── core.figma.ts │ │ │ ├── core.native.ts │ │ │ ├── core.sketch.ts │ │ │ ├── core.ts │ │ │ ├── core.web.ts │ │ │ └── index.ts │ ├── tsconfig.json │ └── tsconfig.module.json ├── datetimepicker │ ├── README.md │ ├── package.json │ └── src │ │ ├── common │ │ └── index.js │ │ ├── core.js │ │ ├── core.native.js │ │ ├── core.windows.js │ │ └── index.js ├── expo-notifications │ └── package.json ├── figma │ ├── README.md │ ├── package.json │ ├── src │ │ ├── components │ │ │ └── Text.tsx │ │ ├── figma │ │ │ ├── index.ts │ │ │ └── widget.ts │ │ ├── index.ts │ │ └── utils │ │ │ ├── index.ts │ │ │ └── props.ts │ └── tsconfig.json ├── lottie-react-native │ └── README.md ├── lottie │ └── README.md ├── native │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── @types │ │ │ └── react-primitives │ │ │ │ └── index.d.ts │ │ ├── Core.ts │ │ ├── context.tsx │ │ ├── index.ts │ │ └── modules │ │ │ ├── AccessibilityInfo │ │ │ ├── core.ts │ │ │ └── index.ts │ │ │ ├── ActivityIndicator │ │ │ ├── core.ts │ │ │ └── index.ts │ │ │ ├── Button │ │ │ ├── core.tsx │ │ │ └── index.ts │ │ │ ├── FlatList │ │ │ ├── core.tsx │ │ │ └── index.ts │ │ │ ├── KeyboardAvoidingView │ │ │ ├── core.native.ts │ │ │ ├── core.ts │ │ │ ├── core.web.ts │ │ │ └── index.ts │ │ │ ├── Modal │ │ │ ├── core.native.ts │ │ │ ├── core.ts │ │ │ ├── core.web.ts │ │ │ └── index.ts │ │ │ ├── PixelRatio │ │ │ ├── core.ts │ │ │ └── index.ts │ │ │ ├── SafeAreaView │ │ │ ├── core.native.ts │ │ │ ├── core.ts │ │ │ ├── core.web.ts │ │ │ └── index.ts │ │ │ ├── ScrollView │ │ │ ├── core.native.ts │ │ │ ├── core.ts │ │ │ ├── core.web.ts │ │ │ └── index.ts │ │ │ ├── TextInput │ │ │ ├── core.native.ts │ │ │ ├── core.sketch.tsx │ │ │ ├── core.ts │ │ │ ├── core.web.tsx │ │ │ └── index.ts │ │ │ └── use-window-dimensions │ │ │ ├── core.native.ts │ │ │ ├── core.sketch.ts │ │ │ ├── core.ts │ │ │ ├── core.web.ts │ │ │ ├── index.js │ │ │ └── index.ts │ ├── tsconfig.json │ └── tsconfig.module-json └── svg │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── src │ ├── @types │ │ └── react-native-svg │ │ │ └── index.d.ts │ ├── cjs │ │ ├── common │ │ │ └── index.tsx │ │ ├── core.native.ts │ │ ├── core.sketch.ts │ │ ├── core.ts │ │ └── core.web.ts │ └── esm │ │ ├── common │ │ └── index.tsx │ │ ├── core.native.ts │ │ ├── core.sketch.ts │ │ ├── core.ts │ │ └── core.web.ts │ ├── tsconfig.json │ └── tsconfig.module.json └── tsconfig.base.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | 106 | # Additions 107 | 108 | .DS_Store 109 | 110 | packages/*/lib 111 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Elemental Design System 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-platform 2 | 3 | Cross-platform React interoperability APIs, component wrappers and polyfills for all React (Native) platforms. 4 | 5 | This exists primarily as an **experimental** and **unofficial** community-led project to explore and help push forward standards and progress for **React as a platform**. 6 | 7 | The project is inspired by and builds on top of Leland’s [`react-primitives`](https://github.com/lelandrichardson/react-primitives) project and Nicolas’s [`react-native-web`](https://github.com/necolas/react-native-web). While not integrated with, this may pull ideas/research from [`reactxp`](https://github.com/microsoft/reactxp). 8 | 9 | Please feel free to post any questions or proposals in issues, or feel free to contact me (via issues/Twitter). 10 | 11 | ## What is `@react-platform`? 12 | 13 | `@react-platform` is an `npm` package ecosystem of primitive components and APIs that can be used for cross-platform React codebases/libraries, with polyfills/fallbacks for platforms that don't have appropriate native/JS equivalents. 14 | 15 | As an example, `@react-platform/native` exports React Native components like `` and `` that fallback to `` on unsupported platforms. 16 | 17 | As this is in **alpha**, all versions are `0.x.x` and packages may be deprecated or change in the future. Where possible, we will try our best to follow semantic versioning and issue deprecation notices. 18 | 19 | ## Supported Platforms 20 | 21 | - [`react-dom`](https://github.com/facebook/react/tree/master/packages/react-dom) – React Web 22 | - [`react-native`](https://github.com/facebook/react-native) – React Native – iOS/Android 23 | - [`react-native-web`](https://github.com/necolas/react-native-web) – React Native Web 24 | - [`react-sketchapp`](https://github.com/airbnb/react-sketchapp) – React Sketch.app 25 | - [`react-figma`](https://github.com/react-figma/react-figma) – React Figma 26 | - [`react-native-windows`](https://github.com/microsoft/react-native-windows) – React Native Windows 27 | - [`react-native-macos`](https://github.com/microsoft/react-native-macos) – React Native macOS (no primitives support yet) 28 | 29 | ## Planned Platforms 30 | 31 | - [`react-native-desktop-qt`](https://github.com/status-im/react-native-desktop-qt) – React Native Qt port (Linux/macOS/Windows) 32 | 33 | ## Getting Started 34 | 35 | Example of `@react-platform/native`, a React Native interoperability layer with polyfills and primitive fallbacks: 36 | 37 | ```sh 38 | npm install --save @react-platform/native 39 | ``` 40 | 41 | On a React web, React Native or React Sketch.app project: 42 | 43 | ```js 44 | import { Text, View } from 'react-primitives'; 45 | import { ScrollView, SafeAreaView, TextInput } from '@react-platform/native'; 46 | 47 | export default function HomeScreen() { 48 | return ( 49 | 50 | 51 | 52 | Header Here 53 | 54 | 55 | 56 | console.log(value)}> 57 | 58 | 59 | ) 60 | } 61 | ``` 62 | 63 | ## Terminology 64 | 65 | ### Bridge 66 | 67 | Messaging tunnel between native code and JavaScript/React runtime. 68 | 69 | ### Layout 70 | 71 | Yoga layout (native Flexbox port). 72 | 73 | ### Threads 74 | 75 | Communication between threads is asynchronous. 76 | 77 | #### UI Thread (Platform UI) 78 | 79 | Bridge to layout thread with `view.appendChild(RCTView)` 80 | 81 | #### Layout Thread (Shadow Tree) 82 | 83 | React reconciliation tree. 84 | 85 | Bridge to JavaScript thread with `[..., createView(id, RCTView, ...)]` 86 | 87 | #### JavaScript Thread (React Runtime) 88 | 89 | ## Reading 90 | 91 | **Talks** 92 | 93 | - [React as a Platform: A path towards a truly cross-platform UI - Leland Richardson](https://www.youtube.com/watch?v=hNwQPJy-XZY) 94 | - [React Native's New Architecture - Parashuram N](https://www.youtube.com/watch?v=UcqRXTriUVI) 95 | 96 | 97 | ## Contributing 98 | 99 | Open to contributions :) 100 | 101 | ## License 102 | 103 | [MIT](./LICENSE.md) 104 | 105 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-platform/root", 3 | "private": true, 4 | "version": "1.0.0", 5 | "description": "Cross-platform React interoperability APIs, component wrappers and polyfills for all React (Native) platforms.", 6 | "main": "index.js", 7 | "scripts": { 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/elemental-design/react-platform.git" 13 | }, 14 | "keywords": [], 15 | "author": "", 16 | "license": "ISC", 17 | "bugs": { 18 | "url": "https://github.com/elemental-design/react-platform/issues" 19 | }, 20 | "homepage": "https://github.com/elemental-design/react-platform#readme", 21 | "dependencies": { 22 | "typescript": "^3.9.5" 23 | }, 24 | "devDependencies": { 25 | "@babel/cli": "^7.10.1", 26 | "@babel/core": "^7.10.2", 27 | "@babel/preset-react": "^7.10.1", 28 | "@types/node": "^16.11.26" 29 | }, 30 | "workspaces": [ 31 | "packages/*" 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /packages/async-storage/README.md: -------------------------------------------------------------------------------- 1 | # Async Storage 2 | 3 | Cross-platform `@react-native-community/async-storage` implementation. Defaults to an (unstable) JS only session/in-memory store. 4 | 5 | ## Platforms 6 | 7 | - `react-native-web` – React Web 8 | - `react-native` – React Native – iOS/Android 9 | - `react-native-windows` – React Native Windows 10 | - `react-native-macos` – React Native macOS 11 | - `react-sketchapp` – React Sketch.app 12 | - TODO: `react-figma` – React Figma 13 | - Use https://www.figma.com/plugin-docs/api/figma-clientStorage/ or https://www.figma.com/plugin-docs/api/properties/nodes-setplugindata/ 14 | -------------------------------------------------------------------------------- /packages/async-storage/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-platform/async-storage", 3 | "version": "0.0.1", 4 | "description": "", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "MIT", 12 | "devDependencies": { 13 | "@react-native-community/async-storage": "^1.10.1" 14 | }, 15 | "peerDependencies": { 16 | "@react-native-community/async-storage": ">=1" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/async-storage/src/core.js: -------------------------------------------------------------------------------- 1 | // This is an unstable JS only base implementation! Data is session only 2 | // TODO: Use console.warn in NODE_ENV=development 3 | const store = {}; 4 | 5 | // We're assuming that users are using async/await, so are throwing the error. Maybe reject is better though, or using async functions + throw + Babel transpiling this repo? 6 | 7 | const getItem = (_key, callback) => new Promise((resolve) => { 8 | try { 9 | const item = store[_key]; 10 | 11 | if (typeof callback === 'function') { 12 | callback(null, item) 13 | return; 14 | } 15 | resolve(item); 16 | } catch (err) { 17 | if (typeof callback === 'function') { 18 | callback(err) 19 | return; 20 | } 21 | throw err; 22 | } 23 | 24 | return; 25 | }); 26 | 27 | const setItem = (_key, value, callback) => new Promise((resolve) => { 28 | try { 29 | const item = store[key] = value; 30 | 31 | if (typeof callback === 'function') { 32 | callback(null); 33 | return; 34 | } 35 | resolve(item); 36 | } catch (err) { 37 | if (typeof callback === 'function') { 38 | callback(err); 39 | return; 40 | } 41 | throw err; 42 | } 43 | 44 | return; 45 | }); 46 | 47 | // Stubs for now to prevent crashes 48 | // TODO: Implement these 49 | const mergeItem = () => { }; 50 | const removeItem = () => { }; 51 | const getAllKeys = () => { }; 52 | const multiGet = () => { }; 53 | const multiSet = () => { }; 54 | const multiMerge = () => { }; 55 | const multiRemove = () => { }; 56 | const clear = () => { }; 57 | const flushGetRequests = () => { }; 58 | 59 | const useAsyncStorage = (_key) => { 60 | // TODO: Look into memoization, etc 61 | return ({ 62 | getItem, setItem, mergeItem, removeItem 63 | }); 64 | }; 65 | 66 | module.exports = { 67 | setItem, 68 | getItem, 69 | mergeItem, 70 | removeItem, 71 | getAllKeys, 72 | multiGet, 73 | multiSet, 74 | multiMerge, 75 | multiRemove, 76 | clear, 77 | flushGetRequests, 78 | useAsyncStorage, 79 | }; 80 | -------------------------------------------------------------------------------- /packages/async-storage/src/core.macos.js: -------------------------------------------------------------------------------- 1 | const AsyncStorage = require('./core.native'); 2 | 3 | module.exports = AsyncStorage; 4 | -------------------------------------------------------------------------------- /packages/async-storage/src/core.native.js: -------------------------------------------------------------------------------- 1 | const AsyncStorage = require('@react-native-community/async-storage'); 2 | 3 | module.exports = AsyncStorage; 4 | -------------------------------------------------------------------------------- /packages/async-storage/src/core.sketch.js: -------------------------------------------------------------------------------- 1 | const Settings = require('sketch/settings'); 2 | 3 | // TODO: Do we want to implement Settings.documentSettingForKey? Could store cool stuff like UUID -> file references in a document 4 | 5 | // We're assuming that users are using async/await, so are throwing the error. Maybe reject is better though, or using async functions + throw + Babel transpiling this repo? 6 | 7 | const getItem = (_key, callback) => new Promise((resolve) => { 8 | try { 9 | const item = Settings.settingForKey(String(_key)); 10 | 11 | if (typeof callback === 'function') { 12 | callback(null, item) 13 | return; 14 | } 15 | resolve(item); 16 | } catch(err) { 17 | if (typeof callback === 'function') { 18 | callback(err) 19 | return; 20 | } 21 | throw err; 22 | } 23 | 24 | return; 25 | }); 26 | 27 | const setItem = (_key, value, callback) => new Promise((resolve) => { 28 | try { 29 | const item = Settings.setSettingForKey(String(_key), value); 30 | 31 | if (typeof callback === 'function') { 32 | callback(null); 33 | return; 34 | } 35 | resolve(item); 36 | } catch(err) { 37 | if (typeof callback === 'function') { 38 | callback(err); 39 | return; 40 | } 41 | throw err; 42 | } 43 | 44 | return; 45 | }); 46 | 47 | // Stubs for now to prevent crashes 48 | // TODO: Implement these 49 | const mergeItem = () => {}; 50 | const removeItem = () => {}; 51 | const getAllKeys = () => {}; 52 | const multiGet = () => {}; 53 | const multiSet = () => {}; 54 | const multiMerge = () => {}; 55 | const multiRemove = () => {}; 56 | const clear = () => {}; 57 | const flushGetRequests = () => {}; 58 | 59 | // Experimental API: https://github.com/react-native-community/react-native-async-storage/issues/32 60 | const useAsyncStorage = (_key) => { 61 | // TODO: Look into memoization, etc 62 | return ({ 63 | getItem, setItem, mergeItem, removeItem 64 | }); 65 | }; 66 | 67 | module.exports = { 68 | setItem, 69 | getItem, 70 | mergeItem, 71 | removeItem, 72 | getAllKeys, 73 | multiGet, 74 | multiSet, 75 | multiMerge, 76 | multiRemove, 77 | clear, 78 | flushGetRequests, 79 | useAsyncStorage, 80 | }; 81 | -------------------------------------------------------------------------------- /packages/async-storage/src/core.web.js: -------------------------------------------------------------------------------- 1 | // We're assuming that the web module/main entrypoint will be resolved by the web build system 2 | // To fall back to the (previously in) react-native-web polyfill implementation 3 | const AsyncStorage = require('@react-native-community/async-storage'); 4 | 5 | module.exports = AsyncStorage; 6 | -------------------------------------------------------------------------------- /packages/async-storage/src/core.windows.js: -------------------------------------------------------------------------------- 1 | const AsyncStorage = require('./core.native'); 2 | 3 | module.exports = AsyncStorage; 4 | -------------------------------------------------------------------------------- /packages/async-storage/src/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elemental-design/react-platform/6d94f0f001da148205c21fad9191137161aafc2c/packages/async-storage/src/index.js -------------------------------------------------------------------------------- /packages/core/README.md: -------------------------------------------------------------------------------- 1 | # React Platform Core 2 | 3 | Please use https://github.com/lelandrichardson/react-primitives/ 4 | 5 | This is an **unstable**/**internal** package for now. 6 | -------------------------------------------------------------------------------- /packages/core/lib/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var ReactPrimitives; 3 | try { 4 | // @ts-ignore 5 | ReactPrimitives = require('react-primitives'); 6 | } 7 | catch (err) { 8 | // FIXME: Clean-up experimental stub if react-primitives isn't installed. 9 | // @ts-ignore 10 | ReactPrimitives = require('./Core'); 11 | } 12 | module.exports = ReactPrimitives; 13 | -------------------------------------------------------------------------------- /packages/core/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-platform/core", 3 | "version": "0.0.1", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@types/prop-types": { 8 | "version": "15.7.4", 9 | "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", 10 | "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==", 11 | "dev": true 12 | }, 13 | "@types/react": { 14 | "version": "17.0.39", 15 | "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.39.tgz", 16 | "integrity": "sha512-UVavlfAxDd/AgAacMa60Azl7ygyQNRwC/DsHZmKgNvPmRR5p70AJ5Q9EAmL2NWOJmeV+vVUI4IAP7GZrN8h8Ug==", 17 | "dev": true, 18 | "requires": { 19 | "@types/prop-types": "*", 20 | "@types/scheduler": "*", 21 | "csstype": "^3.0.2" 22 | } 23 | }, 24 | "@types/scheduler": { 25 | "version": "0.16.2", 26 | "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", 27 | "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", 28 | "dev": true 29 | }, 30 | "csstype": { 31 | "version": "3.0.11", 32 | "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz", 33 | "integrity": "sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==", 34 | "dev": true 35 | }, 36 | "typescript": { 37 | "version": "4.6.2", 38 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz", 39 | "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==", 40 | "dev": true 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-platform/core", 3 | "version": "0.0.3", 4 | "description": "Reserved for future use.", 5 | "main": "lib/index.js", 6 | "sketch": "lib/index.js", 7 | "module": "lib/index.js", 8 | "types": "lib/index.d.ts", 9 | "scripts": { 10 | "clean": "rm -rf lib/", 11 | "build:main": "tsc -p tsconfig.json", 12 | "build:module": "tsc -p tsconfig.module.json", 13 | "build:js": "npm run build:main # injection doesn’t support ESM && npm run build:module", 14 | "build:types": "tsc -d -p tsconfig.json", 15 | "build": "npm run clean && npm run build:js && npm run build:types", 16 | "dev": "tsc --watch -p tsconfig.json & tsc --watch -d -p tsconfig.json", 17 | "test": "echo \"Error: no test specified\" && exit 1" 18 | }, 19 | "keywords": [], 20 | "author": "Macintosh Helper ", 21 | "license": "MIT", 22 | "repository": { 23 | "type": "git", 24 | "url": "git+https://github.com/elemental-design/react-platform.git" 25 | }, 26 | "bugs": { 27 | "url": "https://github.com/elemental-design/react-platform/issues" 28 | }, 29 | "homepage": "https://github.com/elemental-design/react-platform#readme", 30 | "peerDependencies": { 31 | "react-primitives": ">= 0.8.1" 32 | }, 33 | "devDependencies": { 34 | "@types/react": "^17.0.39", 35 | "typescript": "^4.6.2" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/core/src/@types/react-primitives/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'react-primitives' { 2 | import { ComponentType } from 'react'; 3 | 4 | interface TouchableWithoutFeedbackPropsIOS { 5 | /** 6 | * *(Apple TV only)* TV preferred focus (see documentation for the View component). 7 | * 8 | * @platform ios 9 | */ 10 | hasTVPreferredFocus?: boolean; 11 | 12 | /** 13 | * *(Apple TV only)* Object with properties to control Apple TV parallax effects. 14 | * 15 | * enabled: If true, parallax effects are enabled. Defaults to true. 16 | * shiftDistanceX: Defaults to 2.0. 17 | * shiftDistanceY: Defaults to 2.0. 18 | * tiltAngle: Defaults to 0.05. 19 | * magnification: Defaults to 1.0. 20 | * pressMagnification: Defaults to 1.0. 21 | * pressDuration: Defaults to 0.3. 22 | * pressDelay: Defaults to 0.0. 23 | * 24 | * @platform ios 25 | */ 26 | tvParallaxProperties?: any; 27 | } 28 | 29 | interface AccessibilityProps { 30 | /** 31 | * When true, indicates that the view is an accessibility element. 32 | * By default, all the touchable elements are accessible. 33 | */ 34 | accessible?: boolean; 35 | 36 | /** 37 | * Provides an array of custom actions available for accessibility. 38 | */ 39 | accessibilityActions?: ReadonlyArray; 40 | 41 | /** 42 | * Overrides the text that's read by the screen reader when the user interacts with the element. By default, the 43 | * label is constructed by traversing all the children and accumulating all the Text nodes separated by space. 44 | */ 45 | accessibilityLabel?: string; 46 | 47 | /** 48 | * Accessibility Role tells a person using either VoiceOver on iOS or TalkBack on Android the type of element that is focused on. 49 | */ 50 | accessibilityRole?: any; 51 | /** 52 | * Accessibility State tells a person using either VoiceOver on iOS or TalkBack on Android the state of the element currently focused on. 53 | * @deprecated: accessibilityState available in 0.60+ 54 | */ 55 | accessibilityStates?: any[]; 56 | /** 57 | * Accessibility State tells a person using either VoiceOver on iOS or TalkBack on Android the state of the element currently focused on. 58 | */ 59 | accessibilityState?: any; 60 | /** 61 | * An accessibility hint helps users understand what will happen when they perform an action on the accessibility element when that result is not obvious from the accessibility label. 62 | */ 63 | accessibilityHint?: string; 64 | 65 | /** 66 | * When `accessible` is true, the system will try to invoke this function when the user performs an accessibility custom action. 67 | */ 68 | onAccessibilityAction?: (event: any) => void; 69 | } 70 | 71 | export interface TouchableWithoutFeedbackProps extends TouchableWithoutFeedbackPropsIOS, AccessibilityProps { 72 | /** 73 | * Delay in ms, from onPressIn, before onLongPress is called. 74 | */ 75 | delayLongPress?: number; 76 | 77 | /** 78 | * Delay in ms, from the start of the touch, before onPressIn is called. 79 | */ 80 | delayPressIn?: number; 81 | 82 | /** 83 | * Delay in ms, from the release of the touch, before onPressOut is called. 84 | */ 85 | delayPressOut?: number; 86 | 87 | /** 88 | * If true, disable all interactions for this component. 89 | */ 90 | disabled?: boolean; 91 | 92 | /** 93 | * This defines how far your touch can start away from the button. 94 | * This is added to pressRetentionOffset when moving off of the button. 95 | * NOTE The touch area never extends past the parent view bounds and 96 | * the Z-index of sibling views always takes precedence if a touch hits 97 | * two overlapping views. 98 | */ 99 | hitSlop?: any; 100 | 101 | /** 102 | * When `accessible` is true (which is the default) this may be called when 103 | * the OS-specific concept of "blur" occurs, meaning the element lost focus. 104 | * Some platforms may not have the concept of blur. 105 | */ 106 | onBlur?: (e: any) => void; 107 | 108 | /** 109 | * When `accessible` is true (which is the default) this may be called when 110 | * the OS-specific concept of "focus" occurs. Some platforms may not have 111 | * the concept of focus. 112 | */ 113 | onFocus?: (e: any) => void; 114 | 115 | /** 116 | * Invoked on mount and layout changes with 117 | * {nativeEvent: {layout: {x, y, width, height}}} 118 | */ 119 | onLayout?: (event: any) => void; 120 | 121 | onLongPress?: (event: any) => void; 122 | 123 | /** 124 | * Called when the touch is released, 125 | * but not if cancelled (e.g. by a scroll that steals the responder lock). 126 | */ 127 | onPress?: (event: any) => void; 128 | 129 | onPressIn?: (event: any) => void; 130 | 131 | onPressOut?: (event: any) => void; 132 | 133 | /** 134 | * //FIXME: not in doc but available in examples 135 | */ 136 | style?: Object; 137 | 138 | /** 139 | * When the scroll view is disabled, this defines how far your 140 | * touch may move off of the button, before deactivating the button. 141 | * Once deactivated, try moving it back and you'll see that the button 142 | * is once again reactivated! Move it back and forth several times 143 | * while the scroll view is disabled. Ensure you pass in a constant 144 | * to reduce memory allocations. 145 | */ 146 | pressRetentionOffset?: any; 147 | 148 | /** 149 | * Used to locate this view in end-to-end tests. 150 | */ 151 | testID?: string; 152 | } 153 | 154 | interface TouchableOpacityProps extends TouchableWithoutFeedbackProps { 155 | /** 156 | * Determines what the opacity of the wrapped view should be when touch is active. 157 | * Defaults to 0.2 158 | */ 159 | activeOpacity?: number; 160 | } 161 | 162 | 163 | 164 | export const Touchable: ComponentType; 165 | 166 | export type PlatformOSType = 'ios' | 'android' | 'web' | 'sketch' | 'vr' | 'figma'; 167 | export interface PlatformStatic { 168 | OS: PlatformOSType; 169 | Version: number | string; 170 | select(specifics: { [platform in PlatformOSType | 'default']?: T }): T; 171 | } 172 | export const Platform: PlatformStatic; 173 | } 174 | -------------------------------------------------------------------------------- /packages/core/src/Core.ts: -------------------------------------------------------------------------------- 1 | import * as Platform from './modules/Platform'; 2 | 3 | interface API { 4 | StyleSheet: any, 5 | View: any, 6 | Text: any, 7 | Image: any, 8 | Touchable: any, 9 | Easing: any, 10 | Animated: any, 11 | Dimensions: any, 12 | Platform: any, 13 | }; 14 | 15 | const Core: { 16 | StyleSheet: any, 17 | View: any, 18 | Text: any, 19 | Image: any, 20 | Touchable: any, 21 | Easing: any, 22 | Animated: any, 23 | Dimensions: any, 24 | PixelRatio: any, 25 | Platform: any, 26 | inject: (api: API) => void, 27 | } = { 28 | StyleSheet: null, 29 | View: null, 30 | Text: null, 31 | Image: null, 32 | Touchable: null, 33 | Easing: null, 34 | Animated: null, 35 | Dimensions: null, 36 | // PixelRatio: require('./modules/PixelRatio'), 37 | PixelRatio: null, 38 | Platform, 39 | inject: (api: API) => { 40 | if (api.StyleSheet) { 41 | Core.StyleSheet = api.StyleSheet; 42 | } 43 | if (api.View) { 44 | Core.View = api.View; 45 | } 46 | if (api.Text) { 47 | Core.Text = api.Text; 48 | } 49 | if (api.Image) { 50 | Core.Image = api.Image; 51 | } 52 | if (api.Touchable) { 53 | Core.Touchable = api.Touchable; 54 | } 55 | if (api.Easing) { 56 | Core.Easing = api.Easing; 57 | } 58 | if (api.Animated) { 59 | Core.Animated = api.Animated; 60 | } 61 | if (api.Dimensions) { 62 | Core.Dimensions = api.Dimensions; 63 | } 64 | if (api.Platform) { 65 | Core.Platform.inject(api.Platform); 66 | } 67 | }, 68 | }; 69 | 70 | export = Core; 71 | -------------------------------------------------------------------------------- /packages/core/src/index.ts: -------------------------------------------------------------------------------- 1 | let ReactPrimitives: { 2 | StyleSheet: any, 3 | View: any, 4 | Text: any, 5 | Image: any, 6 | Touchable: any, 7 | Easing: any, 8 | Animated: any, 9 | Dimensions: any, 10 | PixelRatio: any, 11 | Platform: any, 12 | inject: (_: any) => void, 13 | }; 14 | 15 | try { 16 | // @ts-ignore 17 | ReactPrimitives = require('react-primitives'); 18 | } catch (err) { 19 | // FIXME: Clean-up experimental stub if react-primitives isn't installed. 20 | // @ts-ignore 21 | ReactPrimitives = require('./Core'); 22 | } 23 | 24 | export = ReactPrimitives; -------------------------------------------------------------------------------- /packages/core/src/modules/Platform/Platform.ts: -------------------------------------------------------------------------------- 1 | const { hasOwnProperty } = Object.prototype; 2 | 3 | const Platform = { 4 | OS: 'unknown', 5 | Version: 0, 6 | select: (obj: any) => { 7 | if (hasOwnProperty.call(obj, Platform.OS)) { 8 | return obj[Platform.OS]; 9 | } 10 | return obj.default; 11 | }, 12 | inject: (platform: any) => { 13 | // Use bracket accessor notation as workaround for 14 | // https://github.com/facebook/metro-bundler/issues/27 15 | Platform['OS'] = platform.OS; // eslint-disable-line dot-notation 16 | Platform['Version'] = platform.Version; // eslint-disable-line dot-notation 17 | }, 18 | }; 19 | 20 | export { Platform }; 21 | export default Platform; 22 | -------------------------------------------------------------------------------- /packages/core/src/modules/Platform/core.figma.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import { Platform as PlatformSketch } from 'react-figma'; 3 | 4 | import Platform from './Platform'; 5 | 6 | Platform.inject({ 7 | OS: PlatformSketch.OS, 8 | Version: PlatformSketch.Version, 9 | }); 10 | 11 | export default Platform; 12 | -------------------------------------------------------------------------------- /packages/core/src/modules/Platform/core.native.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import { Platform as PlatformSketch } from 'react-native'; 3 | 4 | import Platform from './Platform'; 5 | 6 | Platform.inject({ 7 | OS: PlatformSketch.OS, 8 | Version: PlatformSketch.Version, 9 | }); 10 | 11 | export default Platform; 12 | -------------------------------------------------------------------------------- /packages/core/src/modules/Platform/core.sketch.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import { Platform as PlatformSketch } from 'react-sketchapp'; 3 | 4 | import Platform from './Platform'; 5 | 6 | Platform.inject({ 7 | OS: PlatformSketch.OS, 8 | Version: PlatformSketch.Version, 9 | }); 10 | 11 | export default Platform; 12 | -------------------------------------------------------------------------------- /packages/core/src/modules/Platform/core.ts: -------------------------------------------------------------------------------- 1 | export { default } from './core.web'; 2 | -------------------------------------------------------------------------------- /packages/core/src/modules/Platform/core.web.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import { Platform as PlatformSketch } from 'react-native-web'; 3 | 4 | import Platform from './Platform'; 5 | 6 | Platform.inject({ 7 | OS: PlatformSketch.OS, 8 | Version: PlatformSketch.Version, 9 | }); 10 | 11 | export default Platform; 12 | -------------------------------------------------------------------------------- /packages/core/src/modules/Platform/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './core'; 2 | -------------------------------------------------------------------------------- /packages/core/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "lib", 4 | "rootDir": "src", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "module": "commonjs", 7 | "target": "es5", 8 | 9 | "allowJs": true, 10 | "allowSyntheticDefaultImports": true, 11 | "esModuleInterop": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "isolatedModules": true, 14 | "jsx": "react-jsx", 15 | "moduleResolution": "node", 16 | "noFallthroughCasesInSwitch": true, 17 | "resolveJsonModule": true, 18 | "skipLibCheck": true, 19 | "strict": true 20 | }, 21 | "include": [ 22 | "src/**/*" 23 | ], 24 | "exclude": [ 25 | "node_modules" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/core/tsconfig.module.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "module": "esnext", 5 | "target": "es5", 6 | "outDir": "lib/module", 7 | }, 8 | 9 | } 10 | -------------------------------------------------------------------------------- /packages/datetimepicker/README.md: -------------------------------------------------------------------------------- 1 | # @react-platform/datetimepicker 2 | 3 | Cross-platform implementation of `@react-native-community/datetimepicker` 4 | 5 | ## Platforms 6 | 7 | - `react-native-web` – React Web 8 | - `react-native` – React Native – iOS/Android 9 | - `react-native-windows` – React Native Windows 10 | - TODO: `react-primitives` – React Primitives 11 | - TODO: `react-sketchapp` – React Sketch.app 12 | - TODO: `react-figma` – React Figma 13 | -------------------------------------------------------------------------------- /packages/datetimepicker/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-platform/datetimepicker", 3 | "version": "2.4.0", 4 | "description": "", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "MIT", 12 | "devDependencies": { 13 | "@react-native-community/datetimepicker": "^2.6.1" 14 | }, 15 | "peerDependencies": { 16 | "@react-native-community/datetimepicker": ">=1" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/datetimepicker/src/common/index.js: -------------------------------------------------------------------------------- 1 | // FIXME: This is a stub for now to try to prevent crashes from importing/rendering 2 | // Should probably standardise on Android/Material Design date picker first for this primitive 3 | // TODO: Split this up into multiple re-usable components 4 | // This should be injectable too, to override the web implementation 5 | const { View: DateTimePicker } = require('react-primitives'); 6 | 7 | module.exports = DateTimePicker; 8 | -------------------------------------------------------------------------------- /packages/datetimepicker/src/core.js: -------------------------------------------------------------------------------- 1 | const DateTimePicker = require('./common'); 2 | 3 | module.exports = DateTimePicker; 4 | -------------------------------------------------------------------------------- /packages/datetimepicker/src/core.native.js: -------------------------------------------------------------------------------- 1 | const DateTimePicker = require('@react-native-community/datetimepicker'); 2 | 3 | module.exports = DateTimePicker; 4 | -------------------------------------------------------------------------------- /packages/datetimepicker/src/core.windows.js: -------------------------------------------------------------------------------- 1 | const DateTimePicker = require('./core.native'); 2 | 3 | module.exports = DateTimePicker; 4 | -------------------------------------------------------------------------------- /packages/datetimepicker/src/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./core'); 2 | -------------------------------------------------------------------------------- /packages/expo-notifications/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-platform/expo-notifications", 3 | "version": "1.0.0", 4 | "description": "Cross-platform React SVG primitives", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "react-native-svg": "^12.1.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/figma/README.md: -------------------------------------------------------------------------------- 1 | # @react-platform/figma 2 | 3 | Figma React renderer 4 | 5 | ## TODO: 6 | 7 | - Renderer injection system - file/JSON based, Widget JSX API, react-figma, etc 8 | -------------------------------------------------------------------------------- /packages/figma/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "figma", 3 | "version": "0.0.1", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "build": "tsc", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "@figma/plugin-typings": "^1.85.0", 15 | "@figma/widget-typings": "^1.9.1", 16 | "@types/react": "^18.2.55", 17 | "@types/react-dom": "^18.2.19", 18 | "typescript": "^5.3.3" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/figma/src/components/Text.tsx: -------------------------------------------------------------------------------- 1 | import { Text as WidgetText } from '../figma/widget'; 2 | // const { Frame, AutoLayout, Text: _Text, SVG } = widget as WidgetAPI; 3 | 4 | import { extractTextStyles, extractSizeStyles, extractBaseProps, extractBlendProps, extractConstraintProps } from '../utils'; 5 | 6 | 7 | /* 8 | name "" 9 | hidden false 10 | x 0 11 | y 0 12 | blendMode "pass-through" 13 | opacity 1 14 | effect [] 15 | width "hug-contents" 16 | height "hug-contents" 17 | rotation 0 18 | fontFamily "Inter" 19 | horizontalAlignText "left" 20 | verticalAlignText "top" 21 | leadingTrim "auto" 22 | letterSpacing 0 23 | lineHeight "auto" 24 | textDecoration "none" 25 | textCase "original" 26 | fontSize 16 27 | italic false 28 | fill "#000000" 29 | blendMode "normal" 30 | fontWeight 400 31 | paragraphIndent 0 32 | paragraphSpacing 0 33 | listSpacing 0 34 | hangingPunctuation false 35 | hangingList false 36 | truncate false 37 | */ 38 | 39 | 40 | 41 | const extractStyles = (style) => { 42 | return { 43 | ...extractTextStyles(style), 44 | ...extractSizeStyles(style), 45 | ...extractBaseProps(style), 46 | ...extractBlendProps(style), 47 | ...extractConstraintProps(style), 48 | } 49 | } 50 | 51 | export default function Text({ href, onClick, children, style, ...props }) { 52 | return ( 53 | 59 | {children} 60 | 61 | ) 62 | } 63 | 64 | -------------------------------------------------------------------------------- /packages/figma/src/figma/index.ts: -------------------------------------------------------------------------------- 1 | const { widget }: { widget: WidgetAPI } = figma 2 | 3 | export { widget } 4 | -------------------------------------------------------------------------------- /packages/figma/src/figma/widget.ts: -------------------------------------------------------------------------------- 1 | import { FC } from 'react'; 2 | import { widget } from '.'; 3 | 4 | export const Text = widget.Text as FC; 5 | -------------------------------------------------------------------------------- /packages/figma/src/index.ts: -------------------------------------------------------------------------------- 1 | export default {} 2 | -------------------------------------------------------------------------------- /packages/figma/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './props'; 2 | -------------------------------------------------------------------------------- /packages/figma/src/utils/props.ts: -------------------------------------------------------------------------------- 1 | interface TransformObject { 2 | [key: string]: number; 3 | } 4 | 5 | function parseTransform(transform: string): TransformObject { 6 | const transformObject: TransformObject = {}; 7 | 8 | const regex = /(\w+)\(([^)]+)\)/g; 9 | let match; 10 | 11 | while ((match = regex.exec(transform)) !== null) { 12 | const [, property, values] = match; 13 | const parsedValues = values.split(',').map(value => parseFloat(value.trim())); 14 | 15 | switch (property) { 16 | case 'rotate': 17 | transformObject.rotate = parsedValues[0]; 18 | break; 19 | case 'translate': 20 | transformObject.translateX = parsedValues[0]; 21 | transformObject.translateY = parsedValues[1]; 22 | break; 23 | // Add other cases for other transform types if needed 24 | default: 25 | break; 26 | } 27 | } 28 | 29 | return transformObject; 30 | } 31 | 32 | export const extractConstraintProps = (style) => { 33 | const { x, y } = style; 34 | return { x, y } 35 | } 36 | 37 | export const extractBlendProps = (style) => { 38 | const { mixBlendMode, opacity, effect } = style;// mixBlendMode is react-dom/web only 39 | return { 40 | blendMode: mixBlendMode, opacity, effect 41 | } 42 | } 43 | 44 | export const extractBaseProps = (style): BaseProps => { 45 | const { display, position } = style; 46 | let name: any, onClick: any, key: any, hoverStyle: any, tooltip: any; 47 | 48 | return { 49 | name, 50 | hidden: display === 'none' ? true : false, 51 | onClick, key, hoverStyle, tooltip, 52 | positioning: position === 'absolute' ? 'absolute' : 'auto', 53 | } 54 | } 55 | 56 | export const extractSizeStyles = (style) => { 57 | const { width, height, minWidth, minHeight, maxWidth, maxHeight, transform } = style; 58 | const transformProps = parseTransform(transform); 59 | const { rotate: rotation } = transformProps; 60 | 61 | return { width, height, minWidth, maxWidth, minHeight, maxHeight, rotation } 62 | } 63 | 64 | /* 65 | href?: string 66 | fontFamily?: string 67 | letterSpacing?: number | string 68 | textDecoration?: 'none' | 'strikethrough' | 'underline' 69 | fontSize?: number 70 | italic?: boolean 71 | textCase?: 'upper' | 'lower' | 'title' | 'original' | 'small-caps' | 'small-caps-forced' 72 | fontWeight?: FontWeight # eg. 400, 500 or 'medium', 'bold'. 73 | fill?: HexCode | Color | Paint | (SolidPaint | GradientPaint)[] 74 | paragraphIndent?: number 75 | paragraphSpacing?: number 76 | horizontalAlignText?: 'left' | 'right' | 'center' | 'justified' 77 | verticalAlignText?: 'top' | 'center' | 'bottom' 78 | lineHeight?: number | string | 'auto' 79 | truncate?: boolean | number # ( number of lines) 80 | stroke?: HexCode | Color | SolidPaint | GradientPaint | (SolidPaint | GradientPaint)[] 81 | strokeWidth?: number 82 | strokeAlign?: StrokeAlign 83 | */ 84 | 85 | const parseTextDecoration = (style) => { 86 | const { textDecorationLine } = style; 87 | if (['none', 'underline', 'line-through'].includes(textDecorationLine)) { // TODO: multiple? ['underline line-through'] 88 | return { 89 | none: 'none', 90 | underline: 'underline', 91 | 'line-through': 'strikethrough', 92 | }[textDecorationLine]; 93 | } 94 | return undefined; 95 | } 96 | 97 | const parseItalic = (style) => { 98 | const { fontStyle } = style; 99 | return fontStyle === 'italic' ? true : false; 100 | } 101 | const parseTextCase = ({ textTransform, fontVariant }) => { 102 | // style.fontVariant – array of enum('small-caps', 'oldstyle-nums', 'lining-nums', 'tabular-nums', 'proportional-nums') or string 103 | // enum('none', 'uppercase', 'lowercase', 'capitalize') 104 | if (['uppercase', 'lowercase', 'capitalize'].includes(textTransform)) { 105 | return { 106 | none: 'original', 107 | uppercase: 'upper', 108 | lowercase: 'lower', 109 | // | 'title' | 'original' | 'small-caps' | 'small-caps-forced' 110 | }[textTransform]; 111 | } 112 | if (['small-caps', 'oldstyle-nums', 'lining-nums', 'tabular-nums', 'proportional-nums'].includes(fontVariant[0])) { 113 | return { 114 | 'small-caps': 'small-caps', 115 | 'titling-caps': 'title', 116 | }[fontVariant[0]]; 117 | } 118 | return undefined; 119 | } 120 | 121 | const parseHorizontalAlignText = (style) => { 122 | const { textAlign } = style; 123 | 124 | return { 125 | start: 'left', 126 | end: 'right', 127 | center: 'center', 128 | left: 'left', 129 | right: 'right', 130 | }[textAlign]; 131 | } 132 | 133 | // let initialiser as placeholder for future API 134 | export const extractTextStyles = (style) => { 135 | const { color, fontFamily, lineHeight, fontSize, fontWeight, fontVariant, letterSpacing, textTransform } = style; 136 | let href: string; 137 | 138 | 139 | return { 140 | href, 141 | fontFamily, 142 | letterSpacing, 143 | textDecoration: parseTextDecoration(style), 144 | fontSize, 145 | italic: parseItalic(style), 146 | textCase: parseTextCase({ textTransform, fontVariant }), 147 | fontWeight, 148 | fill: color, 149 | // paragraphIndent, 150 | // paragraphSpacing, 151 | horizontalAlignText: parseHorizontalAlignText(style), 152 | // verticalAlignText, 153 | lineHeight, 154 | // truncate, 155 | // stroke, 156 | // strokeWidth, 157 | // strokeAlign, 158 | } 159 | } -------------------------------------------------------------------------------- /packages/figma/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2016", 4 | "outDir": "lib", 5 | "rootDir": "src", 6 | "jsx": "react", 7 | "jsxFactory": "figma.widget.h", 8 | "jsxFragmentFactory": "figma.widget.Fragment", 9 | "noUnusedLocals": true, 10 | "noUnusedParameters": true, 11 | "experimentalDecorators": true, 12 | "allowSyntheticDefaultImports": true, 13 | "removeComments": true, 14 | "noImplicitAny": false, 15 | "moduleResolution": "node", 16 | "typeRoots": ["./node_modules/@types", "./node_modules/@figma"] 17 | }, 18 | "include": [ 19 | "src/**/*" 20 | ], 21 | "exclude": [ 22 | "node_modules" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /packages/lottie-react-native/README.md: -------------------------------------------------------------------------------- 1 | Please see [lottie](../lottie) 2 | -------------------------------------------------------------------------------- /packages/lottie/README.md: -------------------------------------------------------------------------------- 1 | # Lottie 2 | 3 | Cross-platform animation library. 4 | 5 | ## Platforms 6 | 7 | - `react-native` – React Native – Android/iOS 8 | - TODO: `react-dom` – React Web 9 | - Use https://github.com/airbnb/lottie 10 | - `react-native-windows` – React Native Windows 11 | - Track issue: https://github.com/microsoft/react-native-windows/issues/3278 & https://github.com/react-native-community/lottie-react-native/issues/601 12 | 13 | -------------------------------------------------------------------------------- /packages/native/README.md: -------------------------------------------------------------------------------- 1 | # React Platform Native 2 | 3 | Common React Native APIs and components for web and React Native platforms such as `react-native`, `react-native-windows`, `react-native-macos`, `react-sketchapp`, `react-figma`, etc. 4 | 5 | e.g. ``, ``, `` 6 | -------------------------------------------------------------------------------- /packages/native/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-platform/native", 3 | "version": "0.0.3-beta.3", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@react-platform/core": { 8 | "version": "0.0.2-beta.6", 9 | "resolved": "https://registry.npmjs.org/@react-platform/core/-/core-0.0.2-beta.6.tgz", 10 | "integrity": "sha512-StbbYdgr0wT2U3GsAHFT3FJEm6RvwfX1OjGub0vQH09GHm1x+5J4NgRFfLCkQpoqZUfL66Nn9+Dj57GfMIUo/Q==", 11 | "dev": true 12 | }, 13 | "@types/prop-types": { 14 | "version": "15.7.4", 15 | "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", 16 | "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==", 17 | "dev": true 18 | }, 19 | "@types/react": { 20 | "version": "17.0.39", 21 | "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.39.tgz", 22 | "integrity": "sha512-UVavlfAxDd/AgAacMa60Azl7ygyQNRwC/DsHZmKgNvPmRR5p70AJ5Q9EAmL2NWOJmeV+vVUI4IAP7GZrN8h8Ug==", 23 | "dev": true, 24 | "requires": { 25 | "@types/prop-types": "*", 26 | "@types/scheduler": "*", 27 | "csstype": "^3.0.2" 28 | } 29 | }, 30 | "@types/react-native": { 31 | "version": "0.67.2", 32 | "resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.67.2.tgz", 33 | "integrity": "sha512-DyBkq7kw1UngzfvBr8WE41+hL/TWpxOZVaeABJz6Si7DmpT0Rq6vJCYjVaR85ViKSYJvIHpzxYfp0dD+lb3ctA==", 34 | "dev": true, 35 | "requires": { 36 | "@types/react": "*" 37 | } 38 | }, 39 | "@types/scheduler": { 40 | "version": "0.16.2", 41 | "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", 42 | "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", 43 | "dev": true 44 | }, 45 | "csstype": { 46 | "version": "3.0.11", 47 | "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz", 48 | "integrity": "sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==", 49 | "dev": true 50 | }, 51 | "typescript": { 52 | "version": "4.6.2", 53 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz", 54 | "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==", 55 | "dev": true 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /packages/native/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-platform/native", 3 | "version": "0.0.3", 4 | "description": "Common React Native APIs and components for web and React Native platforms such as `react-native`, `react-native-windows`, `react-native-macos`, `react-sketchapp`, `react-figma`, etc.", 5 | "main": "lib/index.js", 6 | "sketch": "lib/index.js", 7 | "###module": "lib/module/index.js", 8 | "types": "lib/index.d.ts", 9 | "scripts": { 10 | "clean": "rm -rf lib/", 11 | "build:main": "tsc -p tsconfig.json", 12 | "build:module": "tsc -p tsconfig.module.json", 13 | "build:types": "tsc -d -p tsconfig.json", 14 | "build:js": "npm run build:main # injection doesn’t support ESM && npm run build:module", 15 | "build": "npm run clean && npm run build:js && npm run build:types", 16 | "dev": "tsc --watch -p tsconfig.json & tsc --watch -d -p tsconfig.json", 17 | "test": "echo \"Error: no test specified\" && exit 1" 18 | }, 19 | "repository": { 20 | "type": "git", 21 | "url": "git+https://github.com/elemental-design/react-platform.git" 22 | }, 23 | "bugs": { 24 | "url": "https://github.com/elemental-design/react-platform/issues" 25 | }, 26 | "homepage": "https://github.com/elemental-design/react-platform#readme", 27 | "keywords": [], 28 | "author": "Macintosh Helper ", 29 | "license": "MIT", 30 | "devDependencies": { 31 | "@react-platform/core": "0.0.2-beta.6", 32 | "@types/react": "^17.0.39", 33 | "@types/react-native": "^0.67.2", 34 | "typescript": "^4.6.2" 35 | }, 36 | "peerDependencies": { 37 | "@react-platform/core": ">= 0.0.1" 38 | }, 39 | "dependencies": {} 40 | } 41 | -------------------------------------------------------------------------------- /packages/native/src/@types/react-primitives/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'react-primitives' { 2 | import { ComponentType } from 'react'; 3 | 4 | interface TouchableWithoutFeedbackPropsIOS { 5 | /** 6 | * *(Apple TV only)* TV preferred focus (see documentation for the View component). 7 | * 8 | * @platform ios 9 | */ 10 | hasTVPreferredFocus?: boolean; 11 | 12 | /** 13 | * *(Apple TV only)* Object with properties to control Apple TV parallax effects. 14 | * 15 | * enabled: If true, parallax effects are enabled. Defaults to true. 16 | * shiftDistanceX: Defaults to 2.0. 17 | * shiftDistanceY: Defaults to 2.0. 18 | * tiltAngle: Defaults to 0.05. 19 | * magnification: Defaults to 1.0. 20 | * pressMagnification: Defaults to 1.0. 21 | * pressDuration: Defaults to 0.3. 22 | * pressDelay: Defaults to 0.0. 23 | * 24 | * @platform ios 25 | */ 26 | tvParallaxProperties?: any; 27 | } 28 | 29 | interface AccessibilityProps { 30 | /** 31 | * When true, indicates that the view is an accessibility element. 32 | * By default, all the touchable elements are accessible. 33 | */ 34 | accessible?: boolean; 35 | 36 | /** 37 | * Provides an array of custom actions available for accessibility. 38 | */ 39 | accessibilityActions?: ReadonlyArray; 40 | 41 | /** 42 | * Overrides the text that's read by the screen reader when the user interacts with the element. By default, the 43 | * label is constructed by traversing all the children and accumulating all the Text nodes separated by space. 44 | */ 45 | accessibilityLabel?: string; 46 | 47 | /** 48 | * Accessibility Role tells a person using either VoiceOver on iOS or TalkBack on Android the type of element that is focused on. 49 | */ 50 | accessibilityRole?: any; 51 | /** 52 | * Accessibility State tells a person using either VoiceOver on iOS or TalkBack on Android the state of the element currently focused on. 53 | * @deprecated: accessibilityState available in 0.60+ 54 | */ 55 | accessibilityStates?: any[]; 56 | /** 57 | * Accessibility State tells a person using either VoiceOver on iOS or TalkBack on Android the state of the element currently focused on. 58 | */ 59 | accessibilityState?: any; 60 | /** 61 | * An accessibility hint helps users understand what will happen when they perform an action on the accessibility element when that result is not obvious from the accessibility label. 62 | */ 63 | accessibilityHint?: string; 64 | 65 | /** 66 | * When `accessible` is true, the system will try to invoke this function when the user performs an accessibility custom action. 67 | */ 68 | onAccessibilityAction?: (event: any) => void; 69 | } 70 | 71 | export interface TouchableWithoutFeedbackProps extends TouchableWithoutFeedbackPropsIOS, AccessibilityProps { 72 | /** 73 | * Delay in ms, from onPressIn, before onLongPress is called. 74 | */ 75 | delayLongPress?: number; 76 | 77 | /** 78 | * Delay in ms, from the start of the touch, before onPressIn is called. 79 | */ 80 | delayPressIn?: number; 81 | 82 | /** 83 | * Delay in ms, from the release of the touch, before onPressOut is called. 84 | */ 85 | delayPressOut?: number; 86 | 87 | /** 88 | * If true, disable all interactions for this component. 89 | */ 90 | disabled?: boolean; 91 | 92 | /** 93 | * This defines how far your touch can start away from the button. 94 | * This is added to pressRetentionOffset when moving off of the button. 95 | * NOTE The touch area never extends past the parent view bounds and 96 | * the Z-index of sibling views always takes precedence if a touch hits 97 | * two overlapping views. 98 | */ 99 | hitSlop?: any; 100 | 101 | /** 102 | * When `accessible` is true (which is the default) this may be called when 103 | * the OS-specific concept of "blur" occurs, meaning the element lost focus. 104 | * Some platforms may not have the concept of blur. 105 | */ 106 | onBlur?: (e: any) => void; 107 | 108 | /** 109 | * When `accessible` is true (which is the default) this may be called when 110 | * the OS-specific concept of "focus" occurs. Some platforms may not have 111 | * the concept of focus. 112 | */ 113 | onFocus?: (e: any) => void; 114 | 115 | /** 116 | * Invoked on mount and layout changes with 117 | * {nativeEvent: {layout: {x, y, width, height}}} 118 | */ 119 | onLayout?: (event: any) => void; 120 | 121 | onLongPress?: (event: any) => void; 122 | 123 | /** 124 | * Called when the touch is released, 125 | * but not if cancelled (e.g. by a scroll that steals the responder lock). 126 | */ 127 | onPress?: (event: any) => void; 128 | 129 | onPressIn?: (event: any) => void; 130 | 131 | onPressOut?: (event: any) => void; 132 | 133 | /** 134 | * //FIXME: not in doc but available in examples 135 | */ 136 | style?: Object; 137 | 138 | /** 139 | * When the scroll view is disabled, this defines how far your 140 | * touch may move off of the button, before deactivating the button. 141 | * Once deactivated, try moving it back and you'll see that the button 142 | * is once again reactivated! Move it back and forth several times 143 | * while the scroll view is disabled. Ensure you pass in a constant 144 | * to reduce memory allocations. 145 | */ 146 | pressRetentionOffset?: any; 147 | 148 | /** 149 | * Used to locate this view in end-to-end tests. 150 | */ 151 | testID?: string; 152 | } 153 | 154 | interface TouchableOpacityProps extends TouchableWithoutFeedbackProps { 155 | /** 156 | * Determines what the opacity of the wrapped view should be when touch is active. 157 | * Defaults to 0.2 158 | */ 159 | activeOpacity?: number; 160 | } 161 | 162 | 163 | 164 | export const Touchable: ComponentType; 165 | 166 | export type PlatformOSType = 'ios' | 'android' | 'web' | 'sketch' | 'vr' | 'figma'; 167 | export interface PlatformStatic { 168 | OS: PlatformOSType; 169 | Version: number | string; 170 | select(specifics: { [platform in PlatformOSType | 'default']?: T }): T; 171 | } 172 | export const Platform: PlatformStatic; 173 | } 174 | -------------------------------------------------------------------------------- /packages/native/src/Core.ts: -------------------------------------------------------------------------------- 1 | type ModuleName = 'AccessibilityInfo' | 'ActivityIndicator' | 'Button' | 'DatePickerIOS' | 'DrawerLayoutAndroid' | 'FlatList' | 'Image' | 'ImageBackground' | 'InputAccessoryView' | 'KeyboardAvoidingView' | 'MaskedViewIOS' | 'Modal' | 'Picker' | 'PickerIOS' | 'Pressable' | 'ProgressBarAndroid' | 'ProgressViewIOS' | 'SafeAreaView' | 'ScrollView' | 'SectionList' | 'SegmentedControlIOS' | 'Slider' | 'Switch' | 'RefreshControl' | 'StatusBar' | 'Text' | 'TextInput' | 'Touchable' | 'TouchableHighlight' | 'TouchableNativeFeedback' | 'TouchableOpacity' | 'TouchableWithoutFeedback' | 'View' | 'VirtualizedList' | 'VirtualizedSectionList' | 'ActionSheetIOS' | 'Alert' | 'Animated' | 'Appearance' | 'AppRegistry' | 'AppState' | 'AsyncStorage' | 'BackHandler' | 'Clipboard' | 'DatePickerAndroid' | 'DeviceInfo' | 'DevSettings' | 'Dimensions' | 'Easing' | 'findNodeHandle' | 'I18nManager' | 'ImagePickerIOS' | 'InteractionManager' | 'Keyboard' | 'LayoutAnimation' | 'Linking' | 'LogBox' | 'NativeDialogManagerAndroid' | 'NativeEventEmitter' | 'Networking' | 'PanResponder' | 'PermissionsAndroid' | 'PixelRatio' | 'PushNotificationIOS' | 'Settings' | 'Share' | 'StatusBarIOS' | 'StyleSheet' | 'Systrace' | 'ToastAndroid' | 'TurboModuleRegistry' | 'TVEventHandler' | 'UIManager' | 'unstable_batchedUpdates' | 'useColorScheme' | 'useWindowDimensions' | 'UTFSequence' | 'Vibration' | 'YellowBox' | 'DeviceEventEmitter' | 'NativeAppEventEmitter' | 'NativeModules' | 'Platform' | 'processColor' | 'PlatformColor' | 'DynamicColorIOS' | 'requireNativeComponent' | 'unstable_RootTagContext' | 'unstable_enableLogBox' | 'ColorPropType' | 'EdgeInsetsPropType' | 'PointPropType' | 'ViewPropTypes'; 2 | 3 | type Modules = { 4 | [key in ModuleName]?: any; 5 | }; 6 | 7 | interface CoreType extends Modules { 8 | inject: (api: Modules) => void, 9 | }; 10 | 11 | import KeyboardAvoidingView from './modules/KeyboardAvoidingView'; 12 | import ScrollView from './modules/ScrollView'; 13 | import SafeAreaView from './modules/SafeAreaView'; 14 | import AccessibilityInfo from './modules/AccessibilityInfo'; 15 | import Button from './modules/Button'; 16 | import FlatList from './modules/FlatList'; 17 | import ActivityIndicator from './modules/ActivityIndicator'; 18 | 19 | const Core: CoreType = { 20 | // React Native API – https://github.com/facebook/react-native/blob/6de3fffc37af9b301b669ba183a7910bcc432b6e/index.js 21 | AccessibilityInfo, 22 | ActivityIndicator, 23 | Button, 24 | DatePickerIOS: null, 25 | DrawerLayoutAndroid: null, 26 | FlatList, 27 | Image: null, 28 | ImageBackground: null, 29 | InputAccessoryView: null, 30 | KeyboardAvoidingView, 31 | MaskedViewIOS: null, 32 | Modal: null, 33 | Picker: null, 34 | PickerIOS: null, 35 | Pressable: null, 36 | ProgressBarAndroid: null, 37 | ProgressViewIOS: null, 38 | SafeAreaView, 39 | ScrollView, 40 | SectionList: null, 41 | SegmentedControlIOS: null, 42 | Slider: null, 43 | Switch: null, 44 | RefreshControl: null, 45 | StatusBar: null, 46 | Text: null, 47 | TextInput: null, 48 | Touchable: null, 49 | TouchableHighlight: null, 50 | TouchableNativeFeedback: null, 51 | TouchableOpacity: null, 52 | TouchableWithoutFeedback: null, 53 | View: null, 54 | VirtualizedList: null, 55 | VirtualizedSectionList: null, 56 | ActionSheetIOS: null, 57 | Alert: null, 58 | Animated: null, 59 | Appearance: null, 60 | AppRegistry: null, 61 | AppState: null, 62 | AsyncStorage: null, 63 | BackHandler: null, 64 | Clipboard: null, 65 | DatePickerAndroid: null, 66 | DeviceInfo: null, 67 | DevSettings: null, 68 | Dimensions: null, 69 | Easing: null, 70 | findNodeHandle: null, 71 | I18nManager: null, 72 | ImagePickerIOS: null, 73 | InteractionManager: null, 74 | Keyboard: null, 75 | LayoutAnimation: null, 76 | Linking: null, 77 | LogBox: null, 78 | NativeDialogManagerAndroid: null, 79 | NativeEventEmitter: null, 80 | Networking: null, 81 | PanResponder: null, 82 | PermissionsAndroid: null, 83 | PushNotificationIOS: null, 84 | Settings: null, 85 | Share: null, 86 | StatusBarIOS: null, 87 | StyleSheet: null, 88 | Systrace: null, 89 | ToastAndroid: null, 90 | TurboModuleRegistry: null, 91 | TVEventHandler: null, 92 | UIManager: null, 93 | unstable_batchedUpdates: null, 94 | useColorScheme: null, 95 | useWindowDimensions: null, 96 | UTFSequence: null, 97 | Vibration: null, 98 | YellowBox: null, 99 | DeviceEventEmitter: null, 100 | NativeAppEventEmitter: null, 101 | NativeModules: null, 102 | processColor: null, 103 | PlatformColor: null, 104 | DynamicColorIOS: null, 105 | requireNativeComponent: null, 106 | unstable_RootTagContext: null, 107 | unstable_enableLogBox: null, 108 | ColorPropType: null, 109 | EdgeInsetsPropType: null, 110 | PointPropType: null, 111 | ViewPropTypes: null, 112 | 113 | PixelRatio: require('./modules/PixelRatio'), 114 | Platform: require('@react-platform/core').Platform, 115 | 116 | inject: (api: Modules) => { 117 | 118 | if (api.Platform) { 119 | Core.Platform.inject(api.Platform); 120 | } 121 | // @ts-ignore 122 | Object.keys(api).forEach((nativeModule: keyof Modules) => { 123 | Core[nativeModule] = api[nativeModule]; 124 | }) 125 | }, 126 | }; 127 | 128 | export = Core; 129 | 130 | -------------------------------------------------------------------------------- /packages/native/src/context.tsx: -------------------------------------------------------------------------------- 1 | import React, { createContext, CSSProperties, ReactNode, useContext, useMemo, useReducer } from 'react'; 2 | 3 | const SET_PROCESS_STYLE_FUNC = 'SET_PROCESS_STYLE_FUNC'; 4 | 5 | type Action = { 6 | type: typeof SET_PROCESS_STYLE_FUNC, 7 | payload: { processStyle?: (k: CSSProperties) => void }, 8 | }; 9 | type Dispatch = (action: Action) => void; 10 | type State = { processStyle: any }; 11 | type NativeProviderProps = { processStyle: any, children: ReactNode }; 12 | 13 | const NativeContext = createContext< 14 | { state: State, dispatch: Dispatch } | undefined 15 | >(undefined); 16 | 17 | function nativeReducer(state: State, action: Action) { 18 | const { type, payload } = action; 19 | 20 | switch (type) { 21 | case SET_PROCESS_STYLE_FUNC: { 22 | const { processStyle } = payload; 23 | return { ...state, processStyle }; 24 | } 25 | default: { 26 | throw new Error(`Unhandled action type: ${type}`) 27 | } 28 | } 29 | } 30 | 31 | export const useNative = (): [State?, Dispatch?] => { 32 | const context = useContext(NativeContext); 33 | 34 | return [context?.state, context?.dispatch]; 35 | }; 36 | 37 | export const setProcessStyle = (func: (k: CSSProperties) => void, dispatch: Dispatch) => { 38 | // const [state, dispatch] = useNative(); 39 | 40 | if (dispatch) { 41 | dispatch({ type: SET_PROCESS_STYLE_FUNC, payload: { processStyle: func } }); 42 | } 43 | } 44 | 45 | export function RPNativeProvider({ processStyle, children }: NativeProviderProps) { 46 | const [state, dispatch] = useReducer(nativeReducer, { processStyle: (style: CSSProperties) => ({ style }) }); 47 | 48 | // NOTE: you *might* need to memoize this value 49 | 50 | const value = useMemo(() => ({ state: { ...state, processStyle }, dispatch }), [state, processStyle]); 51 | 52 | return ( 53 | 54 | {children} 55 | 56 | ); 57 | } 58 | 59 | 60 | export const getInjectedStyles = (styles: CSSProperties) => { 61 | const [state, dispatch] = useNative(); 62 | // console.log({ state }); - if DEBUG 63 | const { processStyle } = state || {}; 64 | 65 | return processStyle(styles) 66 | }; 67 | -------------------------------------------------------------------------------- /packages/native/src/index.ts: -------------------------------------------------------------------------------- 1 | import ScrollView from './modules/ScrollView'; 2 | import SafeAreaView from './modules/SafeAreaView'; 3 | import Modal from './modules/Modal'; 4 | import TextInput from './modules/TextInput'; 5 | 6 | import useWindowDimensions from './modules/use-window-dimensions'; 7 | import { getInjectedStyles, setProcessStyle, RPNativeProvider, useNative } from './context'; 8 | 9 | 10 | export { 11 | ScrollView, 12 | SafeAreaView, 13 | Modal, 14 | TextInput, 15 | getInjectedStyles, 16 | setProcessStyle, 17 | useNative, 18 | RPNativeProvider, 19 | 20 | useWindowDimensions, 21 | }; 22 | -------------------------------------------------------------------------------- /packages/native/src/modules/AccessibilityInfo/core.ts: -------------------------------------------------------------------------------- 1 | export const isBoldTextEnabled = () => {}; 2 | export const isGrayscaleEnabled = () => {}; 3 | export const isInvertColorsEnabled = () => {}; 4 | export const isReduceMotionEnabled = () => {}; 5 | export const isReduceTransparencyEnabled = () => {}; 6 | export const isScreenReaderEnabled = () => {}; 7 | export const addEventListener = () => {}; 8 | export const setAccessibilityFocus = () => {}; 9 | export const announceForAccessibility = () => {}; 10 | export const removeEventListener = () => {}; 11 | -------------------------------------------------------------------------------- /packages/native/src/modules/AccessibilityInfo/index.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import { Platform } from '@react-platform/core'; 3 | 4 | const AccessibilityInfo = Platform.select({ // @ts-ignore 5 | native: () => require('react-native').AccessibilityInfo, 6 | web: () => require('react-native-web').AccessibilityInfo, 7 | default: () => require('./core'), 8 | })(); 9 | 10 | export default AccessibilityInfo; 11 | -------------------------------------------------------------------------------- /packages/native/src/modules/ActivityIndicator/core.ts: -------------------------------------------------------------------------------- 1 | export default {}; // FIXME: Cross-platform stub 2 | -------------------------------------------------------------------------------- /packages/native/src/modules/ActivityIndicator/index.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import { Platform } from '@react-platform/core'; 3 | 4 | const ActivityIndicator = Platform.select({ // @ts-ignore 5 | native: () => require('react-native').ActivityIndicator, 6 | web: () => require('react-native-web').ActivityIndicator, 7 | default: () => require('./core'), 8 | })(); 9 | 10 | export default ActivityIndicator; 11 | -------------------------------------------------------------------------------- /packages/native/src/modules/Button/core.tsx: -------------------------------------------------------------------------------- 1 | // @ts-nocheck FIXME: Add types 2 | 3 | /* 4 | * This file contains source-code copied from https://github.com/facebook/react-native/blob/master/Libraries/Components/Button.js 5 | * React Native's source code is licensed under the MIT license: https://github.com/facebook/react-native/blob/master/LICENSE 6 | */ 7 | import * as React from 'react'; 8 | import { Platform, Touchable, View, Text, StyleSheet } from '@react-platform/core'; 9 | 10 | const Button = ({ 11 | accessibilityLabel, 12 | color, 13 | onPress, 14 | touchSoundDisabled, 15 | title, 16 | hasTVPreferredFocus, 17 | nextFocusDown, 18 | nextFocusForward, 19 | nextFocusLeft, 20 | nextFocusRight, 21 | nextFocusUp, 22 | disabled, 23 | testID, 24 | style, 25 | textStyle, 26 | }: any) => { 27 | const buttonStyles = [styles.button]; 28 | const textStyles = [styles.text]; 29 | 30 | if (style) { 31 | buttonStyles.push(style); 32 | } 33 | if (textStyle) { 34 | textStyles.push(textStyle); 35 | } 36 | 37 | const accessibilityState: { disabled?: boolean } = {}; 38 | 39 | if (disabled) { 40 | buttonStyles.push(styles.buttonDisabled); 41 | textStyles.push(styles.textDisabled); 42 | accessibilityState.disabled = true; 43 | } 44 | 45 | const formattedTitle = 46 | Platform.OS === 'android' ? title.toUpperCase() : title; 47 | 48 | return ( 49 | 64 | 65 | 66 | {formattedTitle} 67 | 68 | 69 | 70 | ) 71 | }; 72 | 73 | const styles = StyleSheet.create({ 74 | button: Platform.select({ 75 | ios: {}, 76 | android: { 77 | elevation: 4, 78 | // Material design blue from https://material.google.com/style/color.html#color-color-palette 79 | backgroundColor: '#2196F3', 80 | borderRadius: 2, 81 | }, 82 | }), 83 | text: { 84 | textAlign: 'center', 85 | margin: 8, 86 | ...Platform.select({ 87 | ios: { 88 | // iOS blue from https://developer.apple.com/ios/human-interface-guidelines/visual-design/color/ 89 | color: '#007AFF', 90 | fontSize: 18, 91 | }, 92 | android: { 93 | color: 'white', 94 | fontWeight: '500', 95 | }, 96 | }), 97 | }, 98 | buttonDisabled: Platform.select({ 99 | ios: {}, 100 | android: { 101 | elevation: 0, 102 | backgroundColor: '#dfdfdf', 103 | }, 104 | }), 105 | textDisabled: Platform.select({ 106 | ios: { 107 | color: '#cdcdcd', 108 | }, 109 | android: { 110 | color: '#a1a1a1', 111 | }, 112 | }), 113 | }); 114 | 115 | export default Button; 116 | -------------------------------------------------------------------------------- /packages/native/src/modules/Button/index.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import { Platform } from '@react-platform/core'; 3 | 4 | const Button = Platform.select({ // @ts-ignore 5 | native: () => require('react-native').Button, 6 | web: () => require('react-native-web').Button, 7 | default: () => require('./core'), 8 | })(); 9 | 10 | export default Button; -------------------------------------------------------------------------------- /packages/native/src/modules/FlatList/core.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * This file contains source-code copied from https://github.com/facebook/react-native/blob/master/Libraries/Components/Button.js 3 | * React Native's source code is licensed under the MIT license: https://github.com/facebook/react-native/blob/master/LICENSE 4 | */ 5 | import * as React from 'react'; 6 | import { View, StyleSheet } from '@react-platform/core'; 7 | 8 | const FlatList = ({ 9 | ListItemComponent, 10 | renderItem, 11 | columnWrapperStyle, 12 | items, 13 | }: any) => { 14 | 15 | const renderer = React.useCallback((props: any): React.ReactNode => { 16 | if (ListItemComponent) { 17 | // $FlowFixMe Component isn't valid 18 | return ; 19 | } else if (renderItem) { 20 | return renderItem(props); 21 | } else { 22 | return null; 23 | } 24 | }, [ListItemComponent, renderItem]); 25 | 26 | return ( 27 | 28 | {items.map((item: any, index: number) => { 29 | const element = renderer({ 30 | item, 31 | index, 32 | // index: index * numColumns + kk, 33 | // separators: info.separators, 34 | }); 35 | return element != null ? ( 36 | {element} 37 | ) : null; 38 | })} 39 | 40 | ) 41 | }; 42 | 43 | const styles = StyleSheet.create({ 44 | row: { 45 | flexDirection: 'row' 46 | } 47 | }); 48 | 49 | export default FlatList; 50 | -------------------------------------------------------------------------------- /packages/native/src/modules/FlatList/index.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import { Platform } from '@react-platform/core'; 3 | 4 | const FlatList = Platform.select({ // @ts-ignore 5 | native: () => require('react-native').FlatList, 6 | web: () => require('react-native-web').FlatList, 7 | default: () => require('./core'), 8 | })(); 9 | 10 | export default FlatList; 11 | -------------------------------------------------------------------------------- /packages/native/src/modules/KeyboardAvoidingView/core.native.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | export { KeyboardAvoidingView as default } from 'react-native'; 3 | -------------------------------------------------------------------------------- /packages/native/src/modules/KeyboardAvoidingView/core.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | export { View as default } from '@react-platform/core'; 3 | -------------------------------------------------------------------------------- /packages/native/src/modules/KeyboardAvoidingView/core.web.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | export { KeyboardAvoidingView as default } from 'react-native-web'; 3 | -------------------------------------------------------------------------------- /packages/native/src/modules/KeyboardAvoidingView/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './core'; 2 | -------------------------------------------------------------------------------- /packages/native/src/modules/Modal/core.native.ts: -------------------------------------------------------------------------------- 1 | export { Modal as default } from 'react-native'; 2 | -------------------------------------------------------------------------------- /packages/native/src/modules/Modal/core.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | export { View as default } from '@react-platform/core'; 3 | -------------------------------------------------------------------------------- /packages/native/src/modules/Modal/core.web.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | export { Modal as default } from 'react-native-web'; 3 | -------------------------------------------------------------------------------- /packages/native/src/modules/Modal/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './core'; 2 | -------------------------------------------------------------------------------- /packages/native/src/modules/PixelRatio/core.ts: -------------------------------------------------------------------------------- 1 | export default {}; 2 | -------------------------------------------------------------------------------- /packages/native/src/modules/PixelRatio/index.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import { Platform } from '@react-platform/core'; 3 | 4 | export default Platform.select({ // @ts-ignore 5 | native: () => require('react-native').PixelRatio, 6 | web: () => require('react-native-web').PixelRatio, 7 | default: () => require('./core'), 8 | })(); 9 | -------------------------------------------------------------------------------- /packages/native/src/modules/SafeAreaView/core.native.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | export { SafeAreaView as default } from 'react-native'; 3 | -------------------------------------------------------------------------------- /packages/native/src/modules/SafeAreaView/core.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | export { View as default } from '@react-platform/core'; 3 | -------------------------------------------------------------------------------- /packages/native/src/modules/SafeAreaView/core.web.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | export { SafeAreaView as default } from 'react-native-web'; 3 | -------------------------------------------------------------------------------- /packages/native/src/modules/SafeAreaView/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './core'; 2 | -------------------------------------------------------------------------------- /packages/native/src/modules/ScrollView/core.native.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | export { ScrollView as default } from 'react-native'; 3 | -------------------------------------------------------------------------------- /packages/native/src/modules/ScrollView/core.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | export { View as default } from '@react-platform/core'; 3 | -------------------------------------------------------------------------------- /packages/native/src/modules/ScrollView/core.web.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | export { ScrollView as default } from 'react-native-web'; 3 | -------------------------------------------------------------------------------- /packages/native/src/modules/ScrollView/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './core'; 2 | -------------------------------------------------------------------------------- /packages/native/src/modules/TextInput/core.native.ts: -------------------------------------------------------------------------------- 1 | export { TextInput as default } from 'react-native'; 2 | -------------------------------------------------------------------------------- /packages/native/src/modules/TextInput/core.sketch.tsx: -------------------------------------------------------------------------------- 1 | import React, { CSSProperties } from 'react'; 2 | 3 | // @ts-ignore 4 | import { Text as _Text, View as _View } from '@react-platform/core'; 5 | import { getInjectedStyles } from '../../context'; 6 | 7 | 8 | 9 | const typographyProps = ['fontFamily', 'fontSize', 'lineHeight', 'bold']; 10 | const colorProps = ['color']; 11 | 12 | // FIXME: Clean up or use styled-system internals ???? Or extract to React Platform stylesheet util library 13 | const textStyleKeys = [...colorProps, ...typographyProps]; 14 | 15 | type CSSKeys = keyof CSSProperties; 16 | 17 | const getSplitStyles = (style: CSSProperties) => { 18 | const { containerStyle, textStyle }: any = Object.keys(style).reduce((acc: any, k: any) => { 19 | if (textStyleKeys.includes(k)) { // @ts-ignore 20 | acc.textStyle[k] = style[k]; 21 | } else { // @ts-ignore 22 | acc.containerStyle[k] = style[k]; 23 | } 24 | return acc; 25 | }, { containerStyle: {}, textStyle: {} }); 26 | 27 | return { 28 | containerStyle, 29 | textStyle, 30 | }; 31 | }; 32 | 33 | 34 | // TODO: Style injection system with middleware 35 | 36 | const _TextInput = React.forwardRef(({ 37 | onChangeText, 38 | onChange, 39 | components = {}, 40 | multiline, 41 | value, 42 | placeholder, 43 | placeholderTextColor = 'gray', 44 | overrides: { style: styleOverride } = { style: {} }, 45 | style, 46 | containerProps, 47 | ...props 48 | }: { 49 | style: CSSProperties, 50 | onChangeText?: Function, 51 | onChange?: Function, 52 | components?: { [key: string]: any }, 53 | overrides?: { style?: CSSProperties }, 54 | value?: string, 55 | placeholder?: string, 56 | placeholderTextColor?: string, 57 | multiline?: boolean, 58 | containerProps?: any, 59 | }, ref) => { 60 | // const { View = 'input' } = components || {}; 61 | const { View, Text } = { View: components?.View, Text: components?.Text || _Text }; 62 | const { containerStyle, textStyle } = getSplitStyles(style); 63 | // console.log({ containerStyle, textStyle }); 64 | const containerStyleProps = getInjectedStyles(containerStyle); 65 | const showPlaceholder = Boolean(!value && placeholder); 66 | const textStyleProps = getInjectedStyles({ ...textStyle, color: showPlaceholder && placeholderTextColor, }); 67 | 68 | // React.useEffect(() => { 69 | // if (multiline) { 70 | // setView(components?.TextArea || 'textarea'); 71 | // } else { 72 | // setView(components?.Input || 'input'); 73 | // } 74 | // }, [multiline]); 75 | 76 | return ( 77 | 78 | onChangeText(targetValue) 85 | // : undefined)} 86 | {...props} 87 | > 88 | {value ? value : placeholder} 89 | 90 | 91 | ); 92 | }); 93 | 94 | _TextInput.defaultProps = { 95 | style: { fontSize: 14, outline: 'none', borderWidth: 0 }, 96 | }; 97 | 98 | export default _TextInput; 99 | -------------------------------------------------------------------------------- /packages/native/src/modules/TextInput/core.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore FIXME: Stub with View, Text, etc (using Sketch design, for unsupported platforms) 2 | export { Text as default } from '@react-platform/core'; 3 | 4 | -------------------------------------------------------------------------------- /packages/native/src/modules/TextInput/core.web.tsx: -------------------------------------------------------------------------------- 1 | import React, { CSSProperties, Ref } from 'react'; 2 | 3 | // TODO: Style injection system with middleware 4 | 5 | const _TextInput = React.forwardRef(({ 6 | onChangeText, 7 | onChange, 8 | components, 9 | multiline, 10 | overrides: { style: styleOverride } = { style: {} }, 11 | style, 12 | ...props 13 | }: { 14 | style?: CSSProperties, 15 | onChangeText?: Function, 16 | onChange?: Function, 17 | components?: { [key: string]: any }, 18 | overrides?: { style?: CSSProperties }, 19 | multiline?: boolean, 20 | }, ref: Ref) => { 21 | // const { View = 'input' } = components || {}; 22 | const [View, setView] = React.useState(components?.View || 'input'); 23 | 24 | React.useEffect(() => { 25 | if (multiline) { 26 | setView(components?.TextArea || 'textarea'); 27 | } else { 28 | setView(components?.Input || 'input'); 29 | } 30 | }, [multiline]); 31 | 32 | return ( 33 | onChangeText(value) 38 | : undefined)} 39 | {...props} 40 | /> 41 | ); 42 | }); 43 | 44 | _TextInput.defaultProps = { 45 | style: { fontSize: 14, outline: 'none', borderWidth: 0 }, 46 | }; 47 | 48 | export default _TextInput; 49 | -------------------------------------------------------------------------------- /packages/native/src/modules/TextInput/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './core'; 2 | -------------------------------------------------------------------------------- /packages/native/src/modules/use-window-dimensions/core.native.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import { useWindowDimensions } from 'react-native'; 3 | 4 | export default useWindowDimensions; 5 | -------------------------------------------------------------------------------- /packages/native/src/modules/use-window-dimensions/core.sketch.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import { useWindowDimensions } from 'react-sketchapp'; 3 | 4 | export default useWindowDimensions; 5 | -------------------------------------------------------------------------------- /packages/native/src/modules/use-window-dimensions/core.ts: -------------------------------------------------------------------------------- 1 | let useWindowDimensions; 2 | 3 | const DEFAULTS = { 4 | width: undefined, 5 | height: undefined, 6 | } 7 | 8 | if (typeof window !== 'undefined') { 9 | useWindowDimensions = require('./core.web'); 10 | } else { 11 | // Stub for hook 12 | useWindowDimensions = () => ({ width: DEFAULTS.width, height: DEFAULTS.height }); 13 | }; 14 | 15 | export default useWindowDimensions as any; 16 | 17 | -------------------------------------------------------------------------------- /packages/native/src/modules/use-window-dimensions/core.web.ts: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react'; 2 | 3 | const DEFAULTS = { 4 | width: undefined, 5 | height: undefined, 6 | }; 7 | 8 | /* code from https://usehooks.com/useWindowSize/ */ 9 | export default function useWindowSize() { 10 | const isClient = typeof window === 'object'; 11 | 12 | function getSize() { 13 | return { 14 | width: isClient 15 | ? window.screen.width < window.innerWidth ? window.screen.height : window.innerWidth 16 | : DEFAULTS.width, 17 | height: isClient 18 | ? window.screen.height < window.innerHeight ? window.screen.height : window.innerHeight 19 | : DEFAULTS.height, 20 | }; 21 | } 22 | 23 | const [windowSize, setWindowSize] = useState(getSize); 24 | 25 | useEffect((): any => { 26 | if (!isClient) { 27 | return false; 28 | } 29 | 30 | function handleResize() { 31 | setWindowSize(getSize()); 32 | } 33 | 34 | window.addEventListener('resize', handleResize); 35 | return () => window.removeEventListener('resize', handleResize); 36 | }, []); // Empty array ensures that effect is only run on mount and unmount 37 | 38 | return windowSize; 39 | } 40 | -------------------------------------------------------------------------------- /packages/native/src/modules/use-window-dimensions/index.js: -------------------------------------------------------------------------------- 1 | export * from './core'; 2 | -------------------------------------------------------------------------------- /packages/native/src/modules/use-window-dimensions/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './core'; 2 | -------------------------------------------------------------------------------- /packages/native/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "lib", 4 | "rootDir": "src", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "module": "commonjs", 7 | "target": "es5", 8 | 9 | "allowJs": true, 10 | "allowSyntheticDefaultImports": true, 11 | "esModuleInterop": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "isolatedModules": true, 14 | "jsx": "react-jsx", 15 | "moduleResolution": "node", 16 | "noFallthroughCasesInSwitch": true, 17 | "resolveJsonModule": true, 18 | "skipLibCheck": true, 19 | "strict": true 20 | }, 21 | "include": [ 22 | "src/**/*" 23 | ], 24 | "exclude": [ 25 | "node_modules" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/native/tsconfig.module-json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "module": "esnext", 5 | "target": "es5", 6 | "outDir": "lib/module", 7 | }, 8 | 9 | } 10 | -------------------------------------------------------------------------------- /packages/svg/README.md: -------------------------------------------------------------------------------- 1 | # React Platform SVG 2 | 3 | Inspired by and code borrowed from https://github.com/chengyin/react-primitives-svg 4 | 5 | ## Platforms 6 | 7 | - `react-dom` – React Web 8 | - `react-native` – React Native – iOS/Android 9 | - `react-sketchapp` – React Sketch.app 10 | - TODO: `react-native-macos` – React Native macOS 11 | - Could implement `` with a port of https://github.com/alloc/react-native-svgkit 12 | - TODO: `react-primitives` – React Primitives 13 | - This should probably be a stub with a ``, and maybe render compute some rough SVG element sizes to render ``s from 14 | - TODO: `react-figma` – React Figma 15 | - `` and `` are possible 16 | - TODO: `react-native-windows` – React Native Windows 17 | - Track issue: https://github.com/microsoft/react-native-windows/issues/3326 18 | 19 | ## Credit 20 | 21 | - https://github.com/chengyin/react-primitives-svg 22 | -------------------------------------------------------------------------------- /packages/svg/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-platform/svg", 3 | "version": "0.0.1-beta.6", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@lona/svg-model": { 8 | "version": "2.1.0", 9 | "resolved": "https://registry.npmjs.org/@lona/svg-model/-/svg-model-2.1.0.tgz", 10 | "integrity": "sha512-+RSiszkpePJ9Mt7FUALh/3Pzur2HW34iqpL7RIiGoNRGJLbcNGAB7ic4bVBkn3mpNY6VlI0fBpkUzcZxvvtDzg==", 11 | "dev": true, 12 | "optional": true, 13 | "requires": { 14 | "csscolorparser": "^1.0.3", 15 | "element-to-path": "^1.2.0", 16 | "lodash.camelcase": "^4.3.0", 17 | "lodash.upperfirst": "^4.3.1", 18 | "svg-transform-parser": "^0.0.1", 19 | "svgpath": "^2.2.3", 20 | "svgson": "^4.0.0" 21 | } 22 | }, 23 | "@react-platform/core": { 24 | "version": "0.0.2-beta.0", 25 | "resolved": "https://registry.npmjs.org/@react-platform/core/-/core-0.0.2-beta.0.tgz", 26 | "integrity": "sha512-Eqk7QaKoMTFJOwUwNdHGy5/TanOnEja9aJmEE7825nBmu5SdNnTz+oOpUNIEqKN8j3jtbTPskVgV/HYUu9wRNA==", 27 | "dev": true 28 | }, 29 | "@sketch-hq/sketch-file-format-ts": { 30 | "version": "4.0.3", 31 | "resolved": "https://registry.npmjs.org/@sketch-hq/sketch-file-format-ts/-/sketch-file-format-ts-4.0.3.tgz", 32 | "integrity": "sha512-Ndgb5GtPi53bp2jOmCcVYiz9Mwx9Mjox7uMQxaNrD2Qm0C8doc2mejzPWPOOiruK7qpHtFBPFX3hXl9pkMkxIA==", 33 | "dev": true, 34 | "optional": true 35 | }, 36 | "@types/node": { 37 | "version": "17.0.21", 38 | "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz", 39 | "integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==", 40 | "dev": true 41 | }, 42 | "@types/prop-types": { 43 | "version": "15.7.4", 44 | "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", 45 | "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==" 46 | }, 47 | "@types/react": { 48 | "version": "17.0.40", 49 | "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.40.tgz", 50 | "integrity": "sha512-UrXhD/JyLH+W70nNSufXqMZNuUD2cXHu6UjCllC6pmOQgBX4SGXOH8fjRka0O0Ee0HrFxapDD8Bwn81Kmiz6jQ==", 51 | "requires": { 52 | "@types/prop-types": "*", 53 | "@types/scheduler": "*", 54 | "csstype": "^3.0.2" 55 | } 56 | }, 57 | "@types/react-native": { 58 | "version": "0.67.3", 59 | "resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.67.3.tgz", 60 | "integrity": "sha512-hF4uOZFl2PPQtGWOtLoafrlCJeU815X3PgfVePM+7EhOIZhYXKH7+p3R3cZSnwVnrU5Ep/JfiHimMDliY3o8oQ==", 61 | "requires": { 62 | "@types/react": "*" 63 | } 64 | }, 65 | "@types/scheduler": { 66 | "version": "0.16.2", 67 | "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", 68 | "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" 69 | }, 70 | "@types/yoga-layout": { 71 | "version": "1.9.2", 72 | "resolved": "https://registry.npmjs.org/@types/yoga-layout/-/yoga-layout-1.9.2.tgz", 73 | "integrity": "sha512-S9q47ByT2pPvD65IvrWp7qppVMpk9WGMbVq9wbWZOHg6tnXSD4vyhao6nOSBwwfDdV2p3Kx9evA9vI+XWTfDvw==", 74 | "dev": true, 75 | "optional": true 76 | }, 77 | "airbnb-prop-types": { 78 | "version": "2.16.0", 79 | "resolved": "https://registry.npmjs.org/airbnb-prop-types/-/airbnb-prop-types-2.16.0.tgz", 80 | "integrity": "sha512-7WHOFolP/6cS96PhKNrslCLMYAI8yB1Pp6u6XmxozQOiZbsI5ycglZr5cHhBFfuRcQQjzCMith5ZPZdYiJCxUg==", 81 | "dev": true, 82 | "optional": true, 83 | "requires": { 84 | "array.prototype.find": "^2.1.1", 85 | "function.prototype.name": "^1.1.2", 86 | "is-regex": "^1.1.0", 87 | "object-is": "^1.1.2", 88 | "object.assign": "^4.1.0", 89 | "object.entries": "^1.1.2", 90 | "prop-types": "^15.7.2", 91 | "prop-types-exact": "^1.2.0", 92 | "react-is": "^16.13.1" 93 | } 94 | }, 95 | "array.prototype.find": { 96 | "version": "2.1.2", 97 | "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.1.2.tgz", 98 | "integrity": "sha512-00S1O4ewO95OmmJW7EesWfQlrCrLEL8kZ40w3+GkLX2yTt0m2ggcePPa2uHPJ9KUmJvwRq+lCV9bD8Yim23x/Q==", 99 | "dev": true, 100 | "optional": true, 101 | "requires": { 102 | "call-bind": "^1.0.2", 103 | "define-properties": "^1.1.3", 104 | "es-abstract": "^1.19.0" 105 | } 106 | }, 107 | "boolbase": { 108 | "version": "1.0.0", 109 | "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", 110 | "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", 111 | "dev": true, 112 | "optional": true 113 | }, 114 | "call-bind": { 115 | "version": "1.0.2", 116 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 117 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 118 | "dev": true, 119 | "optional": true, 120 | "requires": { 121 | "function-bind": "^1.1.1", 122 | "get-intrinsic": "^1.0.2" 123 | } 124 | }, 125 | "css-select": { 126 | "version": "4.2.1", 127 | "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.2.1.tgz", 128 | "integrity": "sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==", 129 | "dev": true, 130 | "optional": true, 131 | "requires": { 132 | "boolbase": "^1.0.0", 133 | "css-what": "^5.1.0", 134 | "domhandler": "^4.3.0", 135 | "domutils": "^2.8.0", 136 | "nth-check": "^2.0.1" 137 | } 138 | }, 139 | "css-tree": { 140 | "version": "1.1.3", 141 | "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", 142 | "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", 143 | "dev": true, 144 | "optional": true, 145 | "requires": { 146 | "mdn-data": "2.0.14", 147 | "source-map": "^0.6.1" 148 | } 149 | }, 150 | "css-what": { 151 | "version": "5.1.0", 152 | "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", 153 | "integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==", 154 | "dev": true, 155 | "optional": true 156 | }, 157 | "csscolorparser": { 158 | "version": "1.0.3", 159 | "resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz", 160 | "integrity": "sha1-s085HupNqPPpgjHizNjfnAQfFxs=", 161 | "dev": true, 162 | "optional": true 163 | }, 164 | "csstype": { 165 | "version": "3.0.11", 166 | "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz", 167 | "integrity": "sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==" 168 | }, 169 | "deep-rename-keys": { 170 | "version": "0.2.1", 171 | "resolved": "https://registry.npmjs.org/deep-rename-keys/-/deep-rename-keys-0.2.1.tgz", 172 | "integrity": "sha1-7eeFN9emaivmFRfir5Vtf1ij8dg=", 173 | "dev": true, 174 | "optional": true, 175 | "requires": { 176 | "kind-of": "^3.0.2", 177 | "rename-keys": "^1.1.2" 178 | } 179 | }, 180 | "define-properties": { 181 | "version": "1.1.3", 182 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", 183 | "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", 184 | "dev": true, 185 | "optional": true, 186 | "requires": { 187 | "object-keys": "^1.0.12" 188 | } 189 | }, 190 | "dom-serializer": { 191 | "version": "1.3.2", 192 | "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", 193 | "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", 194 | "dev": true, 195 | "optional": true, 196 | "requires": { 197 | "domelementtype": "^2.0.1", 198 | "domhandler": "^4.2.0", 199 | "entities": "^2.0.0" 200 | } 201 | }, 202 | "domelementtype": { 203 | "version": "2.2.0", 204 | "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", 205 | "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", 206 | "dev": true, 207 | "optional": true 208 | }, 209 | "domhandler": { 210 | "version": "4.3.0", 211 | "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz", 212 | "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==", 213 | "dev": true, 214 | "optional": true, 215 | "requires": { 216 | "domelementtype": "^2.2.0" 217 | } 218 | }, 219 | "domutils": { 220 | "version": "2.8.0", 221 | "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", 222 | "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", 223 | "dev": true, 224 | "optional": true, 225 | "requires": { 226 | "dom-serializer": "^1.0.1", 227 | "domelementtype": "^2.2.0", 228 | "domhandler": "^4.2.0" 229 | } 230 | }, 231 | "element-to-path": { 232 | "version": "1.2.1", 233 | "resolved": "https://registry.npmjs.org/element-to-path/-/element-to-path-1.2.1.tgz", 234 | "integrity": "sha512-JNFZS0yI3Myywn/ltFj/yTihHNzMTYk0ycHcgcjlvA/dYMUjMIGqvbezPZeXN3U1Klp/aiigr2mpmhVRfudtbg==", 235 | "dev": true, 236 | "optional": true 237 | }, 238 | "entities": { 239 | "version": "2.2.0", 240 | "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", 241 | "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", 242 | "dev": true, 243 | "optional": true 244 | }, 245 | "error-stack-parser": { 246 | "version": "2.0.7", 247 | "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.7.tgz", 248 | "integrity": "sha512-chLOW0ZGRf4s8raLrDxa5sdkvPec5YdvwbFnqJme4rk0rFajP8mPtrDL1+I+CwrQDCjswDA5sREX7jYQDQs9vA==", 249 | "dev": true, 250 | "optional": true, 251 | "requires": { 252 | "stackframe": "^1.1.1" 253 | } 254 | }, 255 | "es-abstract": { 256 | "version": "1.19.1", 257 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", 258 | "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", 259 | "dev": true, 260 | "optional": true, 261 | "requires": { 262 | "call-bind": "^1.0.2", 263 | "es-to-primitive": "^1.2.1", 264 | "function-bind": "^1.1.1", 265 | "get-intrinsic": "^1.1.1", 266 | "get-symbol-description": "^1.0.0", 267 | "has": "^1.0.3", 268 | "has-symbols": "^1.0.2", 269 | "internal-slot": "^1.0.3", 270 | "is-callable": "^1.2.4", 271 | "is-negative-zero": "^2.0.1", 272 | "is-regex": "^1.1.4", 273 | "is-shared-array-buffer": "^1.0.1", 274 | "is-string": "^1.0.7", 275 | "is-weakref": "^1.0.1", 276 | "object-inspect": "^1.11.0", 277 | "object-keys": "^1.1.1", 278 | "object.assign": "^4.1.2", 279 | "string.prototype.trimend": "^1.0.4", 280 | "string.prototype.trimstart": "^1.0.4", 281 | "unbox-primitive": "^1.0.1" 282 | } 283 | }, 284 | "es-to-primitive": { 285 | "version": "1.2.1", 286 | "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", 287 | "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", 288 | "dev": true, 289 | "optional": true, 290 | "requires": { 291 | "is-callable": "^1.1.4", 292 | "is-date-object": "^1.0.1", 293 | "is-symbol": "^1.0.2" 294 | } 295 | }, 296 | "eventemitter3": { 297 | "version": "2.0.3", 298 | "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz", 299 | "integrity": "sha1-teEHm1n7XhuidxwKmTvgYKWMmbo=", 300 | "dev": true, 301 | "optional": true 302 | }, 303 | "function-bind": { 304 | "version": "1.1.1", 305 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 306 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 307 | "dev": true, 308 | "optional": true 309 | }, 310 | "function.prototype.name": { 311 | "version": "1.1.5", 312 | "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", 313 | "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", 314 | "dev": true, 315 | "optional": true, 316 | "requires": { 317 | "call-bind": "^1.0.2", 318 | "define-properties": "^1.1.3", 319 | "es-abstract": "^1.19.0", 320 | "functions-have-names": "^1.2.2" 321 | } 322 | }, 323 | "functions-have-names": { 324 | "version": "1.2.2", 325 | "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.2.tgz", 326 | "integrity": "sha512-bLgc3asbWdwPbx2mNk2S49kmJCuQeu0nfmaOgbs8WIyzzkw3r4htszdIi9Q9EMezDPTYuJx2wvjZ/EwgAthpnA==", 327 | "dev": true, 328 | "optional": true 329 | }, 330 | "get-intrinsic": { 331 | "version": "1.1.1", 332 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", 333 | "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", 334 | "dev": true, 335 | "optional": true, 336 | "requires": { 337 | "function-bind": "^1.1.1", 338 | "has": "^1.0.3", 339 | "has-symbols": "^1.0.1" 340 | } 341 | }, 342 | "get-symbol-description": { 343 | "version": "1.0.0", 344 | "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", 345 | "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", 346 | "dev": true, 347 | "optional": true, 348 | "requires": { 349 | "call-bind": "^1.0.2", 350 | "get-intrinsic": "^1.1.1" 351 | } 352 | }, 353 | "get-value": { 354 | "version": "2.0.6", 355 | "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", 356 | "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", 357 | "dev": true, 358 | "optional": true 359 | }, 360 | "has": { 361 | "version": "1.0.3", 362 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 363 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 364 | "dev": true, 365 | "optional": true, 366 | "requires": { 367 | "function-bind": "^1.1.1" 368 | } 369 | }, 370 | "has-bigints": { 371 | "version": "1.0.1", 372 | "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", 373 | "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", 374 | "dev": true, 375 | "optional": true 376 | }, 377 | "has-symbols": { 378 | "version": "1.0.3", 379 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 380 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 381 | "dev": true, 382 | "optional": true 383 | }, 384 | "has-tostringtag": { 385 | "version": "1.0.0", 386 | "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", 387 | "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", 388 | "dev": true, 389 | "optional": true, 390 | "requires": { 391 | "has-symbols": "^1.0.2" 392 | } 393 | }, 394 | "has-value": { 395 | "version": "0.3.1", 396 | "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", 397 | "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", 398 | "dev": true, 399 | "optional": true, 400 | "requires": { 401 | "get-value": "^2.0.3", 402 | "has-values": "^0.1.4", 403 | "isobject": "^2.0.0" 404 | }, 405 | "dependencies": { 406 | "isobject": { 407 | "version": "2.1.0", 408 | "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", 409 | "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", 410 | "dev": true, 411 | "optional": true, 412 | "requires": { 413 | "isarray": "1.0.0" 414 | } 415 | } 416 | } 417 | }, 418 | "has-values": { 419 | "version": "0.1.4", 420 | "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", 421 | "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", 422 | "dev": true, 423 | "optional": true 424 | }, 425 | "internal-slot": { 426 | "version": "1.0.3", 427 | "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", 428 | "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", 429 | "dev": true, 430 | "optional": true, 431 | "requires": { 432 | "get-intrinsic": "^1.1.0", 433 | "has": "^1.0.3", 434 | "side-channel": "^1.0.4" 435 | } 436 | }, 437 | "invariant": { 438 | "version": "2.2.4", 439 | "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", 440 | "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", 441 | "dev": true, 442 | "optional": true, 443 | "requires": { 444 | "loose-envify": "^1.0.0" 445 | } 446 | }, 447 | "is-bigint": { 448 | "version": "1.0.4", 449 | "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", 450 | "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", 451 | "dev": true, 452 | "optional": true, 453 | "requires": { 454 | "has-bigints": "^1.0.1" 455 | } 456 | }, 457 | "is-boolean-object": { 458 | "version": "1.1.2", 459 | "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", 460 | "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", 461 | "dev": true, 462 | "optional": true, 463 | "requires": { 464 | "call-bind": "^1.0.2", 465 | "has-tostringtag": "^1.0.0" 466 | } 467 | }, 468 | "is-buffer": { 469 | "version": "1.1.6", 470 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", 471 | "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", 472 | "dev": true, 473 | "optional": true 474 | }, 475 | "is-callable": { 476 | "version": "1.2.4", 477 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", 478 | "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", 479 | "dev": true, 480 | "optional": true 481 | }, 482 | "is-date-object": { 483 | "version": "1.0.5", 484 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", 485 | "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", 486 | "dev": true, 487 | "optional": true, 488 | "requires": { 489 | "has-tostringtag": "^1.0.0" 490 | } 491 | }, 492 | "is-negative-zero": { 493 | "version": "2.0.2", 494 | "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", 495 | "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", 496 | "dev": true, 497 | "optional": true 498 | }, 499 | "is-number-object": { 500 | "version": "1.0.6", 501 | "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", 502 | "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", 503 | "dev": true, 504 | "optional": true, 505 | "requires": { 506 | "has-tostringtag": "^1.0.0" 507 | } 508 | }, 509 | "is-plain-object": { 510 | "version": "2.0.4", 511 | "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", 512 | "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", 513 | "dev": true, 514 | "optional": true, 515 | "requires": { 516 | "isobject": "^3.0.1" 517 | } 518 | }, 519 | "is-regex": { 520 | "version": "1.1.4", 521 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", 522 | "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", 523 | "dev": true, 524 | "optional": true, 525 | "requires": { 526 | "call-bind": "^1.0.2", 527 | "has-tostringtag": "^1.0.0" 528 | } 529 | }, 530 | "is-shared-array-buffer": { 531 | "version": "1.0.1", 532 | "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", 533 | "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", 534 | "dev": true, 535 | "optional": true 536 | }, 537 | "is-string": { 538 | "version": "1.0.7", 539 | "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", 540 | "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", 541 | "dev": true, 542 | "optional": true, 543 | "requires": { 544 | "has-tostringtag": "^1.0.0" 545 | } 546 | }, 547 | "is-symbol": { 548 | "version": "1.0.4", 549 | "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", 550 | "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", 551 | "dev": true, 552 | "optional": true, 553 | "requires": { 554 | "has-symbols": "^1.0.2" 555 | } 556 | }, 557 | "is-weakref": { 558 | "version": "1.0.2", 559 | "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", 560 | "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", 561 | "dev": true, 562 | "optional": true, 563 | "requires": { 564 | "call-bind": "^1.0.2" 565 | } 566 | }, 567 | "isarray": { 568 | "version": "1.0.0", 569 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 570 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", 571 | "dev": true, 572 | "optional": true 573 | }, 574 | "isobject": { 575 | "version": "3.0.1", 576 | "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", 577 | "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", 578 | "dev": true, 579 | "optional": true 580 | }, 581 | "js-sha1": { 582 | "version": "0.6.0", 583 | "resolved": "https://registry.npmjs.org/js-sha1/-/js-sha1-0.6.0.tgz", 584 | "integrity": "sha512-01gwBFreYydzmU9BmZxpVk6svJJHrVxEN3IOiGl6VO93bVKYETJ0sIth6DASI6mIFdt7NmfX9UiByRzsYHGU9w==", 585 | "dev": true, 586 | "optional": true 587 | }, 588 | "js-tokens": { 589 | "version": "4.0.0", 590 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 591 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 592 | "dev": true, 593 | "optional": true 594 | }, 595 | "kind-of": { 596 | "version": "3.2.2", 597 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", 598 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", 599 | "dev": true, 600 | "optional": true, 601 | "requires": { 602 | "is-buffer": "^1.1.5" 603 | } 604 | }, 605 | "lodash.camelcase": { 606 | "version": "4.3.0", 607 | "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", 608 | "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", 609 | "dev": true, 610 | "optional": true 611 | }, 612 | "lodash.upperfirst": { 613 | "version": "4.3.1", 614 | "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", 615 | "integrity": "sha1-E2Xt9DFIBIHvDRxolXpe2Z1J984=", 616 | "dev": true, 617 | "optional": true 618 | }, 619 | "loose-envify": { 620 | "version": "1.4.0", 621 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", 622 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", 623 | "dev": true, 624 | "optional": true, 625 | "requires": { 626 | "js-tokens": "^3.0.0 || ^4.0.0" 627 | } 628 | }, 629 | "mdn-data": { 630 | "version": "2.0.14", 631 | "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", 632 | "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", 633 | "dev": true, 634 | "optional": true 635 | }, 636 | "murmur2js": { 637 | "version": "1.0.0", 638 | "resolved": "https://registry.npmjs.org/murmur2js/-/murmur2js-1.0.0.tgz", 639 | "integrity": "sha1-j4NsNl0CDXTlyuW5avLnaPpI1lk=", 640 | "dev": true, 641 | "optional": true 642 | }, 643 | "node-gyp-build": { 644 | "version": "3.9.0", 645 | "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.9.0.tgz", 646 | "integrity": "sha512-zLcTg6P4AbcHPq465ZMFNXx7XpKKJh+7kkN699NiQWisR2uWYOWNWqRHAmbnmKiL4e9aLSlmy5U7rEMUXV59+A==", 647 | "dev": true, 648 | "optional": true 649 | }, 650 | "node-sketch-bridge": { 651 | "version": "0.2.0", 652 | "resolved": "https://registry.npmjs.org/node-sketch-bridge/-/node-sketch-bridge-0.2.0.tgz", 653 | "integrity": "sha512-YNUcyS/9MjkEK4kG51NQyevz/znis1dujSZYIYLpNogoxLWxvEGFZ4CRkm4Jx5aZXvsaAW6yJmI+2mOnwHa9eg==", 654 | "dev": true, 655 | "optional": true, 656 | "requires": { 657 | "node-gyp-build": "^3.3.0" 658 | } 659 | }, 660 | "normalize-css-color": { 661 | "version": "1.0.2", 662 | "resolved": "https://registry.npmjs.org/normalize-css-color/-/normalize-css-color-1.0.2.tgz", 663 | "integrity": "sha1-Apkel8zOxmI/5XOvu/Deah8+n40=", 664 | "dev": true, 665 | "optional": true 666 | }, 667 | "nth-check": { 668 | "version": "2.0.1", 669 | "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", 670 | "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", 671 | "dev": true, 672 | "optional": true, 673 | "requires": { 674 | "boolbase": "^1.0.0" 675 | } 676 | }, 677 | "object-assign": { 678 | "version": "4.1.1", 679 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 680 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", 681 | "dev": true, 682 | "optional": true 683 | }, 684 | "object-inspect": { 685 | "version": "1.12.0", 686 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", 687 | "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", 688 | "dev": true, 689 | "optional": true 690 | }, 691 | "object-is": { 692 | "version": "1.1.5", 693 | "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", 694 | "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", 695 | "dev": true, 696 | "optional": true, 697 | "requires": { 698 | "call-bind": "^1.0.2", 699 | "define-properties": "^1.1.3" 700 | } 701 | }, 702 | "object-keys": { 703 | "version": "1.1.1", 704 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", 705 | "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", 706 | "dev": true, 707 | "optional": true 708 | }, 709 | "object.assign": { 710 | "version": "4.1.2", 711 | "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", 712 | "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", 713 | "dev": true, 714 | "optional": true, 715 | "requires": { 716 | "call-bind": "^1.0.0", 717 | "define-properties": "^1.1.3", 718 | "has-symbols": "^1.0.1", 719 | "object-keys": "^1.1.1" 720 | } 721 | }, 722 | "object.entries": { 723 | "version": "1.1.5", 724 | "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", 725 | "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", 726 | "dev": true, 727 | "optional": true, 728 | "requires": { 729 | "call-bind": "^1.0.2", 730 | "define-properties": "^1.1.3", 731 | "es-abstract": "^1.19.1" 732 | } 733 | }, 734 | "omit-deep": { 735 | "version": "0.3.0", 736 | "resolved": "https://registry.npmjs.org/omit-deep/-/omit-deep-0.3.0.tgz", 737 | "integrity": "sha1-IcivNJm8rdKWUaIyy8rLxSRF6+w=", 738 | "dev": true, 739 | "optional": true, 740 | "requires": { 741 | "is-plain-object": "^2.0.1", 742 | "unset-value": "^0.1.1" 743 | } 744 | }, 745 | "pegjs": { 746 | "version": "0.10.0", 747 | "resolved": "https://registry.npmjs.org/pegjs/-/pegjs-0.10.0.tgz", 748 | "integrity": "sha1-z4uvrm7d/0tafvsYUmnqr0YQ3b0=", 749 | "dev": true, 750 | "optional": true 751 | }, 752 | "prop-types": { 753 | "version": "15.8.1", 754 | "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", 755 | "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", 756 | "dev": true, 757 | "optional": true, 758 | "requires": { 759 | "loose-envify": "^1.4.0", 760 | "object-assign": "^4.1.1", 761 | "react-is": "^16.13.1" 762 | } 763 | }, 764 | "prop-types-exact": { 765 | "version": "1.2.0", 766 | "resolved": "https://registry.npmjs.org/prop-types-exact/-/prop-types-exact-1.2.0.tgz", 767 | "integrity": "sha512-K+Tk3Kd9V0odiXFP9fwDHUYRyvK3Nun3GVyPapSIs5OBkITAm15W0CPFD/YKTkMUAbc0b9CUwRQp2ybiBIq+eA==", 768 | "dev": true, 769 | "optional": true, 770 | "requires": { 771 | "has": "^1.0.3", 772 | "object.assign": "^4.1.0", 773 | "reflect.ownkeys": "^0.2.0" 774 | } 775 | }, 776 | "react-is": { 777 | "version": "16.13.1", 778 | "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", 779 | "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", 780 | "dev": true, 781 | "optional": true 782 | }, 783 | "react-native-svg": { 784 | "version": "12.3.0", 785 | "resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-12.3.0.tgz", 786 | "integrity": "sha512-ESG1g1j7/WLD7X3XRFTQHVv0r6DpbHNNcdusngAODIxG88wpTWUZkhcM3A2HJTb+BbXTFDamHv7FwtRKWQ/ALg==", 787 | "dev": true, 788 | "optional": true, 789 | "requires": { 790 | "css-select": "^4.2.1", 791 | "css-tree": "^1.0.0-alpha.39" 792 | } 793 | }, 794 | "react-sketchapp": { 795 | "version": "3.2.6", 796 | "resolved": "https://registry.npmjs.org/react-sketchapp/-/react-sketchapp-3.2.6.tgz", 797 | "integrity": "sha512-GM4o9vE5PqeMy7RqKGWzcWcZWmJb4MROZ2oJgjNrV2v68x4/sYL40jv7ICci1Kuuno5aV5+OSyKDItkogjLOYw==", 798 | "dev": true, 799 | "optional": true, 800 | "requires": { 801 | "@lona/svg-model": "^2.0.0", 802 | "@sketch-hq/sketch-file-format-ts": "4.0.3", 803 | "airbnb-prop-types": "^2.15.0", 804 | "error-stack-parser": "^2.0.6", 805 | "invariant": "^2.2.2", 806 | "js-sha1": "^0.6.0", 807 | "murmur2js": "^1.0.0", 808 | "node-sketch-bridge": "^0.2.0", 809 | "normalize-css-color": "^1.0.1", 810 | "pegjs": "^0.10.0", 811 | "prop-types": "^15.7.2", 812 | "seedrandom": "^3.0.5", 813 | "yoga-layout-prebuilt": "^1.9.5" 814 | } 815 | }, 816 | "reflect.ownkeys": { 817 | "version": "0.2.0", 818 | "resolved": "https://registry.npmjs.org/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz", 819 | "integrity": "sha1-dJrO7H8/34tj+SegSAnpDFwLNGA=", 820 | "dev": true, 821 | "optional": true 822 | }, 823 | "rename-keys": { 824 | "version": "1.2.0", 825 | "resolved": "https://registry.npmjs.org/rename-keys/-/rename-keys-1.2.0.tgz", 826 | "integrity": "sha512-U7XpAktpbSgHTRSNRrjKSrjYkZKuhUukfoBlXWXUExCAqhzh1TU3BDRAfJmarcl5voKS+pbKU9MvyLWKZ4UEEg==", 827 | "dev": true, 828 | "optional": true 829 | }, 830 | "seedrandom": { 831 | "version": "3.0.5", 832 | "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", 833 | "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==", 834 | "dev": true, 835 | "optional": true 836 | }, 837 | "side-channel": { 838 | "version": "1.0.4", 839 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 840 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 841 | "dev": true, 842 | "optional": true, 843 | "requires": { 844 | "call-bind": "^1.0.0", 845 | "get-intrinsic": "^1.0.2", 846 | "object-inspect": "^1.9.0" 847 | } 848 | }, 849 | "source-map": { 850 | "version": "0.6.1", 851 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 852 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 853 | "dev": true, 854 | "optional": true 855 | }, 856 | "stackframe": { 857 | "version": "1.2.1", 858 | "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.1.tgz", 859 | "integrity": "sha512-h88QkzREN/hy8eRdyNhhsO7RSJ5oyTqxxmmn0dzBIMUclZsjpfmrsg81vp8mjjAs2vAZ72nyWxRUwSwmh0e4xg==", 860 | "dev": true, 861 | "optional": true 862 | }, 863 | "string.prototype.trimend": { 864 | "version": "1.0.4", 865 | "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", 866 | "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", 867 | "dev": true, 868 | "optional": true, 869 | "requires": { 870 | "call-bind": "^1.0.2", 871 | "define-properties": "^1.1.3" 872 | } 873 | }, 874 | "string.prototype.trimstart": { 875 | "version": "1.0.4", 876 | "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", 877 | "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", 878 | "dev": true, 879 | "optional": true, 880 | "requires": { 881 | "call-bind": "^1.0.2", 882 | "define-properties": "^1.1.3" 883 | } 884 | }, 885 | "svg-transform-parser": { 886 | "version": "0.0.1", 887 | "resolved": "https://registry.npmjs.org/svg-transform-parser/-/svg-transform-parser-0.0.1.tgz", 888 | "integrity": "sha1-KhWj0aswtEncSfjNzhZAxN71LR0=", 889 | "dev": true, 890 | "optional": true 891 | }, 892 | "svgpath": { 893 | "version": "2.5.0", 894 | "resolved": "https://registry.npmjs.org/svgpath/-/svgpath-2.5.0.tgz", 895 | "integrity": "sha512-o/vohwqjUO9nDAh4rcjE3KaW/v//At8UJu2LJMybXidf5QLQLVA4bxH0//4YCsr+1H4Gw1Wi/Jc62ynzSBYidw==", 896 | "dev": true, 897 | "optional": true 898 | }, 899 | "svgson": { 900 | "version": "4.1.0", 901 | "resolved": "https://registry.npmjs.org/svgson/-/svgson-4.1.0.tgz", 902 | "integrity": "sha512-DodISxHtdLKUghDYA+PGK4Qq350+CbBAkdvGLkBFSmWd9WKSg4dijgjB1IiRPTmsUCd+a7KYe+ILHtklYgQyzQ==", 903 | "dev": true, 904 | "optional": true, 905 | "requires": { 906 | "deep-rename-keys": "^0.2.1", 907 | "omit-deep": "0.3.0", 908 | "xml-reader": "2.4.3" 909 | } 910 | }, 911 | "typescript": { 912 | "version": "4.6.2", 913 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz", 914 | "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==", 915 | "dev": true 916 | }, 917 | "unbox-primitive": { 918 | "version": "1.0.1", 919 | "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", 920 | "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", 921 | "dev": true, 922 | "optional": true, 923 | "requires": { 924 | "function-bind": "^1.1.1", 925 | "has-bigints": "^1.0.1", 926 | "has-symbols": "^1.0.2", 927 | "which-boxed-primitive": "^1.0.2" 928 | } 929 | }, 930 | "unset-value": { 931 | "version": "0.1.2", 932 | "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-0.1.2.tgz", 933 | "integrity": "sha1-UGgQuGfyfCpabpsEgzYx9t5Y0xA=", 934 | "dev": true, 935 | "optional": true, 936 | "requires": { 937 | "has-value": "^0.3.1", 938 | "isobject": "^3.0.0" 939 | } 940 | }, 941 | "which-boxed-primitive": { 942 | "version": "1.0.2", 943 | "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", 944 | "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", 945 | "dev": true, 946 | "optional": true, 947 | "requires": { 948 | "is-bigint": "^1.0.1", 949 | "is-boolean-object": "^1.1.0", 950 | "is-number-object": "^1.0.4", 951 | "is-string": "^1.0.5", 952 | "is-symbol": "^1.0.3" 953 | } 954 | }, 955 | "xml-lexer": { 956 | "version": "0.2.2", 957 | "resolved": "https://registry.npmjs.org/xml-lexer/-/xml-lexer-0.2.2.tgz", 958 | "integrity": "sha1-UYGTpKozTVj8fSSLVJB5uJkH4EY=", 959 | "dev": true, 960 | "optional": true, 961 | "requires": { 962 | "eventemitter3": "^2.0.0" 963 | } 964 | }, 965 | "xml-reader": { 966 | "version": "2.4.3", 967 | "resolved": "https://registry.npmjs.org/xml-reader/-/xml-reader-2.4.3.tgz", 968 | "integrity": "sha1-n4EMr3xCWlqvuEixxFEDyecddTA=", 969 | "dev": true, 970 | "optional": true, 971 | "requires": { 972 | "eventemitter3": "^2.0.0", 973 | "xml-lexer": "^0.2.2" 974 | } 975 | }, 976 | "yoga-layout-prebuilt": { 977 | "version": "1.10.0", 978 | "resolved": "https://registry.npmjs.org/yoga-layout-prebuilt/-/yoga-layout-prebuilt-1.10.0.tgz", 979 | "integrity": "sha512-YnOmtSbv4MTf7RGJMK0FvZ+KD8OEe/J5BNnR0GHhD8J/XcG/Qvxgszm0Un6FTHWW4uHlTgP0IztiXQnGyIR45g==", 980 | "dev": true, 981 | "optional": true, 982 | "requires": { 983 | "@types/yoga-layout": "1.9.2" 984 | } 985 | } 986 | } 987 | } 988 | -------------------------------------------------------------------------------- /packages/svg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-platform/svg", 3 | "version": "0.0.1", 4 | "description": "Cross-platform React SVG primitives", 5 | "main": "lib/cjs/core.js", 6 | "sketch": "lib/esm/core.sketch.js", 7 | "types": "lib/cjs/core.native.d.ts", 8 | "scripts": { 9 | "clean": "rm -rf lib/", 10 | "build:main": "tsc -p tsconfig.json", 11 | "build:module": "tsc -p tsconfig.module.json", 12 | "build:js": "npm run build:main && npm run build:module", 13 | "copy:types": "mkdir lib/@types && cp -r src/@types/ lib/@types/", 14 | "build:types": "tsc -d -p tsconfig.json && npm run copy:types", 15 | "build": "npm run clean && npm run build:js && npm run build:types", 16 | "test": "echo \"Error: no test specified\" && exit 1" 17 | }, 18 | "keywords": [], 19 | "author": "", 20 | "license": "ISC", 21 | "devDependencies": { 22 | "@react-platform/core": "0.0.2-beta.0", 23 | "@types/node": "^17.0.21", 24 | "react-native-svg": "^12.3.0", 25 | "react-sketchapp": "^3.2.6", 26 | "typescript": "^4.6.2" 27 | }, 28 | "dependencies": { 29 | "@types/react": "^17.0.40", 30 | "@types/react-native": "^0.67.3" 31 | }, 32 | "peerDependencies": { 33 | "@react-platform/core": ">= 0.0.1" 34 | }, 35 | "optionalDependencies": { 36 | "react-sketchapp": ">= 3", 37 | "react-native-svg": "*" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /packages/svg/src/@types/react-native-svg/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'react-native-svg' { 2 | import * as React from 'react'; 3 | import * as ReactNative from 'react-native'; 4 | import { 5 | GestureResponderEvent, 6 | TransformsStyle, 7 | OpaqueColorValue, 8 | } from 'react-native'; 9 | 10 | // Common props 11 | export type NumberProp = string | number; 12 | export type NumberArray = NumberProp[] | NumberProp; 13 | 14 | export type FillRule = 'evenodd' | 'nonzero'; 15 | export type Units = 'userSpaceOnUse' | 'objectBoundingBox'; 16 | 17 | export type TextAnchor = 'start' | 'middle' | 'end'; 18 | export type FontStyle = 'normal' | 'italic' | 'oblique'; 19 | export type FontVariant = 'normal' | 'small-caps'; 20 | export type FontWeight = 21 | | NumberProp 22 | | 'normal' 23 | | 'bold' 24 | | 'bolder' 25 | | 'lighter' 26 | | '100' 27 | | '200' 28 | | '300' 29 | | '400' 30 | | '500' 31 | | '600' 32 | | '700' 33 | | '800' 34 | | '900'; 35 | export type FontStretch = 36 | | 'normal' 37 | | 'wider' 38 | | 'narrower' 39 | | 'ultra-condensed' 40 | | 'extra-condensed' 41 | | 'condensed' 42 | | 'semi-condensed' 43 | | 'semi-expanded' 44 | | 'expanded' 45 | | 'extra-expanded' 46 | | 'ultra-expanded'; 47 | export type TextDecoration = 48 | | 'none' 49 | | 'underline' 50 | | 'overline' 51 | | 'line-through' 52 | | 'blink'; 53 | export type FontVariantLigatures = 'normal' | 'none'; 54 | export type AlignmentBaseline = 55 | | 'baseline' 56 | | 'text-bottom' 57 | | 'alphabetic' 58 | | 'ideographic' 59 | | 'middle' 60 | | 'central' 61 | | 'mathematical' 62 | | 'text-top' 63 | | 'bottom' 64 | | 'center' 65 | | 'top' 66 | | 'text-before-edge' 67 | | 'text-after-edge' 68 | | 'before-edge' 69 | | 'after-edge' 70 | | 'hanging'; 71 | export type BaselineShift = 72 | | 'sub' 73 | | 'super' 74 | | 'baseline' 75 | | ReadonlyArray 76 | | NumberProp; 77 | export type LengthAdjust = 'spacing' | 'spacingAndGlyphs'; 78 | 79 | export type TextPathMethod = 'align' | 'stretch'; 80 | export type TextPathSpacing = 'auto' | 'exact'; 81 | export type TextPathMidLine = 'sharp' | 'smooth'; 82 | 83 | export type Linecap = 'butt' | 'square' | 'round'; 84 | export type Linejoin = 'miter' | 'bevel' | 'round'; 85 | 86 | export interface TouchableProps { 87 | disabled?: boolean; 88 | onPress?: (event: GestureResponderEvent) => void; 89 | onPressIn?: (event: GestureResponderEvent) => void; 90 | onPressOut?: (event: GestureResponderEvent) => void; 91 | onLongPress?: (event: GestureResponderEvent) => void; 92 | delayPressIn?: number; 93 | delayPressOut?: number; 94 | delayLongPress?: number; 95 | } 96 | 97 | export interface ResponderProps extends ReactNative.GestureResponderHandlers { 98 | pointerEvents?: 'box-none' | 'none' | 'box-only' | 'auto'; 99 | } 100 | 101 | // rgba values inside range 0 to 1 inclusive 102 | // rgbaArray = [r, g, b, a] 103 | export type rgbaArray = ReadonlyArray; 104 | 105 | // argb values inside range 0x00 to 0xff inclusive 106 | // int32ARGBColor = 0xaarrggbb 107 | export type int32ARGBColor = number; 108 | 109 | export type Color = int32ARGBColor | rgbaArray | OpaqueColorValue | string; 110 | 111 | export interface FillProps { 112 | fill?: Color; 113 | fillOpacity?: NumberProp; 114 | fillRule?: FillRule; 115 | } 116 | 117 | export interface ClipProps { 118 | clipRule?: FillRule; 119 | clipPath?: string; 120 | } 121 | 122 | export interface VectorEffectProps { 123 | vectorEffect?: 124 | | 'none' 125 | | 'non-scaling-stroke' 126 | | 'nonScalingStroke' 127 | | 'default' 128 | | 'inherit' 129 | | 'uri'; 130 | } 131 | 132 | export interface DefinitionProps { 133 | id?: string; 134 | } 135 | 136 | export interface StrokeProps { 137 | stroke?: Color; 138 | strokeWidth?: NumberProp; 139 | strokeOpacity?: NumberProp; 140 | strokeDasharray?: ReadonlyArray | NumberProp; 141 | strokeDashoffset?: NumberProp; 142 | strokeLinecap?: Linecap; 143 | strokeLinejoin?: Linejoin; 144 | strokeMiterlimit?: NumberProp; 145 | } 146 | 147 | export interface FontObject { 148 | fontStyle?: FontStyle; 149 | fontVariant?: FontVariant; 150 | fontWeight?: FontWeight; 151 | fontStretch?: FontStretch; 152 | fontSize?: NumberProp; 153 | fontFamily?: string; 154 | textAnchor?: TextAnchor; 155 | textDecoration?: TextDecoration; 156 | letterSpacing?: NumberProp; 157 | wordSpacing?: NumberProp; 158 | kerning?: NumberProp; 159 | fontFeatureSettings?: string; 160 | fontVariantLigatures?: FontVariantLigatures; 161 | fontVariationSettings?: string; 162 | } 163 | 164 | export interface FontProps extends FontObject { 165 | font?: FontObject; 166 | } 167 | 168 | export interface TransformObject { 169 | translate?: NumberArray; 170 | translateX?: NumberProp; 171 | translateY?: NumberProp; 172 | origin?: NumberArray; 173 | originX?: NumberProp; 174 | originY?: NumberProp; 175 | scale?: NumberArray; 176 | scaleX?: NumberProp; 177 | scaleY?: NumberProp; 178 | skew?: NumberArray; 179 | skewX?: NumberProp; 180 | skewY?: NumberProp; 181 | rotation?: NumberProp; 182 | x?: NumberArray; 183 | y?: NumberArray; 184 | } 185 | 186 | /* 187 | ColumnMajorTransformMatrix 188 | [a, b, c, d, tx, ty] 189 | This matrix can be visualized as: 190 | ╔═ ═╗ 191 | ║ a c tx ║ 192 | ║ b d ty ║ 193 | ║ 0 0 1 ║ 194 | ╚═ ═╝ 195 | */ 196 | export type ColumnMajorTransformMatrix = [ 197 | number, 198 | number, 199 | number, 200 | number, 201 | number, 202 | number, 203 | ]; 204 | 205 | export interface TransformProps extends TransformObject { 206 | transform?: 207 | | ColumnMajorTransformMatrix 208 | | string 209 | | TransformObject 210 | | TransformsStyle['transform']; 211 | } 212 | 213 | export interface CommonMaskProps { 214 | mask?: string; 215 | } 216 | 217 | export interface CommonMarkerProps { 218 | marker?: string; 219 | markerStart?: string; 220 | markerMid?: string; 221 | markerEnd?: string; 222 | } 223 | 224 | interface StyleProps { 225 | style?: React.CSSProperties | undefined; 226 | } 227 | 228 | export interface CommonPathProps 229 | extends StyleProps, 230 | FillProps, 231 | StrokeProps, 232 | ClipProps, 233 | TransformProps, 234 | VectorEffectProps, 235 | ResponderProps, 236 | TouchableProps, 237 | DefinitionProps, 238 | CommonMarkerProps, 239 | CommonMaskProps {} 240 | 241 | // Element props 242 | export interface CircleProps extends CommonPathProps { 243 | cx?: NumberProp; 244 | cy?: NumberProp; 245 | opacity?: NumberProp; 246 | r?: NumberProp; 247 | } 248 | export const Circle: React.ComponentClass; 249 | export type Circle = React.ComponentClass; 250 | 251 | export interface ClipPathProps { 252 | id?: string; 253 | } 254 | export const ClipPath: React.ComponentClass; 255 | export type ClipPath = React.ComponentClass; 256 | 257 | export const Defs: React.ComponentClass<{}>; 258 | export type Defs = React.ComponentClass<{}>; 259 | 260 | export interface EllipseProps extends CommonPathProps { 261 | cx?: NumberProp; 262 | cy?: NumberProp; 263 | opacity?: NumberProp; 264 | rx?: NumberProp; 265 | ry?: NumberProp; 266 | } 267 | export const Ellipse: React.ComponentClass; 268 | export type Ellipse = React.ComponentClass; 269 | 270 | export interface GProps extends CommonPathProps, FontProps { 271 | opacity?: NumberProp; 272 | } 273 | export const G: React.ComponentClass; 274 | export type G = React.ComponentClass; 275 | 276 | export interface ForeignObjectProps { 277 | x?: NumberProp; 278 | y?: NumberProp; 279 | width?: NumberProp; 280 | height?: NumberProp; 281 | } 282 | export const ForeignObject: React.ComponentClass; 283 | export type ForeignObject = React.ComponentClass; 284 | 285 | export interface ImageProps 286 | extends ResponderProps, 287 | CommonMaskProps, 288 | ClipProps, 289 | TouchableProps { 290 | x?: NumberProp; 291 | y?: NumberProp; 292 | width?: NumberProp; 293 | height?: NumberProp; 294 | xlinkHref?: ReactNative.ImageProps['source']; 295 | href?: ReactNative.ImageProps['source']; 296 | preserveAspectRatio?: string; 297 | opacity?: NumberProp; 298 | clipPath?: string; 299 | id?: string; 300 | } 301 | export const Image: React.ComponentClass; 302 | export type Image = React.ComponentClass; 303 | 304 | export interface LineProps extends CommonPathProps { 305 | opacity?: NumberProp; 306 | x1?: NumberProp; 307 | x2?: NumberProp; 308 | y1?: NumberProp; 309 | y2?: NumberProp; 310 | } 311 | export const Line: React.ComponentClass; 312 | export type Line = React.ComponentClass; 313 | 314 | export interface LinearGradientProps { 315 | x1?: NumberProp; 316 | x2?: NumberProp; 317 | y1?: NumberProp; 318 | y2?: NumberProp; 319 | gradientUnits?: Units; 320 | gradientTransform?: ColumnMajorTransformMatrix | string; 321 | id?: string; 322 | } 323 | export const LinearGradient: React.ComponentClass; 324 | export type LinearGradient = React.ComponentClass; 325 | 326 | export interface PathProps extends CommonPathProps { 327 | d?: string; 328 | opacity?: NumberProp; 329 | } 330 | export const Path: React.ComponentClass; 331 | export type Path = React.ComponentClass; 332 | 333 | export interface PatternProps { 334 | id?: string; 335 | x?: NumberProp; 336 | y?: NumberProp; 337 | width?: NumberProp; 338 | height?: NumberProp; 339 | patternTransform?: ColumnMajorTransformMatrix | string; 340 | patternUnits?: Units; 341 | patternContentUnits?: Units; 342 | viewBox?: string; 343 | preserveAspectRatio?: string; 344 | } 345 | export const Pattern: React.ComponentClass; 346 | export type Pattern = React.ComponentClass; 347 | 348 | export interface PolygonProps extends CommonPathProps { 349 | opacity?: NumberProp; 350 | points?: string | ReadonlyArray; 351 | } 352 | export const Polygon: React.ComponentClass; 353 | export type Polygon = React.ComponentClass; 354 | 355 | export interface PolylineProps extends CommonPathProps { 356 | opacity?: NumberProp; 357 | points?: string | ReadonlyArray; 358 | } 359 | export const Polyline: React.ComponentClass; 360 | export type Polyline = React.ComponentClass; 361 | 362 | export interface RadialGradientProps { 363 | fx?: NumberProp; 364 | fy?: NumberProp; 365 | rx?: NumberProp; 366 | ry?: NumberProp; 367 | cx?: NumberProp; 368 | cy?: NumberProp; 369 | r?: NumberProp; 370 | gradientUnits?: Units; 371 | gradientTransform?: ColumnMajorTransformMatrix | string; 372 | id?: string; 373 | } 374 | export const RadialGradient: React.ComponentClass; 375 | export type RadialGradient = React.ComponentClass; 376 | 377 | export interface RectProps extends CommonPathProps { 378 | x?: NumberProp; 379 | y?: NumberProp; 380 | width?: NumberProp; 381 | height?: NumberProp; 382 | rx?: NumberProp; 383 | ry?: NumberProp; 384 | opacity?: NumberProp; 385 | } 386 | export const Rect: React.ComponentClass; 387 | export type Rect = React.ComponentClass; 388 | 389 | export interface StopProps { 390 | stopColor?: Color; 391 | stopOpacity?: NumberProp; 392 | offset?: NumberProp; 393 | } 394 | export const Stop: React.ComponentClass; 395 | export type Stop = React.ComponentClass; 396 | 397 | interface ViewPropsWithoutStyle extends Omit { 398 | ref?: any; 399 | } 400 | 401 | export interface SvgProps extends GProps, ViewPropsWithoutStyle { 402 | width?: NumberProp; 403 | height?: NumberProp; 404 | viewBox?: string; 405 | preserveAspectRatio?: string; 406 | color?: Color; 407 | title?: string; 408 | style?: React.CSSProperties; 409 | 410 | /* */ 411 | xmlns?: string; 412 | xmlnsXlink?: string; 413 | /* */ 414 | } 415 | 416 | // Svg is both regular and default exported 417 | export const Svg: React.ComponentClass; 418 | export type Svg = React.ComponentClass; 419 | export default Svg; 420 | 421 | export interface SymbolProps { 422 | id?: string; 423 | viewBox?: string; 424 | preserveAspectRatio?: string; 425 | opacity?: NumberProp; 426 | } 427 | export const Symbol: React.ComponentClass; 428 | export type Symbol = React.ComponentClass; 429 | 430 | export interface TSpanProps extends CommonPathProps, FontProps { 431 | x?: NumberArray; 432 | y?: NumberArray; 433 | dx?: NumberArray; 434 | dy?: NumberArray; 435 | rotate?: NumberArray; 436 | inlineSize?: NumberProp; 437 | } 438 | export const TSpan: React.ComponentClass; 439 | export type TSpan = React.ComponentClass; 440 | 441 | export interface TextSpecificProps extends CommonPathProps, FontProps { 442 | alignmentBaseline?: AlignmentBaseline; 443 | baselineShift?: BaselineShift; 444 | verticalAlign?: NumberProp; 445 | lengthAdjust?: LengthAdjust; 446 | textLength?: NumberProp; 447 | fontData?: null | { [name: string]: unknown }; 448 | fontFeatureSettings?: string; 449 | } 450 | 451 | export interface TextProps extends TextSpecificProps { 452 | x?: NumberArray; 453 | y?: NumberArray; 454 | dx?: NumberArray; 455 | dy?: NumberArray; 456 | rotate?: NumberArray; 457 | opacity?: NumberProp; 458 | inlineSize?: NumberProp; 459 | } 460 | export const Text: React.ComponentClass; 461 | export type Text = React.ComponentClass; 462 | 463 | export interface TextPathProps extends TextSpecificProps { 464 | xlinkHref?: string; 465 | href?: string; 466 | startOffset?: NumberProp; 467 | method?: TextPathMethod; 468 | spacing?: TextPathSpacing; 469 | midLine?: TextPathMidLine; 470 | } 471 | export const TextPath: React.ComponentClass; 472 | export type TextPath = React.ComponentClass; 473 | 474 | export interface UseProps extends CommonPathProps { 475 | xlinkHref?: string; 476 | href?: string; 477 | width?: NumberProp; 478 | height?: NumberProp; 479 | x?: NumberProp; 480 | y?: NumberProp; 481 | opacity?: NumberProp; 482 | } 483 | export const Use: React.ComponentClass; 484 | export type Use = React.ComponentClass; 485 | 486 | export enum EMaskUnits { 487 | USER_SPACE_ON_USE = 'userSpaceOnUse', 488 | OBJECT_BOUNDING_BOX = 'objectBoundingBox', 489 | } 490 | 491 | export type TMaskUnits = 492 | | EMaskUnits.USER_SPACE_ON_USE 493 | | EMaskUnits.OBJECT_BOUNDING_BOX; 494 | 495 | export interface MaskProps extends CommonPathProps { 496 | id?: string; 497 | x?: NumberProp; 498 | y?: NumberProp; 499 | width?: NumberProp; 500 | height?: NumberProp; 501 | maskTransform?: ColumnMajorTransformMatrix | string; 502 | maskUnits?: TMaskUnits; 503 | maskContentUnits?: TMaskUnits; 504 | } 505 | export const Mask: React.ComponentClass; 506 | export type Mask = React.ComponentClass; 507 | 508 | export enum MarkerUnits { 509 | STROKE_WIDTH = 'strokeWidth', 510 | USER_SPACE_ON_USE = 'userSpaceOnUse', 511 | } 512 | 513 | export enum Orient { 514 | AUTO = 'auto', 515 | AUTO_START_REVERSE = 'auto-start-reverse', 516 | } 517 | 518 | export interface MarkerProps { 519 | id?: string; 520 | viewBox?: string; 521 | preserveAspectRatio?: string; 522 | refX?: NumberProp; 523 | refY?: NumberProp; 524 | markerWidth?: NumberProp; 525 | markerHeight?: NumberProp; 526 | markerUnits?: MarkerUnits; 527 | orient?: Orient | NumberProp; 528 | } 529 | export const Marker: React.ComponentClass; 530 | export type Marker = React.ComponentClass; 531 | 532 | export type Styles = { [property: string]: string }; 533 | 534 | export interface AST { 535 | tag: string; 536 | style?: Styles; 537 | styles?: string; 538 | priority?: Map; 539 | parent: AST | null; 540 | children: (AST | string)[] | (JSX.Element | string)[]; 541 | props: { 542 | [prop: string]: Styles | string | undefined; 543 | }; 544 | Tag: React.ComponentType; 545 | } 546 | 547 | export interface XmlAST extends AST { 548 | children: (XmlAST | string)[]; 549 | parent: XmlAST | null; 550 | } 551 | 552 | export interface JsxAST extends AST { 553 | children: (JSX.Element | string)[]; 554 | } 555 | 556 | export interface UriProps extends SvgProps { 557 | uri: string | null; 558 | override?: SvgProps; 559 | } 560 | export type UriState = { xml: string | null }; 561 | 562 | export interface XmlProps extends SvgProps { 563 | xml: string | null; 564 | override?: SvgProps; 565 | } 566 | export type XmlState = { ast: JsxAST | null }; 567 | 568 | export interface AstProps extends SvgProps { 569 | ast: JsxAST | null; 570 | override?: SvgProps; 571 | } 572 | 573 | export type Middleware = (ast: XmlAST) => XmlAST; 574 | 575 | export function parse(source: string, middleware?: Middleware): JsxAST | null; 576 | 577 | export const SvgAst: React.FunctionComponent; 578 | 579 | export const SvgXml: React.FunctionComponent; 580 | export const SvgFromXml: React.ComponentClass; 581 | 582 | export const SvgUri: React.FunctionComponent; 583 | export const SvgFromUri: React.ComponentClass; 584 | 585 | export const SvgCss: React.FunctionComponent; 586 | export const SvgWithCss: React.ComponentClass; 587 | 588 | export const SvgCssUri: React.FunctionComponent; 589 | export const SvgWithCssUri: React.ComponentClass; 590 | 591 | export const inlineStyles: Middleware; 592 | } -------------------------------------------------------------------------------- /packages/svg/src/cjs/common/index.tsx: -------------------------------------------------------------------------------- 1 | // Stubs to prevent crashes 2 | // @ts-ignore 3 | import { StyleSheet, View } from '@react-platform/core'; 4 | import { ReactNode } from 'react'; 5 | 6 | 7 | 8 | const Circle = () => null; 9 | 10 | const ClipPath = () => null; 11 | 12 | const Ellipse = () => null; 13 | 14 | const G = () => null; 15 | 16 | const Image = () => null; 17 | 18 | const LinearGradient = () => null; 19 | 20 | const RadialGradient = () => null; 21 | 22 | const Line = () => null; 23 | 24 | const Path = () => null; 25 | 26 | const Pattern = () => null; 27 | 28 | const Polygon = () => null; 29 | 30 | const Polyline = () => null; 31 | 32 | const Rect = () => null; 33 | 34 | const SvgSymbol = () => null; 35 | 36 | const Text = () => null; 37 | 38 | const TextPath = () => null; 39 | 40 | const TSpan = () => null; 41 | 42 | const Use = () => null; 43 | 44 | const Defs = () => null; 45 | 46 | const Stop = () => null; 47 | 48 | // TODO: Render some warning text that svgs do not work on this platform, or a placeholder coloured rectangle or something 49 | const Svg = ({ children, width = 64, height = 64 }: { children: ReactNode, width?: number, height?: number }) => ( 50 | 51 | {children} 52 | 53 | ); 54 | 55 | 56 | export { 57 | Svg, 58 | Circle, 59 | ClipPath, 60 | Ellipse, 61 | G, 62 | Image, 63 | LinearGradient, 64 | RadialGradient, 65 | Line, 66 | Path, 67 | Pattern, 68 | Polygon, 69 | Polyline, 70 | Rect, 71 | SvgSymbol as Symbol, 72 | Text, 73 | TextPath, 74 | TSpan, 75 | Use, 76 | Defs, 77 | Stop, 78 | }; 79 | 80 | export default Svg; -------------------------------------------------------------------------------- /packages/svg/src/cjs/core.native.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-named-as-default */ 2 | import '../@types/react-native-svg'; 3 | 4 | export * from 'react-native-svg'; 5 | export { default } from 'react-native-svg'; 6 | -------------------------------------------------------------------------------- /packages/svg/src/cjs/core.sketch.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-named-as-default */ 2 | 3 | import { Svg } from 'react-sketchapp'; 4 | 5 | const { 6 | Circle, 7 | ClipPath, 8 | Defs, 9 | Ellipse, 10 | G, 11 | Image, 12 | Line, 13 | LinearGradient, 14 | Path, 15 | Pattern, 16 | Polygon, 17 | Polyline, 18 | RadialGradient, 19 | Rect, 20 | Stop, 21 | Symbol, 22 | Text, 23 | TextPath, 24 | TSpan, 25 | Use, 26 | } = Svg; 27 | 28 | export { 29 | Svg, 30 | Circle, 31 | ClipPath, 32 | Defs, 33 | Ellipse, 34 | G, 35 | Image, 36 | Line, 37 | LinearGradient, 38 | Path, 39 | Pattern, 40 | Polygon, 41 | Polyline, 42 | RadialGradient, 43 | Rect, 44 | Stop, 45 | Symbol, 46 | Text, 47 | TextPath, 48 | TSpan, 49 | Use, 50 | }; 51 | 52 | export default Svg; 53 | -------------------------------------------------------------------------------- /packages/svg/src/cjs/core.ts: -------------------------------------------------------------------------------- 1 | let svg; 2 | 3 | if (typeof window !== 'undefined') { 4 | svg = require('./core.web'); 5 | } else { 6 | svg = require('./common'); 7 | } 8 | 9 | export = svg; 10 | -------------------------------------------------------------------------------- /packages/svg/src/cjs/core.web.ts: -------------------------------------------------------------------------------- 1 | import 'react-dom'; 2 | 3 | const Svg = 'svg'; 4 | const Circle = 'circle'; 5 | const ClipPath = 'clipPath'; 6 | const Ellipse = 'ellipse'; 7 | const G = 'g'; 8 | const Image = 'image'; 9 | const LinearGradient = 'linearGradient'; 10 | const RadialGradient = 'radialGradient'; 11 | const Line = 'line'; 12 | const Path = 'path'; 13 | const Pattern = 'pattern'; 14 | const Polygon = 'polygon'; 15 | const Polyline = 'polyline'; 16 | const Rect = 'rect'; 17 | const Symbol = 'symbol'; 18 | const Text = 'text'; 19 | const TextPath = 'textPath'; 20 | const TSpan = 'tspan'; 21 | const Use = 'use'; 22 | const Defs = 'defs'; 23 | const Stop = 'stop'; 24 | 25 | export { 26 | Svg, 27 | Circle, 28 | ClipPath, 29 | Ellipse, 30 | G, 31 | Image, 32 | LinearGradient, 33 | RadialGradient, 34 | Line, 35 | Path, 36 | Pattern, 37 | Polygon, 38 | Polyline, 39 | Rect, 40 | Symbol, 41 | Text, 42 | TextPath, 43 | TSpan, 44 | Use, 45 | Defs, 46 | Stop, 47 | }; 48 | 49 | export default Svg; 50 | -------------------------------------------------------------------------------- /packages/svg/src/esm/common/index.tsx: -------------------------------------------------------------------------------- 1 | // Stubs to prevent crashes 2 | // @ts-ignore 3 | import { StyleSheet, View } from '@react-platform/core'; 4 | import { ReactNode } from 'react'; 5 | 6 | 7 | 8 | const Circle = () => null; 9 | 10 | const ClipPath = () => null; 11 | 12 | const Ellipse = () => null; 13 | 14 | const G = () => null; 15 | 16 | const Image = () => null; 17 | 18 | const LinearGradient = () => null; 19 | 20 | const RadialGradient = () => null; 21 | 22 | const Line = () => null; 23 | 24 | const Path = () => null; 25 | 26 | const Pattern = () => null; 27 | 28 | const Polygon = () => null; 29 | 30 | const Polyline = () => null; 31 | 32 | const Rect = () => null; 33 | 34 | const SvgSymbol = () => null; 35 | 36 | const Text = () => null; 37 | 38 | const TextPath = () => null; 39 | 40 | const TSpan = () => null; 41 | 42 | const Use = () => null; 43 | 44 | const Defs = () => null; 45 | 46 | const Stop = () => null; 47 | 48 | // TODO: Render some warning text that svgs do not work on this platform, or a placeholder coloured rectangle or something 49 | const Svg = ({ children, width = 64, height = 64 }: { children: ReactNode, width?: number, height?: number }) => ( 50 | 51 | {children} 52 | 53 | ); 54 | 55 | 56 | export { 57 | Svg, 58 | Circle, 59 | ClipPath, 60 | Ellipse, 61 | G, 62 | Image, 63 | LinearGradient, 64 | RadialGradient, 65 | Line, 66 | Path, 67 | Pattern, 68 | Polygon, 69 | Polyline, 70 | Rect, 71 | SvgSymbol as Symbol, 72 | Text, 73 | TextPath, 74 | TSpan, 75 | Use, 76 | Defs, 77 | Stop, 78 | }; 79 | 80 | export default Svg; 81 | -------------------------------------------------------------------------------- /packages/svg/src/esm/core.native.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-named-as-default */ 2 | import '../@types/react-native-svg'; 3 | 4 | export * from 'react-native-svg'; 5 | export { default } from 'react-native-svg'; 6 | -------------------------------------------------------------------------------- /packages/svg/src/esm/core.sketch.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-named-as-default */ 2 | 3 | import { Svg } from 'react-sketchapp'; 4 | 5 | const { 6 | Circle, 7 | ClipPath, 8 | Defs, 9 | Ellipse, 10 | G, 11 | Image, 12 | Line, 13 | LinearGradient, 14 | Path, 15 | Pattern, 16 | Polygon, 17 | Polyline, 18 | RadialGradient, 19 | Rect, 20 | Stop, 21 | Symbol, 22 | Text, 23 | TextPath, 24 | TSpan, 25 | Use, 26 | } = Svg; 27 | 28 | export { 29 | Svg, 30 | Circle, 31 | ClipPath, 32 | Defs, 33 | Ellipse, 34 | G, 35 | Image, 36 | Line, 37 | LinearGradient, 38 | Path, 39 | Pattern, 40 | Polygon, 41 | Polyline, 42 | RadialGradient, 43 | Rect, 44 | Stop, 45 | Symbol, 46 | Text, 47 | TextPath, 48 | TSpan, 49 | Use, 50 | }; 51 | 52 | export default Svg; 53 | -------------------------------------------------------------------------------- /packages/svg/src/esm/core.ts: -------------------------------------------------------------------------------- 1 | let svg; 2 | 3 | if (typeof window !== 'undefined') { 4 | svg = require('./core.web'); 5 | } else { 6 | svg = require('./common'); 7 | } 8 | 9 | const { 10 | Svg, 11 | Circle, 12 | ClipPath, 13 | Ellipse, 14 | G, 15 | Image, 16 | LinearGradient, 17 | RadialGradient, 18 | Line, 19 | Path, 20 | Pattern, 21 | Polygon, 22 | Polyline, 23 | Rect, 24 | Symbol, 25 | Text, 26 | TextPath, 27 | TSpan, 28 | Use, 29 | Defs, 30 | Stop, 31 | } = svg; 32 | 33 | export { 34 | Svg, 35 | Circle, 36 | ClipPath, 37 | Ellipse, 38 | G, 39 | Image, 40 | LinearGradient, 41 | RadialGradient, 42 | Line, 43 | Path, 44 | Pattern, 45 | Polygon, 46 | Polyline, 47 | Rect, 48 | Symbol, 49 | Text, 50 | TextPath, 51 | TSpan, 52 | Use, 53 | Defs, 54 | Stop, 55 | }; 56 | 57 | export default svg; 58 | -------------------------------------------------------------------------------- /packages/svg/src/esm/core.web.ts: -------------------------------------------------------------------------------- 1 | import 'react-dom'; 2 | 3 | const Svg = 'svg'; 4 | const Circle = 'circle'; 5 | const ClipPath = 'clipPath'; 6 | const Ellipse = 'ellipse'; 7 | const G = 'g'; 8 | const Image = 'image'; 9 | const LinearGradient = 'linearGradient'; 10 | const RadialGradient = 'radialGradient'; 11 | const Line = 'line'; 12 | const Path = 'path'; 13 | const Pattern = 'pattern'; 14 | const Polygon = 'polygon'; 15 | const Polyline = 'polyline'; 16 | const Rect = 'rect'; 17 | const Symbol = 'symbol'; 18 | const Text = 'text'; 19 | const TextPath = 'textPath'; 20 | const TSpan = 'tspan'; 21 | const Use = 'use'; 22 | const Defs = 'defs'; 23 | const Stop = 'stop'; 24 | 25 | export { 26 | Svg, 27 | Circle, 28 | ClipPath, 29 | Ellipse, 30 | G, 31 | Image, 32 | LinearGradient, 33 | RadialGradient, 34 | Line, 35 | Path, 36 | Pattern, 37 | Polygon, 38 | Polyline, 39 | Rect, 40 | Symbol, 41 | Text, 42 | TextPath, 43 | TSpan, 44 | Use, 45 | Defs, 46 | Stop, 47 | }; 48 | 49 | export default Svg; 50 | -------------------------------------------------------------------------------- /packages/svg/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "lib", 4 | "rootDir": "src", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "module": "commonjs", 7 | "target": "es5", 8 | "baseUrl": "./", 9 | 10 | "allowJs": true, 11 | "allowSyntheticDefaultImports": true, 12 | "esModuleInterop": true, 13 | "forceConsistentCasingInFileNames": true, 14 | "isolatedModules": true, 15 | "jsx": "react-jsx", 16 | "moduleResolution": "node", 17 | "noFallthroughCasesInSwitch": true, 18 | "resolveJsonModule": true, 19 | "skipLibCheck": true, 20 | "strict": true, 21 | "typeRoots": ["node_modules/@types", "src/@types"] 22 | }, 23 | "include": [ 24 | "src/cjs/**/*" 25 | ], 26 | "exclude": [ 27 | "node_modules" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /packages/svg/tsconfig.module.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "module": "esnext", 5 | }, 6 | "include": [ 7 | "src/esm/**/*" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "lib", 4 | "sourceMap": true, 5 | "noImplicitAny": true, 6 | "module": "commonjs", 7 | "target": "es6", 8 | "jsx": "react", 9 | "lib": [ 10 | "es5", 11 | "dom" 12 | ], 13 | "declaration": true, 14 | "inlineSourceMap": false, 15 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, 16 | "strict": true /* Enable all strict type-checking options. */, 17 | }, 18 | } 19 | --------------------------------------------------------------------------------