From bf04aef9f9dce5bf627e7ebd7e913ea10ac3ff63 Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Fri, 16 Nov 2018 12:20:25 +0000 Subject: [PATCH 01/44] adding prettier --- dev/examples/test.tsx | 10 +- package.json | 80 ++++++++------- src/index.ts | 2 +- yarn.lock | 223 +++++++++++++++++++++++++++++++++++++++++- 4 files changed, 269 insertions(+), 46 deletions(-) diff --git a/dev/examples/test.tsx b/dev/examples/test.tsx index ed6f2dedbf..fc39a47132 100644 --- a/dev/examples/test.tsx +++ b/dev/examples/test.tsx @@ -1,9 +1,9 @@ -import * as React from "react" +import * as React from "react"; -import { Test } from "@framer" +import { Test } from "@framer"; export class App extends React.Component { - render() { - return - } + render() { + return ; + } } diff --git a/package.json b/package.json index 0728ca27e3..7de5e59205 100644 --- a/package.json +++ b/package.json @@ -1,38 +1,46 @@ { - "name": "framer", - "version": "0.0.1", - "main": "build/framer.js", - "types": "build/framer.d.ts", - "author": "Framer Motion", - "license": "MIT", - "scripts": { - "coverage": "jest --config jest.json --coverage", - "test": "jest --config jest.json", - "watch": "jest --config jest.json --watch" - }, - "peerDependencies": { - "react": "^16.7", - "react-dom": "^16.7" - }, - "devDependencies": { - "@types/node": "^10.12.9", - "@types/react": "^16.7.6", - "@types/react-dom": "^16.0.9", - "cache-loader": "^1.2.5", - "convert-tsconfig-paths-to-webpack-aliases": "^0.9.2", - "fork-ts-checker-webpack-plugin": "^0.4.15", - "progress-bar-webpack-plugin": "^1.11.0", - "react": "^16.7.0-alpha.2", - "ts-loader": "^5.3.0", - "tslint": "^5.11.0", - "tslint-microsoft-contrib": "^5.2.1", - "typescript": "^3.1.6", - "webpack": "^4.25.1", - "webpack-cli": "^3.1.2", - "webpack-dev-server": "^3.1.10" - }, - "dependencies": { - "react-dev-utils": "^6.1.1", - "react-dom": "^16.7.0-alpha.2" - } + "name": "framer-motion", + "version": "0.0.1", + "private": true, + "main": "build/framer.js", + "types": "build/framer.d.ts", + "author": "Framer Motion", + "license": "MIT", + "scripts": { + "coverage": "jest --config jest.json --coverage", + "test": "jest --config jest.json", + "watch": "jest --config jest.json --watch", + "prettier": "prettier ./src/* --write" + }, + "peerDependencies": { + "react": "^16.7", + "react-dom": "^16.7" + }, + "devDependencies": { + "@types/node": "^10.12.9", + "@types/react": "^16.7.6", + "@types/react-dom": "^16.0.9", + "cache-loader": "^1.2.5", + "convert-tsconfig-paths-to-webpack-aliases": "^0.9.2", + "fork-ts-checker-webpack-plugin": "^0.4.15", + "prettier": "^1.15.2", + "progress-bar-webpack-plugin": "^1.11.0", + "react": "^16.7.0-alpha.2", + "ts-loader": "^5.3.0", + "tslint": "^5.11.0", + "tslint-microsoft-contrib": "^5.2.1", + "typescript": "^3.1.6", + "webpack": "^4.25.1", + "webpack-cli": "^3.1.2", + "webpack-dev-server": "^3.1.10" + }, + "dependencies": { + "husky": "^1.1.4", + "react-dev-utils": "^6.1.1", + "react-dom": "^16.7.0-alpha.2" + }, + "prettier": { + "parser": "typescript", + "singleQuote": true + } } diff --git a/src/index.ts b/src/index.ts index 0a3c0710b3..38aa2796da 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1 @@ -export { Test } from "./test" +export { Test } from './test'; diff --git a/yarn.lock b/yarn.lock index a2549e9310..649cfdad43 100644 --- a/yarn.lock +++ b/yarn.lock @@ -629,7 +629,7 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" -builtin-modules@^1.1.1: +builtin-modules@^1.0.0, builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= @@ -693,6 +693,25 @@ call-me-maybe@^1.0.1: resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= +caller-callsite@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" + integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= + dependencies: + callsites "^2.0.0" + +caller-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" + integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= + dependencies: + caller-callsite "^2.0.0" + +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= + camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" @@ -760,6 +779,11 @@ chrome-trace-event@^1.0.0: dependencies: tslib "^1.9.0" +ci-info@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" + integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== + cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" @@ -948,6 +972,16 @@ core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= +cosmiconfig@^5.0.6: + version "5.0.7" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.7.tgz#39826b292ee0d78eda137dfa3173bd1c21a43b04" + integrity sha512-PcLqxTKiDmNT6pSpy4N6KtuPwb53W+2tzNvwOZw0WH9N6O0vLIBq0x8aj8Oj75ere4YcGi48bDFCL+3fRJdlNA== + dependencies: + import-fresh "^2.0.0" + is-directory "^0.3.1" + js-yaml "^3.9.0" + parse-json "^4.0.0" + create-ecdh@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" @@ -1273,6 +1307,13 @@ errno@^0.1.3, errno@~0.1.7: dependencies: prr "~1.0.1" +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -1363,6 +1404,19 @@ execa@^0.10.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" @@ -1664,11 +1718,23 @@ get-caller-file@^1.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== +get-stdin@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" + integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== + get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -1851,6 +1917,11 @@ homedir-polyfill@^1.0.1: dependencies: parse-passwd "^1.0.0" +hosted-git-info@^2.1.4: + version "2.7.1" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" + integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== + hpack.js@^2.1.6: version "2.1.6" resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" @@ -1910,6 +1981,22 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= +husky@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/husky/-/husky-1.1.4.tgz#92f61383527d2571e9586234e5864356bfaceaa9" + integrity sha512-cZjGpS7qsaBSo3fOMUuR7erQloX3l5XzL1v/RkIqU6zrQImDdU70z5Re9fGDp7+kbYlM2EtS4aYMlahBeiCUGw== + dependencies: + cosmiconfig "^5.0.6" + execa "^1.0.0" + find-up "^3.0.0" + get-stdin "^6.0.0" + is-ci "^1.2.1" + pkg-dir "^3.0.0" + please-upgrade-node "^3.1.1" + read-pkg "^4.0.1" + run-node "^1.0.0" + slash "^2.0.0" + iconv-lite@0.4.23: version "0.4.23" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" @@ -1951,6 +2038,14 @@ immer@1.7.2: resolved "https://registry.yarnpkg.com/immer/-/immer-1.7.2.tgz#a51e9723c50b27e132f6566facbec1c85fc69547" integrity sha512-4Urocwu9+XLDJw4Tc6ZCg7APVjjLInCFvO4TwGsAYV5zT6YYSor14dsZR0+0tHlDIN92cFUOq+i7fC00G5vTxA== +import-fresh@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" + integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= + dependencies: + caller-path "^2.0.0" + resolve-from "^3.0.0" + import-local@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" @@ -2063,6 +2158,11 @@ is-accessor-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" @@ -2075,6 +2175,20 @@ is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + integrity sha1-VAVy0096wxGfj3bDDLwbHgN6/74= + dependencies: + builtin-modules "^1.0.0" + +is-ci@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" + integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== + dependencies: + ci-info "^1.5.0" + is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -2107,6 +2221,11 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-data-descriptor "^1.0.0" kind-of "^6.0.2" +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= + is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -2240,7 +2359,7 @@ js-tokens@^3.0.2: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= -js-yaml@^3.7.0: +js-yaml@^3.7.0, js-yaml@^3.9.0: version "3.12.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== @@ -2248,7 +2367,7 @@ js-yaml@^3.7.0: argparse "^1.0.7" esprima "^4.0.0" -json-parse-better-errors@^1.0.2: +json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== @@ -2719,6 +2838,16 @@ nopt@^4.0.1: abbrev "1" osenv "^0.1.4" +normalize-package-data@^2.3.2: + version "2.4.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" + integrity sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw== + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" @@ -2964,6 +3093,14 @@ parse-asn1@^5.0.0: evp_bytestokey "^1.0.0" pbkdf2 "^3.0.3" +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + parse-passwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" @@ -3080,6 +3217,13 @@ pkg-up@2.0.0: dependencies: find-up "^2.1.0" +please-upgrade-node@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz#ed320051dfcc5024fae696712c8288993595e8ac" + integrity sha512-KY1uHnQ2NlQHqIJQpnh/i54rKkuxCEBx+voJIS/Mvb+L2iYd2NMotwduhKTMjfC1uKoX3VXOxLjIYG66dfJTVQ== + dependencies: + semver-compare "^1.0.0" + portfinder@^1.0.9: version "1.0.19" resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.19.tgz#07e87914a55242dcda5b833d42f018d6875b595f" @@ -3094,6 +3238,11 @@ posix-character-classes@^0.1.0: resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= +prettier@^1.15.2: + version "1.15.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.15.2.tgz#d31abe22afa4351efa14c7f8b94b58bb7452205e" + integrity sha512-YgPLFFA0CdKL4Eg2IHtUSjzj/BWgszDHiNQAe0VAIBse34148whfdzLagRL+QiKS+YfK5ftB6X4v/MBw8yCoug== + process-nextick-args@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" @@ -3169,6 +3318,14 @@ pump@^2.0.0, pump@^2.0.1: end-of-stream "^1.1.0" once "^1.3.1" +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + pumpify@^1.3.3: version "1.5.1" resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" @@ -3308,6 +3465,15 @@ react@^16.7.0-alpha.2: prop-types "^15.6.2" scheduler "^0.12.0-alpha.2" +read-pkg@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-4.0.1.tgz#963625378f3e1c4d48c85872b5a6ec7d5d093237" + integrity sha1-ljYlN48+HE1IyFhytabsfV0JMjc= + dependencies: + normalize-package-data "^2.3.2" + parse-json "^4.0.0" + pify "^3.0.0" + "readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" @@ -3442,6 +3608,11 @@ run-async@^2.2.0: dependencies: is-promise "^2.1.0" +run-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/run-node/-/run-node-1.0.0.tgz#46b50b946a2aa2d4947ae1d886e9856fd9cabe5e" + integrity sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A== + run-queue@^1.0.0, run-queue@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" @@ -3515,7 +3686,12 @@ selfsigned@^1.9.1: dependencies: node-forge "0.7.5" -semver@^5.0.1, semver@^5.3.0, semver@^5.5.0: +semver-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= + +"semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.3.0, semver@^5.5.0: version "5.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== @@ -3642,6 +3818,11 @@ slash@^1.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -3735,6 +3916,32 @@ source-map@^0.6.1, source-map@~0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +spdx-correct@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.2.tgz#19bb409e91b47b1ad54159243f7312a858db3c2e" + integrity sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" + integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz#a59efc09784c2a5bada13cfeaf5c75dd214044d2" + integrity sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg== + spdy-transport@^2.0.18: version "2.1.1" resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-2.1.1.tgz#c54815d73858aadd06ce63001e7d25fa6441623b" @@ -4183,6 +4390,14 @@ v8-compile-cache@^2.0.2: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.2.tgz#a428b28bb26790734c4fc8bc9fa106fccebf6a6c" integrity sha512-1wFuMUIM16MDJRCrpbpuEPTUGmM5QMUg0cr3KFwra2XgOgFcPGDQHDh3CszSCD2Zewc/dh/pamNEW8CbfDebUw== +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" From 9d13ea27a847219cc491c3a5a87558cbb7bdc741 Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Fri, 16 Nov 2018 12:22:19 +0000 Subject: [PATCH 02/44] adding husky --- package.json | 14 +- yarn.lock | 355 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 358 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 7de5e59205..8e3f006246 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "cache-loader": "^1.2.5", "convert-tsconfig-paths-to-webpack-aliases": "^0.9.2", "fork-ts-checker-webpack-plugin": "^0.4.15", + "husky": "^1.1.4", "prettier": "^1.15.2", "progress-bar-webpack-plugin": "^1.11.0", "react": "^16.7.0-alpha.2", @@ -35,12 +36,23 @@ "webpack-dev-server": "^3.1.10" }, "dependencies": { - "husky": "^1.1.4", + "lint-staged": "^8.0.4", "react-dev-utils": "^6.1.1", "react-dom": "^16.7.0-alpha.2" }, "prettier": { "parser": "typescript", "singleQuote": true + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "*.{ts,tsx}": [ + "prettier --write", + "git add" + ] } } diff --git a/yarn.lock b/yarn.lock index 649cfdad43..76fc6fa571 100644 --- a/yarn.lock +++ b/yarn.lock @@ -31,6 +31,13 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== +"@samverschueren/stream-to-observable@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" + integrity sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg== + dependencies: + any-observable "^0.3.0" + "@types/node@*", "@types/node@^10.12.9": version "10.12.9" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.9.tgz#a07bfa74331471e1dc22a47eb72026843f7b95c8" @@ -265,6 +272,11 @@ ansi-colors@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.1.tgz#9638047e4213f3428a11944a7d4b31cba0a3ff95" integrity sha512-Xt+zb6nqgvV9SWAVp0EG3lRsHcbq5DDgqjPPz6pwgtj6RKz65zGXMNa82oJfOSBA/to6GmRP7Dr+6o+kbApTzQ== +ansi-escapes@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" + integrity sha1-06ioOzGapneTZisT52HHkRQiMG4= + ansi-escapes@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" @@ -290,13 +302,18 @@ ansi-styles@^2.2.1: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= -ansi-styles@^3.2.1: +ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" +any-observable@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.3.0.tgz#af933475e5806a67d0d7df090dd5e8bef65d119b" + integrity sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog== + anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -722,7 +739,7 @@ caniuse-lite@^1.0.30000884: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000907.tgz#0b9899bde53fb1c30e214fb12402361e02ff5c42" integrity sha512-No5sQ/OB2Nmka8MNOOM6nJx+Hxt6MQ6h7t7kgJFu9oTuwjykyKRSBP/+i/QAyFHxeHB+ddE0Da1CG5ihx9oehQ== -chalk@2.4.1, chalk@^2.0.0, chalk@^2.3.0, chalk@^2.4.1: +chalk@2.4.1, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.3.1, chalk@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== @@ -731,7 +748,7 @@ chalk@2.4.1, chalk@^2.0.0, chalk@^2.3.0, chalk@^2.4.1: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^1.1.1, chalk@^1.1.3: +chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= @@ -802,13 +819,28 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" -cli-cursor@^2.1.0: +cli-cursor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" + integrity sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc= + dependencies: + restore-cursor "^1.0.1" + +cli-cursor@^2.0.0, cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= dependencies: restore-cursor "^2.0.0" +cli-truncate@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" + integrity sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ= + dependencies: + slice-ansi "0.0.4" + string-width "^1.0.1" + cli-width@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" @@ -848,7 +880,7 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -commander@^2.12.1: +commander@^2.12.1, commander@^2.14.1, commander@^2.9.0: version "2.19.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== @@ -972,7 +1004,7 @@ core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= -cosmiconfig@^5.0.6: +cosmiconfig@^5.0.2, cosmiconfig@^5.0.6: version "5.0.7" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.7.tgz#39826b292ee0d78eda137dfa3173bd1c21a43b04" integrity sha512-PcLqxTKiDmNT6pSpy4N6KtuPwb53W+2tzNvwOZw0WH9N6O0vLIBq0x8aj8Oj75ere4YcGi48bDFCL+3fRJdlNA== @@ -1051,6 +1083,11 @@ cyclist@~0.2.2: resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA= +date-fns@^1.27.2: + version "1.29.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6" + integrity sha512-lbTXWZ6M20cWH8N9S6afb0SBm6tMk+uUg6z3MqHPKE9atmsY3kJkTm8vKe93izJ2B2+q5MV990sM2CHgtAZaOw== + date-now@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" @@ -1077,6 +1114,13 @@ debug@^3.1.0, debug@^3.2.5: dependencies: ms "^2.1.1" +debug@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.0.tgz#373687bffa678b38b1cd91f861b63850035ddc87" + integrity sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg== + dependencies: + ms "^2.1.1" + decamelize@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-2.0.0.tgz#656d7bbc8094c4c788ea53c5840908c9c7d063c7" @@ -1089,6 +1133,11 @@ decode-uri-component@^0.2.0: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= + deep-equal@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" @@ -1261,6 +1310,11 @@ electron-to-chromium@^1.3.62: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.84.tgz#2e55df59e818f150a9f61b53471ebf4f0feecc65" integrity sha512-IYhbzJYOopiTaNWMBp7RjbecUBsbnbDneOP86f3qvS0G0xfzwNSvMJpTrvi5/Y1gU7tg2NAgeg8a8rCYvW9Whw== +elegant-spinner@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" + integrity sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4= + elliptic@^6.0.0: version "6.4.1" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a" @@ -1319,7 +1373,7 @@ escape-html@~1.0.3: resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= -escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.4, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= @@ -1417,6 +1471,11 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +exit-hook@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" + integrity sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g= + expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" @@ -1547,6 +1606,14 @@ faye-websocket@~0.11.0, faye-websocket@~0.11.1: dependencies: websocket-driver ">=0.5.1" +figures@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4= + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + figures@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" @@ -1591,6 +1658,11 @@ find-cache-dir@^1.0.0: make-dir "^1.0.0" pkg-dir "^2.0.0" +find-parent-dir@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54" + integrity sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ= + find-up@3.0.0, find-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" @@ -1699,6 +1771,15 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +g-status@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/g-status/-/g-status-2.0.2.tgz#270fd32119e8fc9496f066fe5fe88e0a6bc78b97" + integrity sha512-kQoE9qH+T1AHKgSSD0Hkv98bobE90ILQcXAF4wvGgsr7uFqNvwmh8j+Lq3l0RVt3E3HjSbv2B9biEGcEtpHLCA== + dependencies: + arrify "^1.0.1" + matcher "^1.0.0" + simple-git "^1.85.0" + gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -1718,6 +1799,11 @@ get-caller-file@^1.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== +get-own-enumerable-property-symbols@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.0.tgz#b877b49a5c16aefac3655f2ed2ea5b684df8d203" + integrity sha512-CIJYJC4GGF06TakLg8z4GQKvDsx9EMspVxOYih7LerEL/WosUnFIww45CGfxfeKHqlg3twgUrYRT1O3WQqjGCg== + get-stdin@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" @@ -2059,6 +2145,11 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= +indent-string@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" + integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok= + indexof@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" @@ -2276,6 +2367,18 @@ is-number@^3.0.0: dependencies: kind-of "^3.0.2" +is-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + +is-observable@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-1.1.0.tgz#b3e986c8f44de950867cab5403f5a3465005975e" + integrity sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA== + dependencies: + symbol-observable "^1.1.0" + is-path-cwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" @@ -2307,6 +2410,11 @@ is-promise@^2.1.0: resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= + is-root@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.0.0.tgz#838d1e82318144e5a6f77819d90207645acc7019" @@ -2349,6 +2457,21 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= +jest-get-type@^22.1.0: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4" + integrity sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w== + +jest-validate@^23.5.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-23.6.0.tgz#36761f99d1ed33fcd425b4e4c5595d62b6597474" + integrity sha512-OFKapYxe72yz7agrDAWi8v2WL8GIfVqcbKRCLbRG9PAxtzF9b1SEDdTpytNDN12z2fJynoBwpMpvj2R39plI2A== + dependencies: + chalk "^2.0.1" + jest-get-type "^22.1.0" + leven "^2.1.0" + pretty-format "^23.6.0" + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -2428,6 +2551,99 @@ lcid@^2.0.0: dependencies: invert-kv "^2.0.0" +leven@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" + integrity sha1-wuep93IJTe6dNCAq6KzORoeHVYA= + +lint-staged@^8.0.4: + version "8.0.4" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-8.0.4.tgz#d3c909fcf7897152cdce2d6e42500cd9b5b41a0d" + integrity sha512-Rs0VxXoyFqHMrPQgKAMy+O907+m5Po71UVPhBi7BUBwU7ZZ2aoc+mZmpOX3DVPCoTcy6+hqJa9yIZfacNpJHdg== + dependencies: + chalk "^2.3.1" + commander "^2.14.1" + cosmiconfig "^5.0.2" + debug "^3.1.0" + dedent "^0.7.0" + del "^3.0.0" + execa "^1.0.0" + find-parent-dir "^0.3.0" + g-status "^2.0.2" + is-glob "^4.0.0" + is-windows "^1.0.2" + jest-validate "^23.5.0" + listr "^0.14.2" + listr-update-renderer "https://github.com/okonet/listr-update-renderer/tarball/upgrade-log-update" + lodash "^4.17.5" + log-symbols "^2.2.0" + micromatch "^3.1.8" + npm-which "^3.0.1" + p-map "^1.1.1" + path-is-inside "^1.0.2" + pify "^3.0.0" + please-upgrade-node "^3.0.2" + staged-git-files "1.1.2" + string-argv "^0.0.2" + stringify-object "^3.2.2" + +listr-silent-renderer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" + integrity sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4= + +listr-update-renderer@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.4.0.tgz#344d980da2ca2e8b145ba305908f32ae3f4cc8a7" + integrity sha1-NE2YDaLKLosUW6MFkI8yrj9MyKc= + dependencies: + chalk "^1.1.3" + cli-truncate "^0.2.1" + elegant-spinner "^1.0.1" + figures "^1.7.0" + indent-string "^3.0.0" + log-symbols "^1.0.2" + log-update "^1.0.2" + strip-ansi "^3.0.1" + +"listr-update-renderer@https://github.com/okonet/listr-update-renderer/tarball/upgrade-log-update": + version "0.4.0" + resolved "https://github.com/okonet/listr-update-renderer/tarball/upgrade-log-update#06073fa93166277607a7814f4e1f83960081414c" + dependencies: + chalk "^1.1.3" + cli-truncate "^0.2.1" + elegant-spinner "^1.0.1" + figures "^1.7.0" + indent-string "^3.0.0" + log-symbols "^1.0.2" + log-update "^2.3.0" + strip-ansi "^3.0.1" + +listr-verbose-renderer@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#8206f4cf6d52ddc5827e5fd14989e0e965933a35" + integrity sha1-ggb0z21S3cWCfl/RSYng6WWTOjU= + dependencies: + chalk "^1.1.3" + cli-cursor "^1.0.2" + date-fns "^1.27.2" + figures "^1.7.0" + +listr@^0.14.2: + version "0.14.2" + resolved "https://registry.yarnpkg.com/listr/-/listr-0.14.2.tgz#cbe44b021100a15376addfc2d79349ee430bfe14" + integrity sha512-vmaNJ1KlGuGWShHI35X/F8r9xxS0VTHh9GejVXwSN20fG5xpq3Jh4bJbnumoT6q5EDM/8/YP1z3YMtQbFmhuXw== + dependencies: + "@samverschueren/stream-to-observable" "^0.3.0" + is-observable "^1.1.0" + is-promise "^2.1.0" + is-stream "^1.1.0" + listr-silent-renderer "^1.1.1" + listr-update-renderer "^0.4.0" + listr-verbose-renderer "^0.4.0" + p-map "^1.1.1" + rxjs "^6.1.0" + loader-runner@^2.3.0: version "2.3.1" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.1.tgz#026f12fe7c3115992896ac02ba022ba92971b979" @@ -2468,6 +2684,37 @@ lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.5: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== +log-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" + integrity sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg= + dependencies: + chalk "^1.0.0" + +log-symbols@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== + dependencies: + chalk "^2.0.1" + +log-update@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-1.0.2.tgz#19929f64c4093d2d2e7075a1dad8af59c296b8d1" + integrity sha1-GZKfZMQJPS0ucHWh2tivWcKWuNE= + dependencies: + ansi-escapes "^1.0.0" + cli-cursor "^1.0.2" + +log-update@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708" + integrity sha1-iDKP19HOeTiykoN0bwsbwSayRwg= + dependencies: + ansi-escapes "^3.0.0" + cli-cursor "^2.0.0" + wrap-ansi "^3.0.1" + loglevel@^1.4.1: version "1.6.1" resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa" @@ -2514,6 +2761,13 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +matcher@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/matcher/-/matcher-1.1.1.tgz#51d8301e138f840982b338b116bb0c09af62c1c2" + integrity sha512-+BmqxWIubKTRKNWx/ahnCkk3mG8m7OturVlqq6HiojGJTd5hVYbgZm6WzcYPCoB+KBT4Vd6R7WSRG2OADNaCjg== + dependencies: + escape-string-regexp "^1.0.4" + md5.js@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" @@ -2868,6 +3122,13 @@ npm-packlist@^1.1.6: ignore-walk "^3.0.1" npm-bundled "^1.0.1" +npm-path@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/npm-path/-/npm-path-2.0.4.tgz#c641347a5ff9d6a09e4d9bce5580c4f505278e64" + integrity sha512-IFsj0R9C7ZdR5cP+ET342q77uSRdtWOlWpih5eC+lu29tIDbNEgDbzgVJ5UFvYHWhxDZ5TFkJafFioO0pPQjCw== + dependencies: + which "^1.2.10" + npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -2875,6 +3136,15 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" +npm-which@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/npm-which/-/npm-which-3.0.1.tgz#9225f26ec3a285c209cae67c3b11a6b4ab7140aa" + integrity sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo= + dependencies: + commander "^2.9.0" + npm-path "^2.0.2" + which "^1.2.10" + npmlog@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" @@ -2957,6 +3227,11 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" +onetime@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + integrity sha1-ofeDj4MUxRbwXs78vEzP4EtO14k= + onetime@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" @@ -3136,7 +3411,7 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-is-inside@^1.0.1: +path-is-inside@^1.0.1, path-is-inside@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= @@ -3217,7 +3492,7 @@ pkg-up@2.0.0: dependencies: find-up "^2.1.0" -please-upgrade-node@^3.1.1: +please-upgrade-node@^3.0.2, please-upgrade-node@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz#ed320051dfcc5024fae696712c8288993595e8ac" integrity sha512-KY1uHnQ2NlQHqIJQpnh/i54rKkuxCEBx+voJIS/Mvb+L2iYd2NMotwduhKTMjfC1uKoX3VXOxLjIYG66dfJTVQ== @@ -3243,6 +3518,14 @@ prettier@^1.15.2: resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.15.2.tgz#d31abe22afa4351efa14c7f8b94b58bb7452205e" integrity sha512-YgPLFFA0CdKL4Eg2IHtUSjzj/BWgszDHiNQAe0VAIBse34148whfdzLagRL+QiKS+YfK5ftB6X4v/MBw8yCoug== +pretty-format@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-23.6.0.tgz#5eaac8eeb6b33b987b7fe6097ea6a8a146ab5760" + integrity sha512-zf9NV1NSlDLDjycnwm6hpFATCGl/K1lt0R/GdkAK2O5LN/rwJoB+Mh93gGJjut4YbmecbfgLWVGSTCr0Ewvvbw== + dependencies: + ansi-regex "^3.0.0" + ansi-styles "^3.2.0" + process-nextick-args@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" @@ -3573,6 +3856,14 @@ resolve@^1.3.2, resolve@^1.5.0: dependencies: path-parse "^1.0.5" +restore-cursor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" + integrity sha1-NGYfRohjJ/7SmRR5FSJS35LapUE= + dependencies: + exit-hook "^1.0.0" + onetime "^1.0.0" + restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" @@ -3813,6 +4104,13 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= +simple-git@^1.85.0: + version "1.107.0" + resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-1.107.0.tgz#12cffaf261c14d6f450f7fdb86c21ccee968b383" + integrity sha512-t4OK1JRlp4ayKRfcW6owrWcRVLyHRUlhGd0uN6ZZTqfDq8a5XpcUdOKiGRNobHEuMtNqzp0vcJNvhYWwh5PsQA== + dependencies: + debug "^4.0.1" + slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" @@ -3823,6 +4121,11 @@ slash@^2.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU= + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -3986,6 +4289,11 @@ ssri@^5.2.4: dependencies: safe-buffer "^5.1.1" +staged-git-files@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-1.1.2.tgz#4326d33886dc9ecfa29a6193bf511ba90a46454b" + integrity sha512-0Eyrk6uXW6tg9PYkhi/V/J4zHp33aNyi2hOCmhFLqLTIhbgqWn5jlSzI+IU0VqrZq6+DbHcabQl/WP6P3BG0QA== + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -4036,6 +4344,11 @@ stream-shift@^1.0.0: resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= +string-argv@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.0.2.tgz#dac30408690c21f3c3630a3ff3a05877bdcbd736" + integrity sha1-2sMECGkMIfPDYwo/86BYd73L1zY= + string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -4060,6 +4373,15 @@ string_decoder@^1.0.0, string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" +stringify-object@^3.2.2: + version "3.3.0" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" + integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== + dependencies: + get-own-enumerable-property-symbols "^3.0.0" + is-obj "^1.0.1" + is-regexp "^1.0.0" + strip-ansi@4.0.0, strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" @@ -4096,6 +4418,11 @@ supports-color@^5.1.0, supports-color@^5.3.0, supports-color@^5.5.0: dependencies: has-flag "^3.0.0" +symbol-observable@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== + tapable@^1.0.0, tapable@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.0.tgz#0d076a172e3d9ba088fd2272b2668fb8d194b78c" @@ -4550,7 +4877,7 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@^1.2.14, which@^1.2.9: +which@^1.2.10, which@^1.2.14, which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -4579,6 +4906,14 @@ wrap-ansi@^2.0.0: string-width "^1.0.1" strip-ansi "^3.0.1" +wrap-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-3.0.1.tgz#288a04d87eda5c286e060dfe8f135ce8d007f8ba" + integrity sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo= + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" From b07e12d9e99bbc3339bb298f45c564779d640011 Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Mon, 19 Nov 2018 15:34:24 +0000 Subject: [PATCH 03/44] adding initial files --- TODO.md | 1 + dev/examples/test.tsx | 6 +- dev/webpack/config.js | 46 +++---- package.json | 9 +- src/hooks/use-config.ts | 18 +++ src/hooks/use-external-ref.ts | 18 +++ src/hooks/use-pose-resolver.ts | 94 ++++++++++++++ src/hooks/use-posed-values.ts | 61 +++++++++ src/hooks/use-style-attr.ts | 16 +++ src/index.ts | 7 +- src/loader.ts | 13 -- src/motion-value/index.ts | 156 +++++++++++++++++++++++ src/motion/component.ts | 33 +++++ src/motion/index.ts | 10 ++ src/motion/supported-elements.ts | 92 ++++++++++++++ src/motion/types.ts | 17 +++ src/test.tsx | 5 - src/utils/pose-resolvers.ts | 15 +++ tsconfig.json | 4 +- webpack.config.js | 205 ++++++++++++++++--------------- yarn.lock | 150 +++++++++++----------- 21 files changed, 745 insertions(+), 231 deletions(-) create mode 100644 TODO.md create mode 100644 src/hooks/use-config.ts create mode 100644 src/hooks/use-external-ref.ts create mode 100644 src/hooks/use-pose-resolver.ts create mode 100644 src/hooks/use-posed-values.ts create mode 100644 src/hooks/use-style-attr.ts delete mode 100644 src/loader.ts create mode 100644 src/motion-value/index.ts create mode 100644 src/motion/component.ts create mode 100644 src/motion/index.ts create mode 100644 src/motion/supported-elements.ts create mode 100644 src/motion/types.ts delete mode 100644 src/test.tsx create mode 100644 src/utils/pose-resolvers.ts diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000000..de9038affa --- /dev/null +++ b/TODO.md @@ -0,0 +1 @@ +- Add Rollup for production bundle generation (will save multiple kb) \ No newline at end of file diff --git a/dev/examples/test.tsx b/dev/examples/test.tsx index fc39a47132..9361370e5e 100644 --- a/dev/examples/test.tsx +++ b/dev/examples/test.tsx @@ -1,9 +1,7 @@ -import * as React from "react"; - -import { Test } from "@framer"; +import * as React from 'react'; export class App extends React.Component { render() { - return ; + return null; } } diff --git a/dev/webpack/config.js b/dev/webpack/config.js index 8446aaf79a..005acc7519 100644 --- a/dev/webpack/config.js +++ b/dev/webpack/config.js @@ -1,28 +1,30 @@ -const path = require("path") -const config = require("../../webpack.config") -const webpack = require("webpack") -const chalk = require("chalk") +const path = require('path'); +const config = require('../../webpack.config'); +const webpack = require('webpack'); +const chalk = require('chalk'); -const DEV_SERVER_PORT = 9990 +const DEV_SERVER_PORT = 9990; -console.log(chalk.bold.green(`\nRunning at: http://0.0.0.0:${DEV_SERVER_PORT}/\n`)) +console.log( + chalk.bold.green(`\nRunning at: http://0.0.0.0:${DEV_SERVER_PORT}/\n`) +); config.entry = { - framer: [ - "react-dev-utils/webpackHotDevClient", - path.join(__dirname, "..", "..", "src", "loader"), - path.join(__dirname, "index"), - ], -} + framer: [ + 'react-dev-utils/webpackHotDevClient', + path.join(__dirname, '..', '..', 'src', 'index'), + path.join(__dirname, 'index') + ] +}; config.devServer = { - contentBase: path.join(__dirname), - hot: false, - inline: false, - // quiet: true, - // open: true, - // openPage: "/", - stats: "errors-only", - port: DEV_SERVER_PORT, -} -Object.assign(exports, config) + contentBase: path.join(__dirname), + hot: false, + inline: false, + // quiet: true, + // open: true, + // openPage: "/", + stats: 'errors-only', + port: DEV_SERVER_PORT +}; +Object.assign(exports, config); diff --git a/package.json b/package.json index 8e3f006246..9e1cebf4f0 100644 --- a/package.json +++ b/package.json @@ -24,9 +24,10 @@ "convert-tsconfig-paths-to-webpack-aliases": "^0.9.2", "fork-ts-checker-webpack-plugin": "^0.4.15", "husky": "^1.1.4", + "lint-staged": "^8.0.4", "prettier": "^1.15.2", "progress-bar-webpack-plugin": "^1.11.0", - "react": "^16.7.0-alpha.2", + "react-dev-utils": "^6.1.1", "ts-loader": "^5.3.0", "tslint": "^5.11.0", "tslint-microsoft-contrib": "^5.2.1", @@ -36,9 +37,9 @@ "webpack-dev-server": "^3.1.10" }, "dependencies": { - "lint-staged": "^8.0.4", - "react-dev-utils": "^6.1.1", - "react-dom": "^16.7.0-alpha.2" + "hey-listen": "^1.0.5", + "popmotion": "^8.5.2", + "stylefire": "^2.3.1" }, "prettier": { "parser": "typescript", diff --git a/src/hooks/use-config.ts b/src/hooks/use-config.ts new file mode 100644 index 0000000000..96bcdc2a04 --- /dev/null +++ b/src/hooks/use-config.ts @@ -0,0 +1,18 @@ +import { useMemo } from 'react'; +import { + MotionConfig, + MotionConfigResolver, + MotionProps +} from '../motion/types'; + +const isResolver = ( + config: MotionConfig | MotionConfigResolver +): config is MotionConfigResolver => typeof config === 'function'; + +const useConfig = ( + baseConfig: MotionConfig | MotionConfigResolver, + props: MotionProps +) => + useMemo(() => (isResolver(baseConfig) ? baseConfig(props) : baseConfig), []); + +export default useConfig; diff --git a/src/hooks/use-external-ref.ts b/src/hooks/use-external-ref.ts new file mode 100644 index 0000000000..f7a68dc009 --- /dev/null +++ b/src/hooks/use-external-ref.ts @@ -0,0 +1,18 @@ +import { useEffect, useRef, Ref, MutableRefObject } from 'react'; + +const useExternalRef = (external?: Ref) => { + const ref = + !external || typeof external === 'function' ? useRef(null) : external; + + useEffect(() => { + if (external && typeof external === 'function') { + external((ref as MutableRefObject).current); + + return () => external(null); + } + }); + + return ref; +}; + +export default useExternalRef; diff --git a/src/hooks/use-pose-resolver.ts b/src/hooks/use-pose-resolver.ts new file mode 100644 index 0000000000..436d5226e1 --- /dev/null +++ b/src/hooks/use-pose-resolver.ts @@ -0,0 +1,94 @@ +import { useRef, useEffect } from 'react'; +import { invariant } from 'hey-listen'; +import { tween, spring, keyframes, decay, physics } from 'popmotion'; +import { poseToArray } from '../utils/pose-resolvers'; +import motionValue, { MotionValue } from '../motion-value'; +import { MotionConfig, MotionProps } from 'motion/types'; + +const transitions = { tween, spring, keyframes, decay, physics }; + +const defaultTransition = { + type: 'spring', + stiffness: 800, + damping: 15 +}; + +const getTransition = (key, transition, to) => { + const transitionDefinition = transition + ? transition[key] || transition.default || transition + : defaultTransition; + + const action = transitions[transitionDefinition.type || 'tween']; + const opts = { ...transitionDefinition, to }; + + return [action, opts]; +}; + +const createPoseResolver = (config, values, props) => pose => { + console.log(pose); +}; + +const usePoseResolver = ( + values: Map, + config: MotionConfig, + props: MotionProps +) => { + const poseResolver = useRef(null); + const { pose } = props; + const prevPoseResolver = poseResolver.current; + poseResolver.current = createPoseResolver(config, values, props); + + useEffect(() => { + if (pose instanceof MotionValue) { + pose.removeSubscriber(prevPoseResolver); + pose.addSubscriber(poseResolver.current); + } else if (prevPoseResolver) { + poseResolver.current(pose); + } + }); + + // const poseObservable = + // props.pose instanceof MotionValue + // ? props.pose.addOnUpdate() + // : motionValue(props.pose); + + // const poseProp = poseToArray(props.pose); + + // useEffect(() => poseObservable.set(poseProp), poseProp); + + // useEffect(() => { + // const hadPose = pose.current !== null; + // pose.current = poseToArray(props.pose); + + // if (!hadPose || !props.pose) return; + + // pose.current.forEach(poseKey => { + // // Resolve Pose with props if function here + + // invariant( + // config[poseKey] !== undefined, + // `Pose with name ${poseKey} not found.` // Show available poses? + // ); + + // const { transition, ...thisPose } = config[poseKey]; + + // // TODO: Check to see if `transition` exists and generate default + // // based on keys being animated if not + + // // Filter pose options like stagger children here + // Object.keys(thisPose).forEach(valueKey => { + // const value = values.get(valueKey); + // const target = thisPose[valueKey]; + + // invariant( + // value !== undefined, + // "Value not found. Ensure all animated values are created on component mount." // Maybe create this value on the fly instead? + // ); + + // value.control(...getTransition(valueKey, transition, target)); + // }); + // }); + // }, pose.current); +}; + +export default usePoseResolver; diff --git a/src/hooks/use-posed-values.ts b/src/hooks/use-posed-values.ts new file mode 100644 index 0000000000..49cc019a6e --- /dev/null +++ b/src/hooks/use-posed-values.ts @@ -0,0 +1,61 @@ +import motionValue, { MotionValue } from '../motion-value'; +import { resolvePoses } from '../utils/pose-resolvers'; +import { MotionConfig, MotionProps } from '../motion/types'; +import { useRef, useEffect, RefObject } from 'react'; +import styler from 'stylefire'; + +export default

( + config: MotionConfig, + props: P & MotionProps, + ref: RefObject +): [Map, P & MotionProps] => { + const values = useRef(new Map()).current; + const returnedProps = {}; + + // In this function we want to find the right approach to ensure + // we successfully remove MotionValues from the returned props + // in a performant way over subsequent renders. + + // 1. Bind stylers to provided motion values via props + Object.keys(props).forEach(key => { + const prop = props[key]; + + if (prop instanceof MotionValue) { + values.set(key, prop); + } else { + returnedProps[key] = prop; + } + }); + + // 2. Create values from poses + const { pose = 'default' } = props; + const initialPoses = resolvePoses(pose); + + initialPoses.forEach(poseKey => { + const poseDef = config[poseKey]; + if (!poseDef) return; + + const initialPose = + typeof poseDef === 'function' ? poseDef(props) : poseDef; + + // We'll need to filter out options like staggerChildren etc + Object.keys(initialPose).forEach(valueKey => { + if (!values.has(valueKey)) { + values.set(valueKey, motionValue(initialPose[valueKey])); + } + }); + }); + + // 3. Bind stylers when ref is ready + useEffect(() => { + const domStyler = styler(ref.current); + + values.forEach((value, key) => { + value.setOnRender(v => domStyler.set(key, v)); + }); + + return () => values.forEach(value => value.destroy()); + }, []); + + return [values, returnedProps]; +}; diff --git a/src/hooks/use-style-attr.ts b/src/hooks/use-style-attr.ts new file mode 100644 index 0000000000..a640923791 --- /dev/null +++ b/src/hooks/use-style-attr.ts @@ -0,0 +1,16 @@ +import { useMemo, CSSProperties } from 'react'; +import { buildStyleProperty } from 'stylefire'; +import { MotionValue } from '../motion-value'; + +export default (styles: CSSProperties, values: Map) => + useMemo(() => { + const resolvedValues = Object.keys(values).reduce((acc, key) => { + acc[key] = values[key].get(); + return acc; + }, {}); + + return { + ...styles, + ...buildStyleProperty(resolvedValues) + }; + }, []); diff --git a/src/index.ts b/src/index.ts index 38aa2796da..5a43d09b28 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1,6 @@ -export { Test } from './test'; +import motion from './motion'; +import useMotionValue from './hooks/use-motion-value'; +import useTransform from './hooks/use-transform'; +import usePose from './hooks/use-pose'; + +export { motion, useMotionValue, useTransform, usePose }; diff --git a/src/loader.ts b/src/loader.ts deleted file mode 100644 index 6bd554f170..0000000000 --- a/src/loader.ts +++ /dev/null @@ -1,13 +0,0 @@ -// This is the main entry in webpack and runs checks if we are stup correctly - -import * as React from "react" - -if (!React) { - throw Error("Framer needs React as an external dependency.") -} - -import * as ReactDOM from "react-dom" - -if (!ReactDOM) { - throw Error("Framer needs ReactDOM as an external dependency.") -} diff --git a/src/motion-value/index.ts b/src/motion-value/index.ts new file mode 100644 index 0000000000..d9a731ad85 --- /dev/null +++ b/src/motion-value/index.ts @@ -0,0 +1,156 @@ +import sync from 'framesync'; +import { Action, ColdSubscription } from 'popmotion'; + +export type ValuePrimitive = number | string; + +export type Transformer = (v: ValuePrimitive) => ValuePrimitive; + +export type Subscriber = (v: ValuePrimitive) => void; + +export type Config = { + transformer?: Transformer; + onRender?: Subscriber; + parent?: MotionValue; +}; + +export type ActionConfig = { [key: string]: any }; + +export type ActionFactory = (actionConfig: ActionConfig) => Action; + +export class MotionValue { + // Current state + current: ValuePrimitive; + + // Previous state + prev: ValuePrimitive; + + // Children get updated onUpdate + children: Set; + + // A reference to the value's parent - currently used for unregistering as a child, + // but maybe it'd be better for this to be just a disconnect function + parent?: MotionValue; + + // onRender is fired on render step after update + onRender: Subscriber | null; + + // Fired + subscribers: Set; + + // If set, will pass `set` values through this function first + transformer?: Transformer; + + // A reference to the currently-controlling animation + controller: ColdSubscription; + + constructor(init: ValuePrimitive, { onRender, transformer, parent }: Config) { + this.parent = parent; + this.transformer = transformer; + if (onRender) this.setOnRender(onRender); + this.set(init); + } + + addChild(config: Config) { + const child = new MotionValue(this.current, { + parent: this, + ...config + }); + + if (!this.children) this.children = new Set(); + + this.children.add(child); + + return child; + } + + removeChild(child: MotionValue) { + this.children.delete(child); + } + + setOnRender(onRender: Subscriber | null) { + this.onRender = onRender; + if (this.onRender) sync.render(this.render); + } + + addSubscriber(sub: Subscriber) { + if (!this.subscribers) this.subscribers = new Set(); + this.subscribers.add(sub); + } + + removeSubscriber(sub: Subscriber) { + if (this.subscribers) { + this.subscribers.delete(sub); + } + } + + set(v: ValuePrimitive) { + this.prev = this.current; + this.current = this.transformer ? this.transformer(v) : v; + + if (this.subscribers) { + sync.update(this.notifySubscribers, false, true); + } + + if (this.children) { + this.children.forEach(this.setChild); + } + + if (this.onRender) { + sync.render(this.render); + } + } + + notifySubscribers = () => this.subscribers.forEach(this.setSubscriber); + setSubscriber = (sub: Subscriber) => sub(this.current); + setChild = (child: MotionValue) => child.set(this.current); + + get() { + return this.current; + } + + getVelocity() { + return 0; + } + + render = () => { + if (this.onRender) this.onRender(this.current); + }; + + control( + controller: ActionFactory, + config: ActionConfig, + transformer: Transformer + ) { + this.stop(); + + let initialisedController = controller({ + from: this.get(), + velocity: this.getVelocity(), + ...config + }); + + if (transformer) { + initialisedController = initialisedController.pipe(transformer); + } + + return new Promise(complete => { + this.controller = initialisedController.start({ + update: (v: ValuePrimitive) => this.set(v), + complete + }); + }); + } + + stop() { + this.controller && this.controller.stop(); + } + + destroy() { + this.setOnRender(null); + this.parent && this.parent.removeChild(this); + this.stop(); + } +} + +export default (init: ValuePrimitive, opts?: Config) => + new MotionValue(init, opts); diff --git a/src/motion/component.ts b/src/motion/component.ts new file mode 100644 index 0000000000..335189f5ce --- /dev/null +++ b/src/motion/component.ts @@ -0,0 +1,33 @@ +import { memo, forwardRef, createElement, Ref, ComponentType } from 'react'; +import { MotionProps, MotionConfig, MotionConfigResolver } from './types'; +import useConfig from '../hooks/use-config'; +import useExternalRef from '../hooks/use-external-ref'; +import usePosedValues from '../hooks/use-posed-values'; +import usePoseResolver from '../hooks/use-pose-resolver'; +import useStyleAttr from '../hooks/use-style-attr'; + +const createMotionComponent =

( + Component: ComponentType

| string +) => (motionConfig: MotionConfig | MotionConfigResolver) => { + const MotionComponent = forwardRef( + (props: P & MotionProps, externalRef?: Ref) => { + const ref = useExternalRef(externalRef); + const config = useConfig(motionConfig, props); + + // Create motion values + const [values, componentProps] = usePosedValues

(config, props, ref); + + usePoseResolver(values, config, props); + + return createElement(Component, { + ref, + ...componentProps, + style: useStyleAttr(props.styles, values) + }); + } + ); + + return memo(MotionComponent); +}; + +export default createMotionComponent; diff --git a/src/motion/index.ts b/src/motion/index.ts new file mode 100644 index 0000000000..0ff5d51233 --- /dev/null +++ b/src/motion/index.ts @@ -0,0 +1,10 @@ +import createMotionComponent from './component'; +import supportedElements from './supported-elements'; + +const motion = createMotionComponent; + +supportedElements.forEach( + element => (motion[element] = createMotionComponent(element)) +); + +export default motion; diff --git a/src/motion/supported-elements.ts b/src/motion/supported-elements.ts new file mode 100644 index 0000000000..984834c011 --- /dev/null +++ b/src/motion/supported-elements.ts @@ -0,0 +1,92 @@ +export default [ + 'a', + 'article', + 'aside', + 'audio', + 'b', + 'blockquote', + 'body', + 'br', + 'button', + 'canvas', + 'caption', + 'cite', + 'code', + 'col', + 'colgroup', + 'data', + 'datalist', + 'dialog', + 'div', + 'em', + 'embed', + 'fieldset', + 'figcaption', + 'figure', + 'footer', + 'form', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'head', + 'header', + 'hgroup', + 'hr', + 'i', + 'iframe', + 'img', + 'input', + 'label', + 'legend', + 'li', + 'nav', + 'object', + 'ol', + 'option', + 'p', + 'param', + 'picture', + 'pre', + 'progress', + 'q', + 'section', + 'select', + 'span', + 'strong', + 'table', + 'tbody', + 'td', + 'textarea', + 'tfoot', + 'th', + 'thead', + 'time', + 'title', + 'tr', + 'ul', + 'video', + + // SVG + 'circle', + 'clipPath', + 'defs', + 'ellipse', + 'g', + 'image', + 'line', + 'linearGradient', + 'mask', + 'path', + 'pattern', + 'polygon', + 'polyline', + 'radialGradient', + 'rect', + 'stop', + 'svg', + 'text', + 'tspan' +]; diff --git a/src/motion/types.ts b/src/motion/types.ts new file mode 100644 index 0000000000..9b5b3a7393 --- /dev/null +++ b/src/motion/types.ts @@ -0,0 +1,17 @@ +import { MotionValue } from '../motion-value'; + +export type MotionProps = { + pose: string | string[] | MotionValue; +}; + +export type Pose = { + [key: string]: number | string; +}; + +export type PoseResolver = (props: { [key: string]: any }) => Pose; + +export type MotionConfig = { + [key: string]: Pose | PoseResolver; +}; + +export type MotionConfigResolver = (props: MotionProps) => MotionConfig; diff --git a/src/test.tsx b/src/test.tsx deleted file mode 100644 index ec40b0ceb8..0000000000 --- a/src/test.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import * as React from "react" - -export const Test = () => { - return

Hello world
-} diff --git a/src/utils/pose-resolvers.ts b/src/utils/pose-resolvers.ts new file mode 100644 index 0000000000..4a9dfc90c5 --- /dev/null +++ b/src/utils/pose-resolvers.ts @@ -0,0 +1,15 @@ +import { MotionValue } from '../motion-value'; + +type PoseNameList = string[]; +type PoseName = string | PoseNameList; +type UnresolvedPose = PoseName | MotionValue; + +export const poseToArray = (pose: PoseName): PoseNameList => + Array.isArray(pose) ? [...pose].reverse() : [pose]; + +export const resolvePoses = (pose: UnresolvedPose): PoseNameList => { + const unresolvedPose = + pose instanceof MotionValue ? (pose.get() as string) : pose; + + return poseToArray(unresolvedPose); +}; diff --git a/tsconfig.json b/tsconfig.json index 7ec77f2df3..c7f7d71627 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { "target": "es2015", - "module": "commonjs", + "module": "esnext", "moduleResolution": "node", "isolatedModules": false, "jsx": "react", @@ -19,7 +19,7 @@ "@framer": ["../src/index"], "@framer/*": ["../src/*"] }, - "strictNullChecks": true, + "strictNullChecks": false, "noImplicitAny": true, "noImplicitThis": true, "noImplicitUseStrict": false, diff --git a/webpack.config.js b/webpack.config.js index dff7695bc2..20022f9e10 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,115 +1,116 @@ -path = require("path") -execSync = require("child_process").execSync -webpack = require("webpack") -UglifyJSPlugin = require("uglifyjs-webpack-plugin") -ProgressBarPlugin = require("progress-bar-webpack-plugin") -ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin") -convertPathsToAliases = require("convert-tsconfig-paths-to-webpack-aliases").default -tsconfig = require("./tsconfig.json") +path = require('path'); +execSync = require('child_process').execSync; +webpack = require('webpack'); +UglifyJSPlugin = require('uglifyjs-webpack-plugin'); +ProgressBarPlugin = require('progress-bar-webpack-plugin'); +ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); +convertPathsToAliases = require('convert-tsconfig-paths-to-webpack-aliases') + .default; +tsconfig = require('./tsconfig.json'); -const BUILD_TYPE = process.env.BUILD_TYPE || "debug" -const GIT_DESCRIBE = execSync("git describe --always --dirty") - .toString() - .trim() -const isProduction = BUILD_TYPE === "production" +const BUILD_TYPE = process.env.BUILD_TYPE || 'debug'; +const GIT_DESCRIBE = execSync('git describe --always --dirty') + .toString() + .trim(); +const isProduction = BUILD_TYPE === 'production'; const tsLoader = { - loader: "ts-loader", - options: { transpileOnly: true }, -} + loader: 'ts-loader', + options: { transpileOnly: true } +}; const config = { - mode: isProduction ? "production" : "development", - target: "web", - entry: { - framer: [path.join(__dirname, "./src/loader"), path.join(__dirname, "./src/index")], - }, - output: { - path: path.join(__dirname, "build"), - filename: isProduction ? "[name].js" : "[name].debug.js", - library: "Framer", - libraryTarget: "umd", - }, - devtool: isProduction ? "source-map" : "#cheap-module-source-map", - module: { - rules: [ - { - test: /\.ts(x?)$/, - exclude: [/__tests__/, /node_modules/], - use: isProduction ? [tsLoader] : ["cache-loader", tsLoader], - }, - ], - }, - externals: { - react: { - root: "React", - commonjs2: "react", - commonjs: "react", - amd: "react", - }, - "react-dom": { - root: "ReactDOM", - commonjs2: "ReactDOM", - commonjs: "ReactDOM", - amd: "ReactDOM", - }, - }, - resolve: { - modules: ["node_modules"], - extensions: [".ts", ".tsx", ".js", ".json"], - alias: convertPathsToAliases(tsconfig), + mode: isProduction ? 'production' : 'development', + target: 'web', + entry: { + framer: [path.join(__dirname, './src/index')] + }, + output: { + path: path.join(__dirname, 'build'), + filename: isProduction ? '[name].js' : '[name].debug.js', + library: 'Framer', + libraryTarget: 'umd' + }, + devtool: isProduction ? 'source-map' : '#cheap-module-source-map', + module: { + rules: [ + { + test: /\.ts(x?)$/, + exclude: [/__tests__/, /node_modules/], + use: isProduction ? [tsLoader] : ['cache-loader', tsLoader] + } + ] + }, + externals: { + react: { + root: 'React', + commonjs2: 'react', + commonjs: 'react', + amd: 'react' }, - performance: { - hints: false, - }, - plugins: [ - new webpack.DefinePlugin({ - "process.env.BUILD_NAME": JSON.stringify("framer"), - "process.env.BUILD_HASH": JSON.stringify(GIT_DESCRIBE), - "process.env.BUILD_TYPE": JSON.stringify(BUILD_TYPE), - "process.env.BUILD_DATE": JSON.stringify(new Date().toISOString()), - "process.env.NODE_ENV": JSON.stringify(BUILD_TYPE), - }), - ], -} + 'react-dom': { + root: 'ReactDOM', + commonjs2: 'ReactDOM', + commonjs: 'ReactDOM', + amd: 'ReactDOM' + } + }, + resolve: { + modules: ['node_modules'], + extensions: ['.ts', '.tsx', '.js', '.json'], + alias: convertPathsToAliases(tsconfig) + }, + performance: { + hints: false + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env.BUILD_NAME': JSON.stringify('framer'), + 'process.env.BUILD_HASH': JSON.stringify(GIT_DESCRIBE), + 'process.env.BUILD_TYPE': JSON.stringify(BUILD_TYPE), + 'process.env.BUILD_DATE': JSON.stringify(new Date().toISOString()), + 'process.env.NODE_ENV': JSON.stringify(BUILD_TYPE) + }) + ] +}; if (!isProduction) { - config.plugins.push(new ForkTsCheckerWebpackPlugin()) + config.plugins.push(new ForkTsCheckerWebpackPlugin()); } if (isProduction) { - config.devtool = "source-map" - config.optimization = { - minimizer: [ - new UglifyJSPlugin({ - parallel: true, - sourceMap: true, - uglifyOptions: { - ecma: 6, - mangle: { - safari10: true, - keep_classnames: true, - }, - compress: { - warnings: false, - conditionals: true, - unused: true, - comparisons: true, - dead_code: true, - evaluate: true, - if_return: true, - join_vars: true, - keep_classnames: true, - }, - output: { - safari10: true, - beautify: false, - comments: false, - }, - }, - }), - ], - } + config.devtool = 'source-map'; + config.optimization = { + minimizer: [ + new UglifyJSPlugin({ + parallel: true, + sourceMap: true, + uglifyOptions: { + ecma: 6, + mangle: { + safari10: true, + keep_classnames: true + }, + compress: { + warnings: false, + conditionals: true, + unused: true, + comparisons: true, + dead_code: true, + evaluate: true, + if_return: true, + join_vars: true, + keep_classnames: true + }, + output: { + safari10: true, + beautify: false, + comments: false + } + } + }) + ] + }; } -module.exports = config +module.exports = config; diff --git a/yarn.lock b/yarn.lock index 76fc6fa571..78a09c94df 100644 --- a/yarn.lock +++ b/yarn.lock @@ -31,6 +31,21 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== +"@popmotion/easing@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@popmotion/easing/-/easing-1.0.1.tgz#48336aea29542113df10aeb81b4fd10f0b95f937" + integrity sha512-NbIEz9mZAem0F0sjg2v57LbU9Y2Xc50QEX434jYrwEQzXJuJipyUV48Qz4hjHqbB/8xiUj0JMQfRvP8K9nUbxg== + +"@popmotion/popcorn@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@popmotion/popcorn/-/popcorn-0.2.0.tgz#02750f55c27febd7b3009cc8ce29392735d235d0" + integrity sha512-IdVpvrvZ6mv7eYwxymQKjmVgOEu5byEwI566JpCIX9GD4/MwT8w0yq5LmC649iXvtYg2JAOW4o1Y+RKYl6dTPA== + dependencies: + "@popmotion/easing" "^1.0.1" + framesync "^4.0.1" + hey-listen "^1.0.5" + style-value-types "^3.0.7" + "@samverschueren/stream-to-observable@^0.3.0": version "0.3.0" resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" @@ -272,11 +287,6 @@ ansi-colors@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.1.tgz#9638047e4213f3428a11944a7d4b31cba0a3ff95" integrity sha512-Xt+zb6nqgvV9SWAVp0EG3lRsHcbq5DDgqjPPz6pwgtj6RKz65zGXMNa82oJfOSBA/to6GmRP7Dr+6o+kbApTzQ== -ansi-escapes@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" - integrity sha1-06ioOzGapneTZisT52HHkRQiMG4= - ansi-escapes@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" @@ -1723,6 +1733,13 @@ fragment-cache@^0.2.1: dependencies: map-cache "^0.2.2" +framesync@^4.0.0, framesync@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/framesync/-/framesync-4.0.1.tgz#ed7791baf0d266f58ab02000456f82cb384815bf" + integrity sha512-7dF3SXz/xMdwSHFHgj8PV2dAUCFclXWhasAb06rFvAM2pX24m9eDs6X+ikK0kx92w/uIljUi0sBINwcbl0rT2Q== + dependencies: + hey-listen "^1.0.5" + fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" @@ -1987,6 +2004,11 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" +hey-listen@^1.0.4, hey-listen@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/hey-listen/-/hey-listen-1.0.5.tgz#6d0a3a2f60177f65bc4404d571a00025bf5dc20e" + integrity sha512-O2iCNxBBGb4hOxL9tUdnoPwDYmZhQ29t5xKV74BVZNdvwCDXCpVYTJ4yoaibc1V0I8Yw3K3nwmvDpoyjnCqUaw== + hmac-drbg@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -2472,16 +2494,16 @@ jest-validate@^23.5.0: leven "^2.1.0" pretty-format "^23.6.0" -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + js-yaml@^3.7.0, js-yaml@^3.9.0: version "3.12.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" @@ -2592,21 +2614,7 @@ listr-silent-renderer@^1.1.1: resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" integrity sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4= -listr-update-renderer@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.4.0.tgz#344d980da2ca2e8b145ba305908f32ae3f4cc8a7" - integrity sha1-NE2YDaLKLosUW6MFkI8yrj9MyKc= - dependencies: - chalk "^1.1.3" - cli-truncate "^0.2.1" - elegant-spinner "^1.0.1" - figures "^1.7.0" - indent-string "^3.0.0" - log-symbols "^1.0.2" - log-update "^1.0.2" - strip-ansi "^3.0.1" - -"listr-update-renderer@https://github.com/okonet/listr-update-renderer/tarball/upgrade-log-update": +listr-update-renderer@^0.4.0, "listr-update-renderer@https://github.com/okonet/listr-update-renderer/tarball/upgrade-log-update": version "0.4.0" resolved "https://github.com/okonet/listr-update-renderer/tarball/upgrade-log-update#06073fa93166277607a7814f4e1f83960081414c" dependencies: @@ -2698,14 +2706,6 @@ log-symbols@^2.2.0: dependencies: chalk "^2.0.1" -log-update@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/log-update/-/log-update-1.0.2.tgz#19929f64c4093d2d2e7075a1dad8af59c296b8d1" - integrity sha1-GZKfZMQJPS0ucHWh2tivWcKWuNE= - dependencies: - ansi-escapes "^1.0.0" - cli-cursor "^1.0.2" - log-update@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708" @@ -2720,13 +2720,6 @@ loglevel@^1.4.1: resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa" integrity sha1-4PyVEztu8nbNyIh82vJKpvFW+Po= -loose-envify@^1.1.0, loose-envify@^1.3.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - lru-cache@^4.1.1: version "4.1.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" @@ -3160,7 +3153,7 @@ number-is-nan@^1.0.0: resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= -object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: +object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= @@ -3499,6 +3492,19 @@ please-upgrade-node@^3.0.2, please-upgrade-node@^3.1.1: dependencies: semver-compare "^1.0.0" +popmotion@^8.5.2: + version "8.5.2" + resolved "https://registry.yarnpkg.com/popmotion/-/popmotion-8.5.2.tgz#5c271fc4370f2739970c3a04bc890b7dbc8e519e" + integrity sha512-RZxR8TlEJ4mLePKMyJnz+OczEq81Yb6eHohLzA05bczpytC9nC9Ak5i+CHAoHaXEpW4dGqs0oeLeURnU/DUVMQ== + dependencies: + "@popmotion/easing" "^1.0.1" + "@popmotion/popcorn" "^0.2.0" + framesync "^4.0.0" + hey-listen "^1.0.5" + style-value-types "^3.0.6" + stylefire "^2.0.7" + tslib "^1.9.1" + portfinder@^1.0.9: version "1.0.19" resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.19.tgz#07e87914a55242dcda5b833d42f018d6875b595f" @@ -3555,14 +3561,6 @@ promise-inflight@^1.0.1: resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= -prop-types@^15.6.2: - version "15.6.2" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102" - integrity sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ== - dependencies: - loose-envify "^1.3.1" - object-assign "^4.1.1" - proxy-addr@~2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" @@ -3723,31 +3721,11 @@ react-dev-utils@^6.1.1: strip-ansi "4.0.0" text-table "0.2.0" -react-dom@^16.7.0-alpha.2: - version "16.7.0-alpha.2" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.7.0-alpha.2.tgz#16632880ed43676315991d8b412cce6975a30282" - integrity sha512-o0mMw8jBlwHjGZEy/vvKd/6giAX0+skREMOTs3/QHmgi+yAhUClp4My4Z9lsKy3SXV+03uPdm1l/QM7NTcGuMw== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - prop-types "^15.6.2" - scheduler "^0.12.0-alpha.2" - react-error-overlay@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-5.1.0.tgz#c516995a5652e7bfbed8b497910d5280df74a7e8" integrity sha512-akMy/BQT5m1J3iJIHkSb4qycq2wzllWsmmolaaFVnb+LPV9cIJ/nTud40ZsiiT0H3P+/wXIdbjx2fzF61OaeOQ== -react@^16.7.0-alpha.2: - version "16.7.0-alpha.2" - resolved "https://registry.yarnpkg.com/react/-/react-16.7.0-alpha.2.tgz#924f2ae843a46ea82d104a8def7a599fbf2c78ce" - integrity sha512-Xh1CC8KkqIojhC+LFXd21jxlVtzoVYdGnQAi/I2+dxbmos9ghbx5TQf9/nDxc4WxaFfUQJkya0w1k6rMeyIaxQ== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - prop-types "^15.6.2" - scheduler "^0.12.0-alpha.2" - read-pkg@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-4.0.1.tgz#963625378f3e1c4d48c85872b5a6ec7d5d093237" @@ -3940,14 +3918,6 @@ sax@^1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -scheduler@^0.12.0-alpha.2: - version "0.12.0-alpha.2" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.12.0-alpha.2.tgz#2a8bc8dc6ecdb75fa6480ceeedc1f187c9539970" - integrity sha512-bfqFzGH18MjjhePIzYQNR0uGQ1wMCX6Q83c2s+3fzyuqKT6zBI2wNQTpq01q72C7QItAp8if5w2LfMiXnI2SYw== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - schema-utils@^0.4.2, schema-utils@^0.4.4, schema-utils@^0.4.5: version "0.4.7" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" @@ -4406,6 +4376,30 @@ strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= +style-value-types@^3.0.6, style-value-types@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/style-value-types/-/style-value-types-3.0.7.tgz#6e7a22cc8b1a4465193268ed66ad5f2a82579054" + integrity sha512-7vzeicDiPNnJjvTYfJbQhZ7P3OCkXfvkJOJQ+ifFnXNTA/7KBxMZacHLvlRjM5/TtXbVdrZE6u+2nzSUSPrbSQ== + +stylefire@^2.0.7: + version "2.2.1" + resolved "https://registry.yarnpkg.com/stylefire/-/stylefire-2.2.1.tgz#3ae1f74477fa5117d410757cefe5878179708e38" + integrity sha512-0Yc5ILS2kVIow8UnbGLGRQhkECxIZTH23Y/KwjVJfuvocWyF/VfuRYwW8MngOkOhJ9oea6E38QgDWWJkj0EqJQ== + dependencies: + framesync "^4.0.0" + hey-listen "^1.0.4" + style-value-types "^3.0.6" + tslib "^1.9.1" + +stylefire@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/stylefire/-/stylefire-2.3.1.tgz#05b65601d65d717b9ac34ece81160f48d9442009" + integrity sha512-RNSf3ofR7n6+DG0zamrx81Ub7b83FqECbK+f4ks8piOogaNhZAKwYeMe5eBOz2cKF7eeD31OgTkfeVTyeGgAdw== + dependencies: + framesync "^4.0.0" + hey-listen "^1.0.4" + style-value-types "^3.0.6" + supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" @@ -4519,7 +4513,7 @@ ts-loader@^5.3.0: micromatch "^3.1.4" semver "^5.0.1" -tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: +tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.1: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== From 71c5ea7ceef6d99da25bd4a75b7f6461a2ef4ba0 Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Mon, 19 Nov 2018 16:29:57 +0000 Subject: [PATCH 04/44] adding pose resolver --- src/hooks/use-pose-resolver.ts | 124 +++++++++++++++++++-------------- src/motion-value/index.ts | 2 +- src/motion/types.ts | 24 ++++++- 3 files changed, 94 insertions(+), 56 deletions(-) diff --git a/src/hooks/use-pose-resolver.ts b/src/hooks/use-pose-resolver.ts index 436d5226e1..4724dd8a83 100644 --- a/src/hooks/use-pose-resolver.ts +++ b/src/hooks/use-pose-resolver.ts @@ -2,8 +2,15 @@ import { useRef, useEffect } from 'react'; import { invariant } from 'hey-listen'; import { tween, spring, keyframes, decay, physics } from 'popmotion'; import { poseToArray } from '../utils/pose-resolvers'; -import motionValue, { MotionValue } from '../motion-value'; -import { MotionConfig, MotionProps } from 'motion/types'; +import { MotionValue } from '../motion-value'; +import { + MotionConfig, + MotionProps, + PoseResolver, + Pose, + Transition, + TransitionMap +} from '../motion/types'; const transitions = { tween, spring, keyframes, decay, physics }; @@ -13,9 +20,15 @@ const defaultTransition = { damping: 15 }; -const getTransition = (key, transition, to) => { +const getTransition = ( + valueKey: string, + transition: Transition, + to: string | number +) => { const transitionDefinition = transition - ? transition[key] || transition.default || transition + ? transition[valueKey] || + (transition as TransitionMap).default || + transition : defaultTransition; const action = transitions[transitionDefinition.type || 'tween']; @@ -24,71 +37,74 @@ const getTransition = (key, transition, to) => { return [action, opts]; }; -const createPoseResolver = (config, values, props) => pose => { - console.log(pose); -}; - -const usePoseResolver = ( +const createPoseResolver = ( values: Map, config: MotionConfig, props: MotionProps -) => { - const poseResolver = useRef(null); - const { pose } = props; - const prevPoseResolver = poseResolver.current; - poseResolver.current = createPoseResolver(config, values, props); +) => (poseList: string[]) => { + poseList.forEach(poseKey => { + invariant( + config[poseKey] !== undefined, + `Pose with name ${poseKey} not found.` + ); - useEffect(() => { - if (pose instanceof MotionValue) { - pose.removeSubscriber(prevPoseResolver); - pose.addSubscriber(poseResolver.current); - } else if (prevPoseResolver) { - poseResolver.current(pose); - } - }); + const pose: Pose = + typeof config[poseKey] === 'function' + ? (config[poseKey] as PoseResolver)(props) + : (config[poseKey] as Pose); - // const poseObservable = - // props.pose instanceof MotionValue - // ? props.pose.addOnUpdate() - // : motionValue(props.pose); + const { transition, ...thisPose } = pose; - // const poseProp = poseToArray(props.pose); + // TODO: Check to see if `transition` exists and generate default + // based on keys being animated if not - // useEffect(() => poseObservable.set(poseProp), poseProp); + // Filter pose options like stagger children here + Object.keys(thisPose).forEach(valueKey => { + const value = values.get(valueKey); + const target = thisPose[valueKey]; - // useEffect(() => { - // const hadPose = pose.current !== null; - // pose.current = poseToArray(props.pose); + invariant( + value !== undefined, + 'Value not found. Ensure all animated values are created on component mount.' // Maybe create this value on the fly instead? + ); - // if (!hadPose || !props.pose) return; + const [action, opts] = getTransition(valueKey, transition, target); - // pose.current.forEach(poseKey => { - // // Resolve Pose with props if function here - - // invariant( - // config[poseKey] !== undefined, - // `Pose with name ${poseKey} not found.` // Show available poses? - // ); + value.control(action, opts); + }); + }); +}; - // const { transition, ...thisPose } = config[poseKey]; +const usePoseResolver = ( + values: Map, + config: MotionConfig, + props: MotionProps +) => { + const poseSubscriber = useRef(null); + const { pose } = props; + const poseIsSubscription = pose instanceof MotionValue; + const poseResolver = createPoseResolver(values, config, props); - // // TODO: Check to see if `transition` exists and generate default - // // based on keys being animated if not + // If we're controlled by props, fire resolver with latest pose + const poseList = !poseIsSubscription + ? poseToArray(pose as string | string[]) + : []; + useEffect(() => { + if (!poseIsSubscription) poseResolver(poseList); + }, poseList); - // // Filter pose options like stagger children here - // Object.keys(thisPose).forEach(valueKey => { - // const value = values.get(valueKey); - // const target = thisPose[valueKey]; + // Or if we're using a pose subscription, manage subscriptions + useEffect(() => { + if (!poseIsSubscription) return; - // invariant( - // value !== undefined, - // "Value not found. Ensure all animated values are created on component mount." // Maybe create this value on the fly instead? - // ); + poseSubscriber.current = (v: string | string[]) => + poseResolver(poseToArray(v)); + (pose as MotionValue).addSubscriber(poseSubscriber.current); - // value.control(...getTransition(valueKey, transition, target)); - // }); - // }); - // }, pose.current); + return () => { + (pose as MotionValue).removeSubscriber(poseSubscriber.current); + }; + }); }; export default usePoseResolver; diff --git a/src/motion-value/index.ts b/src/motion-value/index.ts index d9a731ad85..edc033fc08 100644 --- a/src/motion-value/index.ts +++ b/src/motion-value/index.ts @@ -119,7 +119,7 @@ export class MotionValue { control( controller: ActionFactory, config: ActionConfig, - transformer: Transformer + transformer?: Transformer ) { this.stop(); diff --git a/src/motion/types.ts b/src/motion/types.ts index 9b5b3a7393..00c78418b0 100644 --- a/src/motion/types.ts +++ b/src/motion/types.ts @@ -4,7 +4,29 @@ export type MotionProps = { pose: string | string[] | MotionValue; }; -export type Pose = { +export type Tween = {}; + +export type Spring = {}; + +export type Decay = {}; + +export type Keyframes = {}; + +export type Physics = {}; + +export type Transition = Tween | Spring | Decay | Keyframes | Physics; + +export type TransitionMap = { default?: Transition; [key: string]: Transition }; + +export type TransitionDefinition = Transition | TransitionMap; + +export type PoseSettings = { + transition?: TransitionDefinition; + staggerDirection?: number; + staggerChildren?: number; +}; + +export type Pose = PoseSettings & { [key: string]: number | string; }; From 86d1ffc9d8428f02403ceaec993da4fcfbcfebae Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Mon, 19 Nov 2018 16:37:20 +0000 Subject: [PATCH 05/44] adding useTransform --- package.json | 1 + src/hooks/use-transform.ts | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 src/hooks/use-transform.ts diff --git a/package.json b/package.json index 9e1cebf4f0..a7dd0dc609 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "webpack-dev-server": "^3.1.10" }, "dependencies": { + "@popmotion/popcorn": "^0.2.0", "hey-listen": "^1.0.5", "popmotion": "^8.5.2", "stylefire": "^2.3.1" diff --git a/src/hooks/use-transform.ts b/src/hooks/use-transform.ts new file mode 100644 index 0000000000..9dc723b68c --- /dev/null +++ b/src/hooks/use-transform.ts @@ -0,0 +1,22 @@ +import { useMemo, useRef } from 'react'; +import { MotionValue } from '../motion-value'; +import { interpolate } from '@popmotion/popcorn'; + +export default ( + value: MotionValue, + from: number[], + to: string[] | number[] +) => { + const transformedValue = useRef(null); + + return useMemo( + () => { + if (transformedValue.current) transformedValue.current.destroy(); + transformedValue.current = value.addChild({ + transformer: interpolate(from, to) + }); + return transformedValue.current; + }, + [value, ...from, ...to] + ); +}; From 4c61c4d5e6a5406382781d146684b0510111e184 Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Mon, 19 Nov 2018 17:40:49 +0000 Subject: [PATCH 06/44] removing generics --- dev/examples/test.tsx | 3 ++- src/hooks/use-config.ts | 8 ++++---- src/hooks/use-motion-value.ts | 4 ++++ src/hooks/use-pose.ts | 17 ++++++++++++++++ src/hooks/use-posed-values.ts | 8 ++++---- src/hooks/use-style-attr.ts | 5 ++++- src/motion-value/index.ts | 2 +- src/motion/component.ts | 37 +++++++++++++++++++++++------------ src/motion/index.ts | 3 ++- src/motion/types.ts | 25 +++++++++++++++++------ 10 files changed, 82 insertions(+), 30 deletions(-) create mode 100644 src/hooks/use-motion-value.ts create mode 100644 src/hooks/use-pose.ts diff --git a/dev/examples/test.tsx b/dev/examples/test.tsx index 9361370e5e..e3a139519a 100644 --- a/dev/examples/test.tsx +++ b/dev/examples/test.tsx @@ -1,7 +1,8 @@ import * as React from 'react'; export class App extends React.Component { - render() { + // I've had to return `any` here, I thought this was usually inferred? + render(): any { return null; } } diff --git a/src/hooks/use-config.ts b/src/hooks/use-config.ts index 96bcdc2a04..805b075b0e 100644 --- a/src/hooks/use-config.ts +++ b/src/hooks/use-config.ts @@ -1,16 +1,16 @@ import { useMemo } from 'react'; import { MotionConfig, - MotionConfigResolver, + MotionConfigFactory, MotionProps } from '../motion/types'; const isResolver = ( - config: MotionConfig | MotionConfigResolver -): config is MotionConfigResolver => typeof config === 'function'; + config: MotionConfig | MotionConfigFactory +): config is MotionConfigFactory => typeof config === 'function'; const useConfig = ( - baseConfig: MotionConfig | MotionConfigResolver, + baseConfig: MotionConfig | MotionConfigFactory, props: MotionProps ) => useMemo(() => (isResolver(baseConfig) ? baseConfig(props) : baseConfig), []); diff --git a/src/hooks/use-motion-value.ts b/src/hooks/use-motion-value.ts new file mode 100644 index 0000000000..04504f15a4 --- /dev/null +++ b/src/hooks/use-motion-value.ts @@ -0,0 +1,4 @@ +import { useMemo } from 'react'; +import motionValue from '../motion-value'; + +export default (init: number | string) => useMemo(() => motionValue(init), []); diff --git a/src/hooks/use-pose.ts b/src/hooks/use-pose.ts new file mode 100644 index 0000000000..1230d965d0 --- /dev/null +++ b/src/hooks/use-pose.ts @@ -0,0 +1,17 @@ +import { useMemo } from 'react'; +import motionValue from '../motion-value'; +import { poseToArray } from '../utils/pose-resolvers'; + +const usePose = (initPose = 'default') => { + return useMemo(() => { + const pose = motionValue(initPose, { + transformer: (v: string | string[]) => poseToArray(v) + }); + + const setPose = (newPose: string | string[]) => pose.set(newPose); + + return [pose, setPose]; + }, []); +}; + +export default usePose; diff --git a/src/hooks/use-posed-values.ts b/src/hooks/use-posed-values.ts index 49cc019a6e..a7b8ce9c14 100644 --- a/src/hooks/use-posed-values.ts +++ b/src/hooks/use-posed-values.ts @@ -4,11 +4,11 @@ import { MotionConfig, MotionProps } from '../motion/types'; import { useRef, useEffect, RefObject } from 'react'; import styler from 'stylefire'; -export default

( +export default ( config: MotionConfig, - props: P & MotionProps, + props: MotionProps, ref: RefObject -): [Map, P & MotionProps] => { +): [Map, Partial] => { const values = useRef(new Map()).current; const returnedProps = {}; @@ -51,7 +51,7 @@ export default

( const domStyler = styler(ref.current); values.forEach((value, key) => { - value.setOnRender(v => domStyler.set(key, v)); + value.setOnRender((v: any) => domStyler.set(key, v)); }); return () => values.forEach(value => value.destroy()); diff --git a/src/hooks/use-style-attr.ts b/src/hooks/use-style-attr.ts index a640923791..60f1e11875 100644 --- a/src/hooks/use-style-attr.ts +++ b/src/hooks/use-style-attr.ts @@ -2,7 +2,10 @@ import { useMemo, CSSProperties } from 'react'; import { buildStyleProperty } from 'stylefire'; import { MotionValue } from '../motion-value'; -export default (styles: CSSProperties, values: Map) => +export default ( + values: Map, + styles?: CSSProperties +): CSSProperties => useMemo(() => { const resolvedValues = Object.keys(values).reduce((acc, key) => { acc[key] = values[key].get(); diff --git a/src/motion-value/index.ts b/src/motion-value/index.ts index edc033fc08..1e14bfd656 100644 --- a/src/motion-value/index.ts +++ b/src/motion-value/index.ts @@ -1,7 +1,7 @@ import sync from 'framesync'; import { Action, ColdSubscription } from 'popmotion'; -export type ValuePrimitive = number | string; +export type ValuePrimitive = any; export type Transformer = (v: ValuePrimitive) => ValuePrimitive; diff --git a/src/motion/component.ts b/src/motion/component.ts index 335189f5ce..e8c8901735 100644 --- a/src/motion/component.ts +++ b/src/motion/component.ts @@ -1,29 +1,42 @@ -import { memo, forwardRef, createElement, Ref, ComponentType } from 'react'; -import { MotionProps, MotionConfig, MotionConfigResolver } from './types'; +import { + memo, + forwardRef, + createElement, + Ref, + ComponentType, + createRef, + HTMLProps, + SVGProps +} from 'react'; +import { MotionProps, ComponentFactory } from './types'; import useConfig from '../hooks/use-config'; import useExternalRef from '../hooks/use-external-ref'; import usePosedValues from '../hooks/use-posed-values'; import usePoseResolver from '../hooks/use-pose-resolver'; import useStyleAttr from '../hooks/use-style-attr'; -const createMotionComponent =

( - Component: ComponentType

| string -) => (motionConfig: MotionConfig | MotionConfigResolver) => { +const createMotionComponent = ( + Component: string | ComponentType +): ComponentFactory => motionConfig => { const MotionComponent = forwardRef( - (props: P & MotionProps, externalRef?: Ref) => { + (props: MotionProps, externalRef?: Ref) => { const ref = useExternalRef(externalRef); const config = useConfig(motionConfig, props); // Create motion values - const [values, componentProps] = usePosedValues

(config, props, ref); + const [values, componentProps] = usePosedValues(config, props, ref); usePoseResolver(values, config, props); - return createElement(Component, { - ref, - ...componentProps, - style: useStyleAttr(props.styles, values) - }); + // Types here are a bit of a hack + return createElement | SVGProps & MotionProps>( + Component, + { + ref: createRef(), + ...componentProps, + style: useStyleAttr(values, props.style) + } + ); } ); diff --git a/src/motion/index.ts b/src/motion/index.ts index 0ff5d51233..58e94ab34e 100644 --- a/src/motion/index.ts +++ b/src/motion/index.ts @@ -1,7 +1,8 @@ import createMotionComponent from './component'; import supportedElements from './supported-elements'; +import { Motion } from './types'; -const motion = createMotionComponent; +const motion: Motion = createMotionComponent as Motion; supportedElements.forEach( element => (motion[element] = createMotionComponent(element)) diff --git a/src/motion/types.ts b/src/motion/types.ts index 00c78418b0..586a13e6a8 100644 --- a/src/motion/types.ts +++ b/src/motion/types.ts @@ -1,7 +1,26 @@ import { MotionValue } from '../motion-value'; +import { RefObject, CSSProperties, ComponentType } from 'react'; + +export type MotionConfigFactory = (props: MotionProps) => MotionConfig; + +export type ComponentFactory = ( + config?: MotionConfigFactory | MotionConfig +) => ComponentType; + +export type Motion = { + (component: ComponentType): ComponentFactory; + [key: string]: ComponentFactory; +}; + +export type MotionConfig = { + [key: string]: Pose | PoseResolver; +}; export type MotionProps = { + [key: string]: any; + ref: RefObject; pose: string | string[] | MotionValue; + style: CSSProperties; }; export type Tween = {}; @@ -31,9 +50,3 @@ export type Pose = PoseSettings & { }; export type PoseResolver = (props: { [key: string]: any }) => Pose; - -export type MotionConfig = { - [key: string]: Pose | PoseResolver; -}; - -export type MotionConfigResolver = (props: MotionProps) => MotionConfig; From c721b3c0398776ce4fcdbdf93b0d0c3d707541ae Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Tue, 20 Nov 2018 11:54:11 +0000 Subject: [PATCH 07/44] adding tests --- .gitignore | 1 + dev/.DS_Store | Bin 0 -> 6148 bytes dev/examples/test.tsx | 13 +- dev/styled.ts | 16 + dev/webpack/config.js | 1 + dev/webpack/examples.tsx | 112 +- dev/webpack/index.tsx | 8 +- package.json | 20 +- src/hooks/use-pose-resolver.ts | 18 +- src/hooks/use-posed-values.ts | 2 + src/hooks/use-transform.ts | 4 +- src/motion-value/index.ts | 9 +- src/motion/component.ts | 2 +- src/motion/types.ts | 2 +- src/utils/__tests__/pose-resolvers.test.ts | 15 + src/utils/pose-resolvers.ts | 4 +- tsconfig.json | 4 +- yarn.lock | 2228 +++++++++++++++++++- 18 files changed, 2329 insertions(+), 130 deletions(-) create mode 100644 dev/.DS_Store create mode 100644 dev/styled.ts create mode 100644 src/utils/__tests__/pose-resolvers.test.ts diff --git a/.gitignore b/.gitignore index 7c7b153109..bccfa11ce3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /node_modules /.cache-loader +.DS_Store diff --git a/dev/.DS_Store b/dev/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..2eb4585ac85b5728fae815b1413c5f81a5396cd5 GIT binary patch literal 6148 zcmeHK%}yIJ5FUq6oK&beR4T{4AaURjRDKRsrB$E@Zb(~|1Fc|}M6hC6N7+rcB~7)j z0dK&g^a=Vn?KifIfRy(m{3FdAV=$ zGEVcs$R?-#0YW|=r+MF0Ju}Yxh3zMD4y{|db=p~*OtyD+HiPZm?sPMl?Co`7zuuir zTl&@d*4x9g>#sMHZ`1F$b||E9e zGql|!VwN^kMT7xiKp0pI2K?5ipD)Jm$X^Hp!oUJC!23f0Weh#m4(--~!af0je2ugM zo3D(V6L<_g)(+u;D3=O!smebwluJi@;NwD%wL_Oq%0E7o|FZHg6lK4T{sS9MDs(8N zFdz&(W?;!xJAD4X`}_OZ*!SPueK+m8o99KJhNP%IG gV#M-Myau&`_J9pw=&^Q)7KmH~EDcf!1OJqP-`VtS7XSbN literal 0 HcmV?d00001 diff --git a/dev/examples/test.tsx b/dev/examples/test.tsx index e3a139519a..4bcf91e4c0 100644 --- a/dev/examples/test.tsx +++ b/dev/examples/test.tsx @@ -1,8 +1,9 @@ import * as React from 'react'; +import { motion } from '@framer'; +import { Box } from '../styled'; -export class App extends React.Component { - // I've had to return `any` here, I thought this was usually inferred? - render(): any { - return null; - } -} +const MotionBox = motion(Box)(); + +export const App = () => { + return ; +}; diff --git a/dev/styled.ts b/dev/styled.ts new file mode 100644 index 0000000000..9591a4b89e --- /dev/null +++ b/dev/styled.ts @@ -0,0 +1,16 @@ +import styled from 'styled-components'; + +export const Container = styled.div` + min-width: 100vw; + min-height: 100vh; + background: #343d48; + display: flex; + align-items: center; + justify-content: center; +`; + +export const Box = styled.div` + width: 100px; + height: 100px; + background: #fff; +`; diff --git a/dev/webpack/config.js b/dev/webpack/config.js index 005acc7519..a51cedaf6d 100644 --- a/dev/webpack/config.js +++ b/dev/webpack/config.js @@ -27,4 +27,5 @@ config.devServer = { stats: 'errors-only', port: DEV_SERVER_PORT }; + Object.assign(exports, config); diff --git a/dev/webpack/examples.tsx b/dev/webpack/examples.tsx index b4106f6e22..8b8d27a852 100644 --- a/dev/webpack/examples.tsx +++ b/dev/webpack/examples.tsx @@ -1,68 +1,78 @@ -import * as React from "react" -import { basename, extname } from "path" +import * as React from 'react'; +import { basename, extname } from 'path'; +import { Container } from '../styled'; -const context = require["context"]("../examples", true, /\.(tsx?)$/) +const context = require['context']('../examples', true, /\.(tsx?)$/); const fileName = (pathName: string) => { - return basename(pathName, extname(pathName)) -} + return basename(pathName, extname(pathName)); +}; const style: React.CSSProperties = { - font: "16px/1.6em 'Helvetica Neue'", - textRendering: "optimizeLegibility", - margin: "64px", -} + font: "16px/1.6em 'Helvetica Neue'", + textRendering: 'optimizeLegibility', + margin: '64px' +}; const Code: React.SFC = props => { - return {props.children} -} + return ( + + {props.children} + + ); +}; const ExampleList = () => { - return ( -

-

Framer Examples

-

- You can edit any of these in the dev/examples folder. -

-
    - {context.keys().map((name: string) => ( -
  • - {fileName(name)}{" "} - {name.replace("./", "examples/")} -
  • - ))} -
-
- ) -} + return ( +
+

Framer Examples

+

+ You can edit any of these in the dev/examples folder. +

+
    + {context.keys().map((name: string) => ( +
  • + {fileName(name)}{' '} + {name.replace('./', 'examples/')} +
  • + ))} +
+
+ ); +}; export class App extends React.Component { - render() { - const url = new URL(window.location.href) - const example = url.searchParams.get("example") + render() { + const url = new URL(window.location.href); + const example = url.searchParams.get('example'); - if (!example) { - return - } - - const exampleName = fileName(example) - const exampleApp = require(`../examples/${exampleName}`) + if (!example) { + return ; + } - if (exampleApp) { - if (exampleApp.App) { - // Update the document title to the example - document.title = exampleName + const exampleName = fileName(example); + const exampleApp = require(`../examples/${exampleName}`); - return React.createElement(exampleApp.App) - } else { - return ( -

- examples/{example} does not have a export named App -

- ) - } - } + if (exampleApp) { + if (exampleApp.App) { + // Update the document title to the example + document.title = exampleName; - return + return ( + + + + ); + } else { + return ( +

+ examples/{example} does not have a export named{' '} + App +

+ ); + } } + + return ; + } } diff --git a/dev/webpack/index.tsx b/dev/webpack/index.tsx index c6058686b9..3bab16a925 100644 --- a/dev/webpack/index.tsx +++ b/dev/webpack/index.tsx @@ -1,6 +1,6 @@ -import * as React from "react" -import * as ReactDOM from "react-dom" +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; -const App = require("./examples").App +const App = require('./examples').App; -ReactDOM.render(, document.getElementById("root")) +ReactDOM.render(, document.getElementById('root')); diff --git a/package.json b/package.json index a7dd0dc609..d9fc7aadef 100644 --- a/package.json +++ b/package.json @@ -7,9 +7,9 @@ "author": "Framer Motion", "license": "MIT", "scripts": { - "coverage": "jest --config jest.json --coverage", - "test": "jest --config jest.json", - "watch": "jest --config jest.json --watch", + "coverage": "jest --coverage", + "test": "jest", + "watch": "jest --watch", "prettier": "prettier ./src/* --write" }, "peerDependencies": { @@ -17,17 +17,24 @@ "react-dom": "^16.7" }, "devDependencies": { + "@types/jest": "^23.3.9", "@types/node": "^10.12.9", "@types/react": "^16.7.6", "@types/react-dom": "^16.0.9", + "@types/styled-components": "^4.1.0", "cache-loader": "^1.2.5", "convert-tsconfig-paths-to-webpack-aliases": "^0.9.2", "fork-ts-checker-webpack-plugin": "^0.4.15", "husky": "^1.1.4", + "jest": "^23.6.0", "lint-staged": "^8.0.4", "prettier": "^1.15.2", "progress-bar-webpack-plugin": "^1.11.0", + "react": "^16.7.0-alpha.2", "react-dev-utils": "^6.1.1", + "react-dom": "^16.7.0-alpha.2", + "styled-components": "^4.1.1", + "ts-jest": "^23.10.4", "ts-loader": "^5.3.0", "tslint": "^5.11.0", "tslint-microsoft-contrib": "^5.2.1", @@ -39,7 +46,7 @@ "dependencies": { "@popmotion/popcorn": "^0.2.0", "hey-listen": "^1.0.5", - "popmotion": "^8.5.2", + "popmotion": "8.5.3", "stylefire": "^2.3.1" }, "prettier": { @@ -56,5 +63,10 @@ "prettier --write", "git add" ] + }, + "jest": { + "preset": "ts-jest", + "testEnvironment": "node", + "rootDir": "src" } } diff --git a/src/hooks/use-pose-resolver.ts b/src/hooks/use-pose-resolver.ts index 4724dd8a83..ba73c7a805 100644 --- a/src/hooks/use-pose-resolver.ts +++ b/src/hooks/use-pose-resolver.ts @@ -1,4 +1,4 @@ -import { useRef, useEffect } from 'react'; +import { useRef, useEffect, MutableRefObject } from 'react'; import { invariant } from 'hey-listen'; import { tween, spring, keyframes, decay, physics } from 'popmotion'; import { poseToArray } from '../utils/pose-resolvers'; @@ -12,6 +12,8 @@ import { TransitionMap } from '../motion/types'; +type PoseSubscriber = (v: string | string[]) => void; + const transitions = { tween, spring, keyframes, decay, physics }; const defaultTransition = { @@ -22,8 +24,8 @@ const defaultTransition = { const getTransition = ( valueKey: string, - transition: Transition, - to: string | number + to: string | number, + transition?: Transition ) => { const transitionDefinition = transition ? transition[valueKey] || @@ -68,9 +70,9 @@ const createPoseResolver = ( 'Value not found. Ensure all animated values are created on component mount.' // Maybe create this value on the fly instead? ); - const [action, opts] = getTransition(valueKey, transition, target); + const [action, opts] = getTransition(valueKey, target, transition); - value.control(action, opts); + value && value.control(action, opts); }); }); }; @@ -80,7 +82,7 @@ const usePoseResolver = ( config: MotionConfig, props: MotionProps ) => { - const poseSubscriber = useRef(null); + const poseSubscriber: MutableRefObject = useRef(null); const { pose } = props; const poseIsSubscription = pose instanceof MotionValue; const poseResolver = createPoseResolver(values, config, props); @@ -102,7 +104,9 @@ const usePoseResolver = ( (pose as MotionValue).addSubscriber(poseSubscriber.current); return () => { - (pose as MotionValue).removeSubscriber(poseSubscriber.current); + if (poseSubscriber.current) { + (pose as MotionValue).removeSubscriber(poseSubscriber.current); + } }; }); }; diff --git a/src/hooks/use-posed-values.ts b/src/hooks/use-posed-values.ts index a7b8ce9c14..d104cfb861 100644 --- a/src/hooks/use-posed-values.ts +++ b/src/hooks/use-posed-values.ts @@ -48,6 +48,8 @@ export default ( // 3. Bind stylers when ref is ready useEffect(() => { + if (!ref.current) return; + const domStyler = styler(ref.current); values.forEach((value, key) => { diff --git a/src/hooks/use-transform.ts b/src/hooks/use-transform.ts index 9dc723b68c..6aa3d53809 100644 --- a/src/hooks/use-transform.ts +++ b/src/hooks/use-transform.ts @@ -1,4 +1,4 @@ -import { useMemo, useRef } from 'react'; +import { useMemo, useRef, MutableRefObject } from 'react'; import { MotionValue } from '../motion-value'; import { interpolate } from '@popmotion/popcorn'; @@ -7,7 +7,7 @@ export default ( from: number[], to: string[] | number[] ) => { - const transformedValue = useRef(null); + const transformedValue: MutableRefObject = useRef(null); return useMemo( () => { diff --git a/src/motion-value/index.ts b/src/motion-value/index.ts index 1e14bfd656..73430a0b17 100644 --- a/src/motion-value/index.ts +++ b/src/motion-value/index.ts @@ -41,9 +41,12 @@ export class MotionValue { transformer?: Transformer; // A reference to the currently-controlling animation - controller: ColdSubscription; + controller?: ColdSubscription; - constructor(init: ValuePrimitive, { onRender, transformer, parent }: Config) { + constructor( + init: ValuePrimitive, + { onRender, transformer, parent }: Config = {} + ) { this.parent = parent; this.transformer = transformer; if (onRender) this.setOnRender(onRender); @@ -142,7 +145,7 @@ export class MotionValue { } stop() { - this.controller && this.controller.stop(); + if (this.controller) this.controller.stop(); } destroy() { diff --git a/src/motion/component.ts b/src/motion/component.ts index e8c8901735..933b3eac20 100644 --- a/src/motion/component.ts +++ b/src/motion/component.ts @@ -17,7 +17,7 @@ import useStyleAttr from '../hooks/use-style-attr'; const createMotionComponent = ( Component: string | ComponentType -): ComponentFactory => motionConfig => { +): ComponentFactory => (motionConfig = {}) => { const MotionComponent = forwardRef( (props: MotionProps, externalRef?: Ref) => { const ref = useExternalRef(externalRef); diff --git a/src/motion/types.ts b/src/motion/types.ts index 586a13e6a8..9ba2b66943 100644 --- a/src/motion/types.ts +++ b/src/motion/types.ts @@ -35,7 +35,7 @@ export type Physics = {}; export type Transition = Tween | Spring | Decay | Keyframes | Physics; -export type TransitionMap = { default?: Transition; [key: string]: Transition }; +export type TransitionMap = { [key: string]: Transition }; export type TransitionDefinition = Transition | TransitionMap; diff --git a/src/utils/__tests__/pose-resolvers.test.ts b/src/utils/__tests__/pose-resolvers.test.ts new file mode 100644 index 0000000000..46e8ab3b5e --- /dev/null +++ b/src/utils/__tests__/pose-resolvers.test.ts @@ -0,0 +1,15 @@ +import { poseToArray } from '../pose-resolvers'; + +describe('poseToArray', () => { + it('Should correctly convert single string to array', () => { + expect(poseToArray('a')).toEqual(['a']); + }); + + it('Should leave arrays as-is', () => { + expect(poseToArray(['a', 'b'])).toEqual(['a', 'b']); + }); + + it('Should remove falsey poses', () => { + expect(poseToArray(undefined)).toEqual([]); + }); +}); diff --git a/src/utils/pose-resolvers.ts b/src/utils/pose-resolvers.ts index 4a9dfc90c5..1ff9077250 100644 --- a/src/utils/pose-resolvers.ts +++ b/src/utils/pose-resolvers.ts @@ -4,8 +4,8 @@ type PoseNameList = string[]; type PoseName = string | PoseNameList; type UnresolvedPose = PoseName | MotionValue; -export const poseToArray = (pose: PoseName): PoseNameList => - Array.isArray(pose) ? [...pose].reverse() : [pose]; +export const poseToArray = (pose?: PoseName): PoseNameList => + Array.isArray(pose) ? [...pose].reverse() : pose ? [pose] : []; export const resolvePoses = (pose: UnresolvedPose): PoseNameList => { const unresolvedPose = diff --git a/tsconfig.json b/tsconfig.json index c7f7d71627..7ec77f2df3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { "target": "es2015", - "module": "esnext", + "module": "commonjs", "moduleResolution": "node", "isolatedModules": false, "jsx": "react", @@ -19,7 +19,7 @@ "@framer": ["../src/index"], "@framer/*": ["../src/*"] }, - "strictNullChecks": false, + "strictNullChecks": true, "noImplicitAny": true, "noImplicitThis": true, "noImplicitUseStrict": false, diff --git a/yarn.lock b/yarn.lock index 78a09c94df..1c3a5e902e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,13 +2,20 @@ # yarn lockfile v1 -"@babel/code-frame@7.0.0": +"@babel/code-frame@7.0.0", "@babel/code-frame@^7.0.0-beta.35": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA== dependencies: "@babel/highlight" "^7.0.0" +"@babel/helper-annotate-as-pure@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" + integrity sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q== + dependencies: + "@babel/types" "^7.0.0" + "@babel/highlight@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4" @@ -18,6 +25,32 @@ esutils "^2.0.2" js-tokens "^4.0.0" +"@babel/types@^7.0.0": + version "7.1.6" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.1.6.tgz#0adb330c3a281348a190263aceb540e10f04bcce" + integrity sha512-DMiUzlY9DSjVsOylJssxLHSgj6tWM9PRFJOGW/RaOglVOK9nzTxoOMfTfRQXGUCUQ/HmlG2efwC+XqUEJ5ay4w== + dependencies: + esutils "^2.0.2" + lodash "^4.17.10" + to-fast-properties "^2.0.0" + +"@emotion/is-prop-valid@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.6.8.tgz#68ad02831da41213a2089d2cab4e8ac8b30cbd85" + integrity sha512-IMSL7ekYhmFlILXcouA6ket3vV7u9BqStlXzbKOF9HBtpUPMMlHU+bBxrLOa2NvleVwNIxeq/zL8LafLbeUXcA== + dependencies: + "@emotion/memoize" "^0.6.6" + +"@emotion/memoize@^0.6.6": + version "0.6.6" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.6.6.tgz#004b98298d04c7ca3b4f50ca2035d4f60d2eed1b" + integrity sha512-h4t4jFjtm1YV7UirAFuSuFGyLa+NNxjdkq6DpFLANNQY5rHueFZHVY+8Cu1HYVP6DrheB0kv4m5xPjo7eKT7yQ== + +"@emotion/unitless@^0.7.0": + version "0.7.2" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.2.tgz#b180097bb44a40c3b59efea9cf28df2fe542d518" + integrity sha512-mK4SHgIiJiwRZyenDXlaLUdR7vm8xUvJ4VYmpWNTDtF3ykEbI1XNVcbhAZwt07xjtCvLenoJMP8Eqx1FXvoWDQ== + "@mrmlnc/readdir-enhanced@^2.2.1": version "2.2.1" resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" @@ -53,6 +86,11 @@ dependencies: any-observable "^0.3.0" +"@types/jest@^23.3.9": + version "23.3.9" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-23.3.9.tgz#c16b55186ee73ae65e001fbee69d392c51337ad1" + integrity sha512-wNMwXSUcwyYajtbayfPp55tSayuDVU6PfY5gzvRSj80UvxdXEJOVPnUVajaOp7NgXLm+1e2ZDLULmpsU9vDvQw== + "@types/node@*", "@types/node@^10.12.9": version "10.12.9" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.9.tgz#a07bfa74331471e1dc22a47eb72026843f7b95c8" @@ -79,6 +117,15 @@ "@types/prop-types" "*" csstype "^2.2.0" +"@types/styled-components@^4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-4.1.0.tgz#87d193ccfd4768c3b7606404646f3564c18830d0" + integrity sha512-B2OuPjx5LG+JIgDid7mR9WCYQ4XqWgOe9D6oyUtnEVES4D3S4rtyD0Vgp7BzAk6YAkLM6m4MqK/9Ityl5SwwTg== + dependencies: + "@types/node" "*" + "@types/react" "*" + csstype "^2.2.0" + "@webassemblyjs/ast@1.7.11": version "1.7.11" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.7.11.tgz#b988582cafbb2b095e8b556526f30c90d057cace" @@ -232,6 +279,11 @@ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.1.tgz#5c85d662f76fa1d34575766c5dcd6615abcd30d8" integrity sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g== +abab@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.0.tgz#aba0ab4c5eee2d4c79d3487d85450fb2376ebb0f" + integrity sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w== + abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -252,11 +304,29 @@ acorn-dynamic-import@^3.0.0: dependencies: acorn "^5.0.0" -acorn@^5.0.0, acorn@^5.6.2: +acorn-globals@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.0.tgz#e3b6f8da3c1552a95ae627571f7dd6923bb54103" + integrity sha512-hMtHj3s5RnuhvHPowpBYvJVj3rAar82JiDQHvGs1zO0l10ocX/xEdBShNHTJaboucJUsScghp74pH3s7EnHHQw== + dependencies: + acorn "^6.0.1" + acorn-walk "^6.0.1" + +acorn-walk@^6.0.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.1.1.tgz#d363b66f5fac5f018ff9c3a1e7b6f8e310cc3913" + integrity sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw== + +acorn@^5.0.0, acorn@^5.5.3, acorn@^5.6.2: version "5.7.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== +acorn@^6.0.1: + version "6.0.4" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.4.tgz#77377e7353b72ec5104550aa2d2097a2fd40b754" + integrity sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg== + address@1.0.3, address@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/address/-/address-1.0.3.tgz#b5f50631f8d6cec8bd20c963963afb55e06cbce9" @@ -272,7 +342,7 @@ ajv-keywords@^3.1.0: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" integrity sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo= -ajv@^6.1.0: +ajv@^6.1.0, ajv@^6.5.5: version "6.5.5" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.5.tgz#cf97cdade71c6399a92c6d6c4177381291b781a1" integrity sha512-7q7gtRQDJSyuEHjuVgHoUa2VuemFiCMrfQc9Tc08XTAc4Zj/5U1buQJ0HU6i7fKjXU09SVgSmxa4sLvuvS8Iyg== @@ -332,6 +402,13 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" +append-transform@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991" + integrity sha1-126/jKlNJ24keja61EpLdKthGZE= + dependencies: + default-require-extensions "^1.0.0" + aproba@^1.0.3, aproba@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" @@ -352,12 +429,19 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= + dependencies: + arr-flatten "^1.0.1" + arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= -arr-flatten@^1.1.0: +arr-flatten@^1.0.1, arr-flatten@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== @@ -367,6 +451,11 @@ arr-union@^3.1.0: resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= +array-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" + integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= + array-filter@~0.0.0: version "0.0.1" resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" @@ -404,6 +493,11 @@ array-uniq@^1.0.1: resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= + array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" @@ -414,6 +508,11 @@ arrify@^1.0.1: resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= +asap@~2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= + asn1.js@^4.0.0: version "4.10.1" resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" @@ -423,6 +522,18 @@ asn1.js@^4.0.0: inherits "^2.0.1" minimalistic-assert "^1.0.0" +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + assert@^1.1.1: version "1.4.1" resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" @@ -435,22 +546,54 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + async-each@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" integrity sha1-GdOGodntxufByF04iu28xW0zYC0= +async-limiter@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" + integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== + async@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= +async@^2.1.4, async@^2.5.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" + integrity sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ== + dependencies: + lodash "^4.17.10" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + atob@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -babel-code-frame@^6.22.0: +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" + integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== + +babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= @@ -459,6 +602,166 @@ babel-code-frame@^6.22.0: esutils "^2.0.2" js-tokens "^3.0.2" +babel-core@^6.0.0, babel-core@^6.26.0: + version "6.26.3" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" + integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA== + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.1" + debug "^2.6.9" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.8" + slash "^1.0.0" + source-map "^0.5.7" + +babel-generator@^6.18.0, babel-generator@^6.26.0: + version "6.26.1" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" + integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.7" + trim-right "^1.0.1" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI= + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-jest@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-23.6.0.tgz#a644232366557a2240a0c083da6b25786185a2f1" + integrity sha512-lqKGG6LYXYu+DQh/slrQ8nxXQkEkhugdXsU6St7GmhVS7Ilc/22ArwqXNJrf0QaOBjZB0360qZMwXqDYQHXaew== + dependencies: + babel-plugin-istanbul "^4.1.6" + babel-preset-jest "^23.2.0" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-istanbul@^4.1.6: + version "4.1.6" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz#36c59b2192efce81c5b378321b74175add1c9a45" + integrity sha512-PWP9FQ1AhZhS01T/4qLSKoHGY/xvkZdVBGlKM/HuxxS3+sC66HhTNR7+MpbO/so/cz/wY94MeSWJuP1hXIPfwQ== + dependencies: + babel-plugin-syntax-object-rest-spread "^6.13.0" + find-up "^2.1.0" + istanbul-lib-instrument "^1.10.1" + test-exclude "^4.2.1" + +babel-plugin-jest-hoist@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-23.2.0.tgz#e61fae05a1ca8801aadee57a6d66b8cefaf44167" + integrity sha1-5h+uBaHKiAGq3uV6bWa4zvr0QWc= + +"babel-plugin-styled-components@>= 1": + version "1.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.8.0.tgz#9dd054c8e86825203449a852a5746f29f2dab857" + integrity sha512-PcrdbXFO/9Plo9JURIj8G0Dsz+Ct8r+NvjoLh6qPt8Y/3EIAj1gHGW1ocPY1IkQbXZLBEZZSRBAxJem1KFdBXg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.0.0" + lodash "^4.17.10" + +babel-plugin-syntax-object-rest-spread@^6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + integrity sha1-/WU28rzhODb/o6VFjEkDpZe7O/U= + +babel-preset-jest@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-23.2.0.tgz#8ec7a03a138f001a1a8fb1e8113652bf1a55da46" + integrity sha1-jsegOhOPABoaj7HoETZSvxpV2kY= + dependencies: + babel-plugin-jest-hoist "^23.2.0" + babel-plugin-syntax-object-rest-spread "^6.13.0" + +babel-register@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + integrity sha1-btAhFz4vy0htestFxgCahW9kcHE= + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + +babel-runtime@^6.22.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.0.0, babel-traverse@^6.18.0, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.0.0, babel-types@^6.18.0, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -487,6 +790,13 @@ batch@0.6.1: resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + big.js@^3.1.3: version "3.2.0" resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" @@ -543,6 +853,15 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + braces@^2.3.0, braces@^2.3.1: version "2.3.2" resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" @@ -564,6 +883,18 @@ brorand@^1.0.1: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= +browser-process-hrtime@^0.1.2: + version "0.1.3" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz#616f00faef1df7ec1b5bf9cfe2bdc3170f26c7b4" + integrity sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw== + +browser-resolve@^1.11.3: + version "1.11.3" + resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6" + integrity sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ== + dependencies: + resolve "1.1.7" + browserify-aes@^1.0.0, browserify-aes@^1.0.4: version "1.2.0" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" @@ -632,7 +963,21 @@ browserslist@4.1.1: electron-to-chromium "^1.3.62" node-releases "^1.0.0-alpha.11" -buffer-from@^1.0.0: +bs-logger@0.x: + version "0.2.6" + resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" + integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== + dependencies: + fast-json-stable-stringify "2.x" + +bser@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.0.0.tgz#9ac78d3ed5d915804fd87acb158bc797147a1719" + integrity sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk= + dependencies: + node-int64 "^0.4.0" + +buffer-from@1.x, buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== @@ -749,6 +1094,18 @@ caniuse-lite@^1.0.30000884: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000907.tgz#0b9899bde53fb1c30e214fb12402361e02ff5c42" integrity sha512-No5sQ/OB2Nmka8MNOOM6nJx+Hxt6MQ6h7t7kgJFu9oTuwjykyKRSBP/+i/QAyFHxeHB+ddE0Da1CG5ihx9oehQ== +capture-exit@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-1.2.0.tgz#1c5fcc489fd0ab00d4f1ac7ae1072e3173fbab6f" + integrity sha1-HF/MSJ/QqwDU8ax64QcuMXP7q28= + dependencies: + rsvp "^3.3.3" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + chalk@2.4.1, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.3.1, chalk@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" @@ -865,6 +1222,11 @@ cliui@^4.0.0: strip-ansi "^4.0.0" wrap-ansi "^2.0.0" +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" @@ -890,6 +1252,13 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" + integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w== + dependencies: + delayed-stream "~1.0.0" + commander@^2.12.1, commander@^2.14.1, commander@^2.9.0: version "2.19.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" @@ -900,6 +1269,11 @@ commander@~2.13.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" integrity sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA== +commander@~2.17.1: + version "2.17.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" + integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -977,6 +1351,13 @@ content-type@~1.0.4: resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== +convert-source-map@^1.4.0, convert-source-map@^1.5.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" + integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== + dependencies: + safe-buffer "~5.1.1" + convert-tsconfig-paths-to-webpack-aliases@^0.9.2: version "0.9.2" resolved "https://registry.yarnpkg.com/convert-tsconfig-paths-to-webpack-aliases/-/convert-tsconfig-paths-to-webpack-aliases-0.9.2.tgz#55d67f86c7a506ab5d89d14580ae6e7c07f1aad0" @@ -1009,7 +1390,17 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= -core-util-is@~1.0.0: +core-js@^1.0.0: + version "1.2.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" + integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY= + +core-js@^2.4.0, core-js@^2.5.0: + version "2.5.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" + integrity sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw== + +core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= @@ -1066,6 +1457,15 @@ cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + crypto-browserify@^3.11.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" @@ -1083,6 +1483,32 @@ crypto-browserify@^3.11.0: randombytes "^2.0.0" randomfill "^1.0.3" +css-color-keywords@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05" + integrity sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU= + +css-to-react-native@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-2.2.2.tgz#c077d0f7bf3e6c915a539e7325821c9dd01f9965" + integrity sha512-w99Fzop1FO8XKm0VpbQp3y5mnTnaS+rtCvS+ylSEOK76YXO5zoHQx/QMB1N54Cp+Ya9jB9922EHrh14ld4xmmw== + dependencies: + css-color-keywords "^1.0.0" + fbjs "^0.8.5" + postcss-value-parser "^3.3.0" + +cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": + version "0.3.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.4.tgz#8cd52e8a3acfd68d3aed38ee0a640177d2f9d797" + integrity sha512-+7prCSORpXNeR4/fUP3rL+TzqtiFfhMvTd7uEqMdgPvLPt4+uzFUeufx5RHjGTACCargg/DiEt/moMQmvnfkog== + +cssstyle@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.1.1.tgz#18b038a9c44d65f7a8e428a653b9f6fe42faf5fb" + integrity sha512-364AI1l/M5TYcFH83JnOH/pSqgaNnKmYgKrm0didZMGKWjQB60dymwWy1rKUgL3J1ffdq9xVi2yGLHdSjjSNog== + dependencies: + cssom "0.3.x" + csstype@^2.2.0: version "2.5.7" resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.5.7.tgz#bf9235d5872141eccfb2d16d82993c6b149179ff" @@ -1093,6 +1519,22 @@ cyclist@~0.2.2: resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA= +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +data-urls@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" + integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== + dependencies: + abab "^2.0.0" + whatwg-mimetype "^2.2.0" + whatwg-url "^7.0.0" + date-fns@^1.27.2: version "1.29.0" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6" @@ -1103,7 +1545,7 @@ date-now@^0.1.4: resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= -debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.6, debug@^2.6.8: +debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.6, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -1131,6 +1573,11 @@ debug@^4.0.1: dependencies: ms "^2.1.1" +decamelize@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + decamelize@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-2.0.0.tgz#656d7bbc8094c4c788ea53c5840908c9c7d063c7" @@ -1158,6 +1605,11 @@ deep-extend@^0.6.0: resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + default-gateway@^2.6.0: version "2.7.2" resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-2.7.2.tgz#b7ef339e5e024b045467af403d50348db4642d0f" @@ -1166,6 +1618,13 @@ default-gateway@^2.6.0: execa "^0.10.0" ip-regex "^2.1.0" +default-require-extensions@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8" + integrity sha1-836hXT4T/9m0N9M+GnW1+5eHTLg= + dependencies: + strip-bom "^2.0.0" + define-properties@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" @@ -1207,6 +1666,11 @@ del@^3.0.0: pify "^3.0.0" rimraf "^2.2.8" +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" @@ -1230,11 +1694,23 @@ destroy@~1.0.4: resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg= + dependencies: + repeating "^2.0.0" + detect-libc@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= +detect-newline@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" + integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= + detect-node@^2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" @@ -1295,6 +1771,13 @@ domain-browser@^1.1.1: resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== +domexception@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" + integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== + dependencies: + webidl-conversions "^4.0.2" + duplexer@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" @@ -1310,6 +1793,14 @@ duplexify@^3.4.2, duplexify@^3.6.0: readable-stream "^2.0.0" stream-shift "^1.0.0" +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -1348,6 +1839,13 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= +encoding@^0.1.11: + version "0.1.12" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s= + dependencies: + iconv-lite "~0.4.13" + end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.1" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" @@ -1371,13 +1869,33 @@ errno@^0.1.3, errno@~0.1.7: dependencies: prr "~1.0.1" -error-ex@^1.3.1: +error-ex@^1.2.0, error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== dependencies: is-arrayish "^0.2.1" +es-abstract@^1.5.1: + version "1.12.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" + integrity sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA== + dependencies: + es-to-primitive "^1.1.1" + function-bind "^1.1.1" + has "^1.0.1" + is-callable "^1.1.3" + is-regex "^1.0.4" + +es-to-primitive@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" + integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -1388,6 +1906,18 @@ escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1 resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +escodegen@^1.9.1: + version "1.11.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.11.0.tgz#b27a9389481d5bfd5bec76f7bb1eb3f8f4556589" + integrity sha512-IeMV45ReixHS53K/OmfKAIztN/igDHzTJUhZM3k1jMhIZWjk45SMwAtBsEXiJp3vSPmTcu6CXn7mDvFHRN66fw== + dependencies: + esprima "^3.1.3" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + eslint-scope@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172" @@ -1396,6 +1926,11 @@ eslint-scope@^4.0.0: esrecurse "^4.1.0" estraverse "^4.1.1" +esprima@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= + esprima@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" @@ -1408,7 +1943,7 @@ esrecurse@^4.1.0: dependencies: estraverse "^4.1.0" -estraverse@^4.1.0, estraverse@^4.1.1: +estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= @@ -1455,6 +1990,13 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: md5.js "^1.3.4" safe-buffer "^5.1.1" +exec-sh@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.2.tgz#2a5e7ffcbd7d0ba2755bdecb16e5a427dfbdec36" + integrity sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw== + dependencies: + merge "^1.2.0" + execa@^0.10.0: version "0.10.0" resolved "https://registry.yarnpkg.com/execa/-/execa-0.10.0.tgz#ff456a8f53f90f8eccc71a96d11bdfc7f082cb50" @@ -1468,6 +2010,19 @@ execa@^0.10.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + execa@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" @@ -1486,6 +2041,18 @@ exit-hook@^1.0.0: resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" integrity sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g= +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= + dependencies: + is-posix-bracket "^0.1.0" + expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" @@ -1499,6 +2066,13 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= + dependencies: + fill-range "^2.1.0" + expand-tilde@^2.0.0, expand-tilde@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" @@ -1506,6 +2080,18 @@ expand-tilde@^2.0.0, expand-tilde@^2.0.2: dependencies: homedir-polyfill "^1.0.1" +expect@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-23.6.0.tgz#1e0c8d3ba9a581c87bd71fb9bc8862d443425f98" + integrity sha512-dgSoOHgmtn/aDGRVFWclQyPDKl2CQRq0hmIEoUAuQs/2rn2NcvCWcSCovm6BLeuB/7EZuLGu2QfnR+qRt5OM4w== + dependencies: + ansi-styles "^3.2.0" + jest-diff "^23.6.0" + jest-get-type "^22.1.0" + jest-matcher-utils "^23.6.0" + jest-message-util "^23.4.0" + jest-regex-util "^23.3.0" + express@^4.16.2: version "4.16.4" resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" @@ -1557,6 +2143,11 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + external-editor@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" @@ -1566,6 +2157,13 @@ external-editor@^3.0.0: iconv-lite "^0.4.24" tmp "^0.0.33" +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= + dependencies: + is-extglob "^1.0.0" + extglob@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" @@ -1580,6 +2178,16 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + fast-deep-equal@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" @@ -1597,11 +2205,16 @@ fast-glob@^2.0.2: merge2 "^1.2.3" micromatch "^3.1.10" -fast-json-stable-stringify@^2.0.0: +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + faye-websocket@^0.10.0: version "0.10.0" resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" @@ -1616,6 +2229,26 @@ faye-websocket@~0.11.0, faye-websocket@~0.11.1: dependencies: websocket-driver ">=0.5.1" +fb-watchman@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58" + integrity sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg= + dependencies: + bser "^2.0.0" + +fbjs@^0.8.5: + version "0.8.17" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd" + integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90= + dependencies: + core-js "^1.0.0" + isomorphic-fetch "^2.1.1" + loose-envify "^1.0.0" + object-assign "^4.1.0" + promise "^7.1.1" + setimmediate "^1.0.5" + ua-parser-js "^0.7.18" + figures@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" @@ -1631,11 +2264,35 @@ figures@^2.0.0: dependencies: escape-string-regexp "^1.0.5" +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= + +fileset@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0" + integrity sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA= + dependencies: + glob "^7.0.3" + minimatch "^3.0.3" + filesize@3.6.1: version "3.6.1" resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" integrity sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg== +fill-range@^2.1.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" + integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q== + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^3.0.0" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" @@ -1680,6 +2337,14 @@ find-up@3.0.0, find-up@^3.0.0: dependencies: locate-path "^3.0.0" +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" @@ -1702,11 +2367,23 @@ follow-redirects@^1.0.0: dependencies: debug "=3.1.0" -for-in@^1.0.2: +for-in@^1.0.1, for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= + dependencies: + for-in "^1.0.1" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + fork-ts-checker-webpack-plugin@^0.4.15: version "0.4.15" resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-0.4.15.tgz#7cd9f94f3dd58cd1fe8f953f876e72090eda3f6d" @@ -1721,6 +2398,15 @@ fork-ts-checker-webpack-plugin@^0.4.15: resolve "^1.5.0" tapable "^1.0.0" +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + forwarded@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" @@ -1775,7 +2461,7 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@^1.2.2: +fsevents@^1.2.2, fsevents@^1.2.3: version "1.2.4" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" integrity sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg== @@ -1843,6 +2529,28 @@ get-value@^2.0.3, get-value@^2.0.6: resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= + dependencies: + is-glob "^2.0.0" + glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" @@ -1893,6 +2601,11 @@ global-prefix@^1.0.1: is-windows "^1.0.1" which "^1.2.14" +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== + globby@8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/globby/-/globby-8.0.1.tgz#b5ad48b8aa80b35b814fc1281ecc851f1d2b5b50" @@ -1922,6 +2635,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== +growly@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" + integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= + gzip-size@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.0.0.tgz#a55ecd99222f4c48fd8c01c625ce3b349d0a0e80" @@ -1935,6 +2653,30 @@ handle-thing@^1.2.5: resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-1.2.5.tgz#fd7aad726bf1a5fd16dfc29b2f7a6601d27139c4" integrity sha1-/Xqtcmvxpf0W38KbL3pmAdJxOcQ= +handlebars@^4.0.3: + version "4.0.12" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5" + integrity sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA== + dependencies: + async "^2.5.0" + optimist "^0.6.1" + source-map "^0.6.1" + optionalDependencies: + uglify-js "^3.1.4" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.0: + version "5.1.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" + integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== + dependencies: + ajv "^6.5.5" + har-schema "^2.0.0" + has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" @@ -1942,6 +2684,11 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -1988,6 +2735,13 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" +has@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + hash-base@^3.0.0: version "3.0.4" resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" @@ -2018,6 +2772,14 @@ hmac-drbg@^1.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + integrity sha1-42w/LSyufXRqhX440Y1fMqeILbg= + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + homedir-polyfill@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc" @@ -2040,6 +2802,13 @@ hpack.js@^2.1.6: readable-stream "^2.0.1" wbuf "^1.1.0" +html-encoding-sniffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" + integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== + dependencies: + whatwg-encoding "^1.0.1" + html-entities@^1.2.0: version "1.2.1" resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" @@ -2084,6 +2853,15 @@ http-proxy@^1.16.2: follow-redirects "^1.0.0" requires-port "^1.0.0" +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" @@ -2112,7 +2890,7 @@ iconv-lite@0.4.23: dependencies: safer-buffer ">= 2.1.2 < 3" -iconv-lite@^0.4.24, iconv-lite@^0.4.4: +iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -2154,6 +2932,14 @@ import-fresh@^2.0.0: caller-path "^2.0.0" resolve-from "^3.0.0" +import-local@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" + integrity sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ== + dependencies: + pkg-dir "^2.0.0" + resolve-cwd "^2.0.0" + import-local@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" @@ -2232,6 +3018,18 @@ interpret@^1.1.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" integrity sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ= +invariant@^2.2.2, invariant@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= + invert-kv@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" @@ -2295,7 +3093,12 @@ is-builtin-module@^1.0.0: dependencies: builtin-modules "^1.0.0" -is-ci@^1.2.1: +is-callable@^1.1.3, is-callable@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" + integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== + +is-ci@^1.0.10, is-ci@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== @@ -2316,6 +3119,11 @@ is-data-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= + is-descriptor@^0.1.0: version "0.1.6" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" @@ -2339,6 +3147,18 @@ is-directory@^0.3.1: resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= + dependencies: + is-primitive "^2.0.0" + is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -2351,11 +3171,23 @@ is-extendable@^1.0.1: dependencies: is-plain-object "^2.0.4" +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= + is-extglob@^2.1.0, is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko= + dependencies: + number-is-nan "^1.0.0" + is-fullwidth-code-point@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" @@ -2368,6 +3200,18 @@ is-fullwidth-code-point@^2.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= +is-generator-fn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-1.0.0.tgz#969d49e1bb3329f6bb7f09089be26578b2ddd46a" + integrity sha1-lp1J4bszKfa7fwkIm+JleLLd1Go= + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= + dependencies: + is-extglob "^1.0.0" + is-glob@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" @@ -2382,6 +3226,13 @@ is-glob@^4.0.0: dependencies: is-extglob "^2.1.1" +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= + dependencies: + kind-of "^3.0.2" + is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -2389,6 +3240,11 @@ is-number@^3.0.0: dependencies: kind-of "^3.0.2" +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== + is-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" @@ -2427,11 +3283,28 @@ is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= + is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= + dependencies: + has "^1.0.1" + is-regexp@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" @@ -2442,11 +3315,28 @@ is-root@2.0.0: resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.0.0.tgz#838d1e82318144e5a6f77819d90207645acc7019" integrity sha512-F/pJIk8QD6OX5DNhRB7hWamLsUilmkDGho48KbgZ6xg/lmAZXHxzXQ91jzB3yRSw5kdQGGGc4yz8HYhTYIMWPg== -is-stream@^1.1.0: +is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= +is-symbol@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" + integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== + dependencies: + has-symbols "^1.0.0" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + is-windows@^1.0.1, is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -2479,12 +3369,373 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= +isomorphic-fetch@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" + integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk= + dependencies: + node-fetch "^1.0.1" + whatwg-fetch ">=0.10.0" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +istanbul-api@^1.3.1: + version "1.3.7" + resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.3.7.tgz#a86c770d2b03e11e3f778cd7aedd82d2722092aa" + integrity sha512-4/ApBnMVeEPG3EkSzcw25wDe4N66wxwn+KKn6b47vyek8Xb3NBAcg4xfuQbS7BqcZuTX4wxfD5lVagdggR3gyA== + dependencies: + async "^2.1.4" + fileset "^2.0.2" + istanbul-lib-coverage "^1.2.1" + istanbul-lib-hook "^1.2.2" + istanbul-lib-instrument "^1.10.2" + istanbul-lib-report "^1.1.5" + istanbul-lib-source-maps "^1.2.6" + istanbul-reports "^1.5.1" + js-yaml "^3.7.0" + mkdirp "^0.5.1" + once "^1.4.0" + +istanbul-lib-coverage@^1.2.0, istanbul-lib-coverage@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz#ccf7edcd0a0bb9b8f729feeb0930470f9af664f0" + integrity sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ== + +istanbul-lib-hook@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.2.2.tgz#bc6bf07f12a641fbf1c85391d0daa8f0aea6bf86" + integrity sha512-/Jmq7Y1VeHnZEQ3TL10VHyb564mn6VrQXHchON9Jf/AEcmQ3ZIiyD1BVzNOKTZf/G3gE+kiGK6SmpF9y3qGPLw== + dependencies: + append-transform "^0.4.0" + +istanbul-lib-instrument@^1.10.1, istanbul-lib-instrument@^1.10.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz#1f55ed10ac3c47f2bdddd5307935126754d0a9ca" + integrity sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A== + dependencies: + babel-generator "^6.18.0" + babel-template "^6.16.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + babylon "^6.18.0" + istanbul-lib-coverage "^1.2.1" + semver "^5.3.0" + +istanbul-lib-report@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.5.tgz#f2a657fc6282f96170aaf281eb30a458f7f4170c" + integrity sha512-UsYfRMoi6QO/doUshYNqcKJqVmFe9w51GZz8BS3WB0lYxAllQYklka2wP9+dGZeHYaWIdcXUx8JGdbqaoXRXzw== + dependencies: + istanbul-lib-coverage "^1.2.1" + mkdirp "^0.5.1" + path-parse "^1.0.5" + supports-color "^3.1.2" + +istanbul-lib-source-maps@^1.2.4, istanbul-lib-source-maps@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.6.tgz#37b9ff661580f8fca11232752ee42e08c6675d8f" + integrity sha512-TtbsY5GIHgbMsMiRw35YBHGpZ1DVFEO19vxxeiDMYaeOFOCzfnYVxvl6pOUIZR4dtPhAGpSMup8OyF8ubsaqEg== + dependencies: + debug "^3.1.0" + istanbul-lib-coverage "^1.2.1" + mkdirp "^0.5.1" + rimraf "^2.6.1" + source-map "^0.5.3" + +istanbul-reports@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.5.1.tgz#97e4dbf3b515e8c484caea15d6524eebd3ff4e1a" + integrity sha512-+cfoZ0UXzWjhAdzosCPP3AN8vvef8XDkWtTfgaN+7L3YTpNYITnCaEkceo5SEYy644VkHka/P1FvkWvrG/rrJw== + dependencies: + handlebars "^4.0.3" + +jest-changed-files@^23.4.2: + version "23.4.2" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-23.4.2.tgz#1eed688370cd5eebafe4ae93d34bb3b64968fe83" + integrity sha512-EyNhTAUWEfwnK0Is/09LxoqNDOn7mU7S3EHskG52djOFS/z+IT0jT3h3Ql61+dklcG7bJJitIWEMB4Sp1piHmA== + dependencies: + throat "^4.0.0" + +jest-cli@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-23.6.0.tgz#61ab917744338f443ef2baa282ddffdd658a5da4" + integrity sha512-hgeD1zRUp1E1zsiyOXjEn4LzRLWdJBV//ukAHGlx6s5mfCNJTbhbHjgxnDUXA8fsKWN/HqFFF6X5XcCwC/IvYQ== + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.1" + exit "^0.1.2" + glob "^7.1.2" + graceful-fs "^4.1.11" + import-local "^1.0.0" + is-ci "^1.0.10" + istanbul-api "^1.3.1" + istanbul-lib-coverage "^1.2.0" + istanbul-lib-instrument "^1.10.1" + istanbul-lib-source-maps "^1.2.4" + jest-changed-files "^23.4.2" + jest-config "^23.6.0" + jest-environment-jsdom "^23.4.0" + jest-get-type "^22.1.0" + jest-haste-map "^23.6.0" + jest-message-util "^23.4.0" + jest-regex-util "^23.3.0" + jest-resolve-dependencies "^23.6.0" + jest-runner "^23.6.0" + jest-runtime "^23.6.0" + jest-snapshot "^23.6.0" + jest-util "^23.4.0" + jest-validate "^23.6.0" + jest-watcher "^23.4.0" + jest-worker "^23.2.0" + micromatch "^2.3.11" + node-notifier "^5.2.1" + prompts "^0.1.9" + realpath-native "^1.0.0" + rimraf "^2.5.4" + slash "^1.0.0" + string-length "^2.0.0" + strip-ansi "^4.0.0" + which "^1.2.12" + yargs "^11.0.0" + +jest-config@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-23.6.0.tgz#f82546a90ade2d8c7026fbf6ac5207fc22f8eb1d" + integrity sha512-i8V7z9BeDXab1+VNo78WM0AtWpBRXJLnkT+lyT+Slx/cbP5sZJ0+NDuLcmBE5hXAoK0aUp7vI+MOxR+R4d8SRQ== + dependencies: + babel-core "^6.0.0" + babel-jest "^23.6.0" + chalk "^2.0.1" + glob "^7.1.1" + jest-environment-jsdom "^23.4.0" + jest-environment-node "^23.4.0" + jest-get-type "^22.1.0" + jest-jasmine2 "^23.6.0" + jest-regex-util "^23.3.0" + jest-resolve "^23.6.0" + jest-util "^23.4.0" + jest-validate "^23.6.0" + micromatch "^2.3.11" + pretty-format "^23.6.0" + +jest-diff@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-23.6.0.tgz#1500f3f16e850bb3d71233408089be099f610c7d" + integrity sha512-Gz9l5Ov+X3aL5L37IT+8hoCUsof1CVYBb2QEkOupK64XyRR3h+uRpYIm97K7sY8diFxowR8pIGEdyfMKTixo3g== + dependencies: + chalk "^2.0.1" + diff "^3.2.0" + jest-get-type "^22.1.0" + pretty-format "^23.6.0" + +jest-docblock@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-23.2.0.tgz#f085e1f18548d99fdd69b20207e6fd55d91383a7" + integrity sha1-8IXh8YVI2Z/dabICB+b9VdkTg6c= + dependencies: + detect-newline "^2.1.0" + +jest-each@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-23.6.0.tgz#ba0c3a82a8054387016139c733a05242d3d71575" + integrity sha512-x7V6M/WGJo6/kLoissORuvLIeAoyo2YqLOoCDkohgJ4XOXSqOtyvr8FbInlAWS77ojBsZrafbozWoKVRdtxFCg== + dependencies: + chalk "^2.0.1" + pretty-format "^23.6.0" + +jest-environment-jsdom@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-23.4.0.tgz#056a7952b3fea513ac62a140a2c368c79d9e6023" + integrity sha1-BWp5UrP+pROsYqFAosNox52eYCM= + dependencies: + jest-mock "^23.2.0" + jest-util "^23.4.0" + jsdom "^11.5.1" + +jest-environment-node@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-23.4.0.tgz#57e80ed0841dea303167cce8cd79521debafde10" + integrity sha1-V+gO0IQd6jAxZ8zozXlSHeuv3hA= + dependencies: + jest-mock "^23.2.0" + jest-util "^23.4.0" + jest-get-type@^22.1.0: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4" integrity sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w== -jest-validate@^23.5.0: +jest-haste-map@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-23.6.0.tgz#2e3eb997814ca696d62afdb3f2529f5bbc935e16" + integrity sha512-uyNhMyl6dr6HaXGHp8VF7cK6KpC6G9z9LiMNsst+rJIZ8l7wY0tk8qwjPmEghczojZ2/ZhtEdIabZ0OQRJSGGg== + dependencies: + fb-watchman "^2.0.0" + graceful-fs "^4.1.11" + invariant "^2.2.4" + jest-docblock "^23.2.0" + jest-serializer "^23.0.1" + jest-worker "^23.2.0" + micromatch "^2.3.11" + sane "^2.0.0" + +jest-jasmine2@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-23.6.0.tgz#840e937f848a6c8638df24360ab869cc718592e0" + integrity sha512-pe2Ytgs1nyCs8IvsEJRiRTPC0eVYd8L/dXJGU08GFuBwZ4sYH/lmFDdOL3ZmvJR8QKqV9MFuwlsAi/EWkFUbsQ== + dependencies: + babel-traverse "^6.0.0" + chalk "^2.0.1" + co "^4.6.0" + expect "^23.6.0" + is-generator-fn "^1.0.0" + jest-diff "^23.6.0" + jest-each "^23.6.0" + jest-matcher-utils "^23.6.0" + jest-message-util "^23.4.0" + jest-snapshot "^23.6.0" + jest-util "^23.4.0" + pretty-format "^23.6.0" + +jest-leak-detector@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-23.6.0.tgz#e4230fd42cf381a1a1971237ad56897de7e171de" + integrity sha512-f/8zA04rsl1Nzj10HIyEsXvYlMpMPcy0QkQilVZDFOaPbv2ur71X5u2+C4ZQJGyV/xvVXtCCZ3wQ99IgQxftCg== + dependencies: + pretty-format "^23.6.0" + +jest-matcher-utils@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-23.6.0.tgz#726bcea0c5294261a7417afb6da3186b4b8cac80" + integrity sha512-rosyCHQfBcol4NsckTn01cdelzWLU9Cq7aaigDf8VwwpIRvWE/9zLgX2bON+FkEW69/0UuYslUe22SOdEf2nog== + dependencies: + chalk "^2.0.1" + jest-get-type "^22.1.0" + pretty-format "^23.6.0" + +jest-message-util@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-23.4.0.tgz#17610c50942349508d01a3d1e0bda2c079086a9f" + integrity sha1-F2EMUJQjSVCNAaPR4L2iwHkIap8= + dependencies: + "@babel/code-frame" "^7.0.0-beta.35" + chalk "^2.0.1" + micromatch "^2.3.11" + slash "^1.0.0" + stack-utils "^1.0.1" + +jest-mock@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-23.2.0.tgz#ad1c60f29e8719d47c26e1138098b6d18b261134" + integrity sha1-rRxg8p6HGdR8JuETgJi20YsmETQ= + +jest-regex-util@^23.3.0: + version "23.3.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-23.3.0.tgz#5f86729547c2785c4002ceaa8f849fe8ca471bc5" + integrity sha1-X4ZylUfCeFxAAs6qj4Sf6MpHG8U= + +jest-resolve-dependencies@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-23.6.0.tgz#b4526af24c8540d9a3fab102c15081cf509b723d" + integrity sha512-EkQWkFWjGKwRtRyIwRwI6rtPAEyPWlUC2MpzHissYnzJeHcyCn1Hc8j7Nn1xUVrS5C6W5+ZL37XTem4D4pLZdA== + dependencies: + jest-regex-util "^23.3.0" + jest-snapshot "^23.6.0" + +jest-resolve@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-23.6.0.tgz#cf1d1a24ce7ee7b23d661c33ba2150f3aebfa0ae" + integrity sha512-XyoRxNtO7YGpQDmtQCmZjum1MljDqUCob7XlZ6jy9gsMugHdN2hY4+Acz9Qvjz2mSsOnPSH7skBmDYCHXVZqkA== + dependencies: + browser-resolve "^1.11.3" + chalk "^2.0.1" + realpath-native "^1.0.0" + +jest-runner@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-23.6.0.tgz#3894bd219ffc3f3cb94dc48a4170a2e6f23a5a38" + integrity sha512-kw0+uj710dzSJKU6ygri851CObtCD9cN8aNkg8jWJf4ewFyEa6kwmiH/r/M1Ec5IL/6VFa0wnAk6w+gzUtjJzA== + dependencies: + exit "^0.1.2" + graceful-fs "^4.1.11" + jest-config "^23.6.0" + jest-docblock "^23.2.0" + jest-haste-map "^23.6.0" + jest-jasmine2 "^23.6.0" + jest-leak-detector "^23.6.0" + jest-message-util "^23.4.0" + jest-runtime "^23.6.0" + jest-util "^23.4.0" + jest-worker "^23.2.0" + source-map-support "^0.5.6" + throat "^4.0.0" + +jest-runtime@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-23.6.0.tgz#059e58c8ab445917cd0e0d84ac2ba68de8f23082" + integrity sha512-ycnLTNPT2Gv+TRhnAYAQ0B3SryEXhhRj1kA6hBPSeZaNQkJ7GbZsxOLUkwg6YmvWGdX3BB3PYKFLDQCAE1zNOw== + dependencies: + babel-core "^6.0.0" + babel-plugin-istanbul "^4.1.6" + chalk "^2.0.1" + convert-source-map "^1.4.0" + exit "^0.1.2" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.1.11" + jest-config "^23.6.0" + jest-haste-map "^23.6.0" + jest-message-util "^23.4.0" + jest-regex-util "^23.3.0" + jest-resolve "^23.6.0" + jest-snapshot "^23.6.0" + jest-util "^23.4.0" + jest-validate "^23.6.0" + micromatch "^2.3.11" + realpath-native "^1.0.0" + slash "^1.0.0" + strip-bom "3.0.0" + write-file-atomic "^2.1.0" + yargs "^11.0.0" + +jest-serializer@^23.0.1: + version "23.0.1" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-23.0.1.tgz#a3776aeb311e90fe83fab9e533e85102bd164165" + integrity sha1-o3dq6zEekP6D+rnlM+hRAr0WQWU= + +jest-snapshot@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-23.6.0.tgz#f9c2625d1b18acda01ec2d2b826c0ce58a5aa17a" + integrity sha512-tM7/Bprftun6Cvj2Awh/ikS7zV3pVwjRYU2qNYS51VZHgaAMBs5l4o/69AiDHhQrj5+LA2Lq4VIvK7zYk/bswg== + dependencies: + babel-types "^6.0.0" + chalk "^2.0.1" + jest-diff "^23.6.0" + jest-matcher-utils "^23.6.0" + jest-message-util "^23.4.0" + jest-resolve "^23.6.0" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + pretty-format "^23.6.0" + semver "^5.5.0" + +jest-util@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-23.4.0.tgz#4d063cb927baf0a23831ff61bec2cbbf49793561" + integrity sha1-TQY8uSe68KI4Mf9hvsLLv0l5NWE= + dependencies: + callsites "^2.0.0" + chalk "^2.0.1" + graceful-fs "^4.1.11" + is-ci "^1.0.10" + jest-message-util "^23.4.0" + mkdirp "^0.5.1" + slash "^1.0.0" + source-map "^0.6.0" + +jest-validate@^23.5.0, jest-validate@^23.6.0: version "23.6.0" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-23.6.0.tgz#36761f99d1ed33fcd425b4e4c5595d62b6597474" integrity sha512-OFKapYxe72yz7agrDAWi8v2WL8GIfVqcbKRCLbRG9PAxtzF9b1SEDdTpytNDN12z2fJynoBwpMpvj2R39plI2A== @@ -2494,16 +3745,40 @@ jest-validate@^23.5.0: leven "^2.1.0" pretty-format "^23.6.0" -js-tokens@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" - integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= +jest-watcher@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-23.4.0.tgz#d2e28ce74f8dad6c6afc922b92cabef6ed05c91c" + integrity sha1-0uKM50+NrWxq/JIrksq+9u0FyRw= + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.1" + string-length "^2.0.0" + +jest-worker@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-23.2.0.tgz#faf706a8da36fae60eb26957257fa7b5d8ea02b9" + integrity sha1-+vcGqNo2+uYOsmlXJX+ntdjqArk= + dependencies: + merge-stream "^1.0.1" -js-tokens@^4.0.0: +jest@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-23.6.0.tgz#ad5835e923ebf6e19e7a1d7529a432edfee7813d" + integrity sha512-lWzcd+HSiqeuxyhG+EnZds6iO3Y3ZEnMrfZq/OTGvF/C+Z4fPMCdhWTGSAiO2Oym9rbEXfwddHhh6jqrTF3+Lw== + dependencies: + import-local "^1.0.0" + jest-cli "^23.6.0" + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= + js-yaml@^3.7.0, js-yaml@^3.9.0: version "3.12.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" @@ -2512,6 +3787,48 @@ js-yaml@^3.7.0, js-yaml@^3.9.0: argparse "^1.0.7" esprima "^4.0.0" +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +jsdom@^11.5.1: + version "11.12.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" + integrity sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw== + dependencies: + abab "^2.0.0" + acorn "^5.5.3" + acorn-globals "^4.1.0" + array-equal "^1.0.0" + cssom ">= 0.3.2 < 0.4.0" + cssstyle "^1.0.0" + data-urls "^1.0.0" + domexception "^1.0.1" + escodegen "^1.9.1" + html-encoding-sniffer "^1.0.2" + left-pad "^1.3.0" + nwsapi "^2.0.7" + parse5 "4.0.0" + pn "^1.1.0" + request "^2.87.0" + request-promise-native "^1.0.5" + sax "^1.2.4" + symbol-tree "^3.2.2" + tough-cookie "^2.3.4" + w3c-hr-time "^1.0.1" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.3" + whatwg-mimetype "^2.1.0" + whatwg-url "^6.4.1" + ws "^5.2.0" + xml-name-validator "^3.0.0" + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s= + json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" @@ -2522,12 +3839,29 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + json3@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" integrity sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE= -json5@^0.5.0: +json5@2.x: + version "2.1.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850" + integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ== + dependencies: + minimist "^1.2.0" + +json5@^0.5.0, json5@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= @@ -2537,6 +3871,16 @@ jsonify@~0.0.0: resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + killable@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" @@ -2566,6 +3910,18 @@ kind-of@^6.0.0, kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== +kleur@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-2.0.2.tgz#b704f4944d95e255d038f0cb05fb8a602c55a300" + integrity sha512-77XF9iTllATmG9lSlIv0qdQ2BQ/h9t0bJllHlbvsQ0zUWfU7Yi0S8L5JXzPZgkefIiajLmBJJ4BsMJmqcf7oxQ== + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= + dependencies: + invert-kv "^1.0.0" + lcid@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" @@ -2573,11 +3929,24 @@ lcid@^2.0.0: dependencies: invert-kv "^2.0.0" +left-pad@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" + integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA== + leven@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" integrity sha1-wuep93IJTe6dNCAq6KzORoeHVYA= +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + lint-staged@^8.0.4: version "8.0.4" resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-8.0.4.tgz#d3c909fcf7897152cdce2d6e42500cd9b5b41a0d" @@ -2652,6 +4021,17 @@ listr@^0.14.2: p-map "^1.1.1" rxjs "^6.1.0" +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + loader-runner@^2.3.0: version "2.3.1" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.1.tgz#026f12fe7c3115992896ac02ba022ba92971b979" @@ -2687,7 +4067,12 @@ lodash.debounce@^4.0.8: resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= -lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.5: +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= + +lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== @@ -2720,7 +4105,14 @@ loglevel@^1.4.1: resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa" integrity sha1-4PyVEztu8nbNyIh82vJKpvFW+Po= -lru-cache@^4.1.1: +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lru-cache@^4.0.1, lru-cache@^4.1.1: version "4.1.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" integrity sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA== @@ -2735,6 +4127,18 @@ make-dir@^1.0.0: dependencies: pify "^3.0.0" +make-error@1.x: + version "1.3.5" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8" + integrity sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g== + +makeerror@1.0.x: + version "1.0.11" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" + integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw= + dependencies: + tmpl "1.0.x" + map-age-cleaner@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" @@ -2761,6 +4165,11 @@ matcher@^1.0.0: dependencies: escape-string-regexp "^1.0.4" +math-random@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac" + integrity sha1-izqsWIuKZuSXXjzepn97sylgH6w= + md5.js@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" @@ -2775,6 +4184,13 @@ media-typer@0.3.0: resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= +mem@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y= + dependencies: + mimic-fn "^1.0.0" + mem@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/mem/-/mem-4.0.0.tgz#6437690d9471678f6cc83659c00cbafcd6b0cdaf" @@ -2784,6 +4200,11 @@ mem@^4.0.0: mimic-fn "^1.0.0" p-is-promise "^1.1.0" +memoize-one@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-4.0.3.tgz#cdfdd942853f1a1b4c71c5336b8c49da0bf0273c" + integrity sha512-QmpUu4KqDmX0plH4u+tf0riMc1KHE1+lw95cMrLlXQAFOx/xnBtwhZ52XJxd9X2O6kwKBqX32kmhbhlobD0cuw== + memory-fs@^0.4.0, memory-fs@~0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" @@ -2797,16 +4218,47 @@ merge-descriptors@1.0.1: resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= +merge-stream@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" + integrity sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE= + dependencies: + readable-stream "^2.0.1" + merge2@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA== +merge@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" + integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== + methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= +micromatch@^2.3.11: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8, micromatch@^3.1.9: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -2839,7 +4291,7 @@ miller-rabin@^4.0.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8" integrity sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg== -mime-types@~2.1.17, mime-types@~2.1.18: +mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.18, mime-types@~2.1.19: version "2.1.21" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96" integrity sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg== @@ -2871,7 +4323,7 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= -minimatch@3.0.4, minimatch@^3.0.4: +minimatch@3.0.4, minimatch@^3.0.3, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -2883,11 +4335,16 @@ minimist@0.0.8: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= -minimist@^1.2.0: +minimist@^1.1.1, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= + minipass@^2.2.1, minipass@^2.3.4: version "2.3.5" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" @@ -2927,7 +4384,7 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: +mkdirp@0.5.x, mkdirp@0.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= @@ -2996,6 +4453,11 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + needle@^2.2.1: version "2.2.4" resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" @@ -3020,11 +4482,24 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== +node-fetch@^1.0.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + node-forge@0.7.5: version "0.7.5" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df" integrity sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ== +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= + node-libs-browser@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.1.0.tgz#5f94263d404f6e44767d726901fff05478d600df" @@ -3054,6 +4529,16 @@ node-libs-browser@^2.0.0: util "^0.10.3" vm-browserify "0.0.4" +node-notifier@^5.2.1: + version "5.3.0" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.3.0.tgz#c77a4a7b84038733d5fb351aafd8a268bfe19a01" + integrity sha512-AhENzCSGZnZJgBARsUjnQ7DnZbzyP+HxlVXuD0xqAnvL8q+OqtSX7lGg9e8nHzwXkMMXNdVeqq4E2M3EUAqX6Q== + dependencies: + growly "^1.3.0" + semver "^5.5.0" + shellwords "^0.1.1" + which "^1.3.0" + node-pre-gyp@^0.10.0: version "0.10.3" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" @@ -3095,7 +4580,7 @@ normalize-package-data@^2.3.2: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" -normalize-path@^2.1.1: +normalize-path@^2.0.1, normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= @@ -3153,7 +4638,17 @@ number-is-nan@^1.0.0: resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= -object-assign@^4.0.1, object-assign@^4.1.0: +nwsapi@^2.0.7: + version "2.0.9" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.0.9.tgz#77ac0cdfdcad52b6a1151a84e73254edc33ed016" + integrity sha512-nlWFSCTYQcHk/6A9FFnfhKc14c3aFhfdNBXgo8Qgi9QTBu/qg3Ww+Uiz9wMzXd1T8GFxPc2QIHB6Qtf2XFryFQ== + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= @@ -3189,6 +4684,22 @@ object.assign@^4.0.1: has-symbols "^1.0.0" object-keys "^1.0.11" +object.getownpropertydescriptors@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" + integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY= + dependencies: + define-properties "^1.1.2" + es-abstract "^1.5.1" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" @@ -3239,6 +4750,26 @@ opn@5.4.0, opn@^5.1.0: dependencies: is-wsl "^1.1.0" +optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +optionator@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + original@>=0.0.5, original@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" @@ -3256,6 +4787,15 @@ os-homedir@^1.0.0: resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= +os-locale@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" + integrity sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA== + dependencies: + execa "^0.7.0" + lcid "^1.0.0" + mem "^1.1.0" + os-locale@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.0.1.tgz#3b014fbf01d87f60a1e5348d80fe870dc82c4620" @@ -3265,7 +4805,7 @@ os-locale@^3.0.0: lcid "^2.0.0" mem "^4.0.0" -os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= @@ -3361,6 +4901,23 @@ parse-asn1@^5.0.0: evp_bytestokey "^1.0.0" pbkdf2 "^3.0.3" +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + dependencies: + error-ex "^1.2.0" + parse-json@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" @@ -3374,6 +4931,11 @@ parse-passwd@^1.0.0: resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= +parse5@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" + integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA== + parseurl@~1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" @@ -3394,12 +4956,19 @@ path-dirname@^1.0.0: resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= + dependencies: + pinkie-promise "^2.0.0" + path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= -path-is-absolute@^1.0.0: +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= @@ -3424,6 +4993,15 @@ path-to-regexp@0.1.7: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + path-type@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" @@ -3442,6 +5020,11 @@ pbkdf2@^3.0.3: safe-buffer "^5.0.1" sha.js "^2.4.8" +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + pify@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -3492,10 +5075,15 @@ please-upgrade-node@^3.0.2, please-upgrade-node@^3.1.1: dependencies: semver-compare "^1.0.0" -popmotion@^8.5.2: - version "8.5.2" - resolved "https://registry.yarnpkg.com/popmotion/-/popmotion-8.5.2.tgz#5c271fc4370f2739970c3a04bc890b7dbc8e519e" - integrity sha512-RZxR8TlEJ4mLePKMyJnz+OczEq81Yb6eHohLzA05bczpytC9nC9Ak5i+CHAoHaXEpW4dGqs0oeLeURnU/DUVMQ== +pn@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" + integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== + +popmotion@8.5.3: + version "8.5.3" + resolved "https://registry.yarnpkg.com/popmotion/-/popmotion-8.5.3.tgz#693a197c7d724ce9999cc1b6410530360ac347cd" + integrity sha512-y6Fi/K1JvRFfvYn0BUPH7EUMYywvMwB5MocYwAPD2PkDwZ5D+L5ZidAQ9M/4nto9YU//2F2Q9xR6XztGnDfvyQ== dependencies: "@popmotion/easing" "^1.0.1" "@popmotion/popcorn" "^0.2.0" @@ -3519,6 +5107,21 @@ posix-character-classes@^0.1.0: resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= +postcss-value-parser@^3.3.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= + prettier@^1.15.2: version "1.15.2" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.15.2.tgz#d31abe22afa4351efa14c7f8b94b58bb7452205e" @@ -3532,6 +5135,11 @@ pretty-format@^23.6.0: ansi-regex "^3.0.0" ansi-styles "^3.2.0" +private@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== + process-nextick-args@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" @@ -3561,6 +5169,29 @@ promise-inflight@^1.0.1: resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= +promise@^7.1.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" + integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== + dependencies: + asap "~2.0.3" + +prompts@^0.1.9: + version "0.1.14" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-0.1.14.tgz#a8e15c612c5c9ec8f8111847df3337c9cbd443b2" + integrity sha512-rxkyiE9YH6zAz/rZpywySLKkpaj0NMVyNw1qhsubdbjjSgcayjTShDreZGlFMcGSu5sab3bAKPfFk78PB90+8w== + dependencies: + kleur "^2.0.1" + sisteransi "^0.1.1" + +prop-types@^15.5.4, prop-types@^15.6.2: + version "15.6.2" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102" + integrity sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ== + dependencies: + loose-envify "^1.3.1" + object-assign "^4.1.1" + proxy-addr@~2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" @@ -3579,6 +5210,11 @@ pseudomap@^1.0.2: resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= +psl@^1.1.24: + version "1.1.29" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67" + integrity sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ== + public-encrypt@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" @@ -3621,7 +5257,7 @@ punycode@1.3.2: resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= -punycode@^1.2.4: +punycode@^1.2.4, punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= @@ -3631,7 +5267,7 @@ punycode@^2.1.0: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -qs@6.5.2: +qs@6.5.2, qs@~6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== @@ -3651,6 +5287,15 @@ querystringify@^2.0.0: resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.0.tgz#7ded8dfbf7879dcc60d0a644ac6754b283ad17ef" integrity sha512-sluvZZ1YiTLD5jsqZcDmFyV2EwToyXZBfpoVOmktMmW+VEnhgakFHnasVph65fOjGPTWN0Nw3+XQaSeMayr0kg== +randomatic@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" + integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw== + dependencies: + is-number "^4.0.0" + kind-of "^6.0.0" + math-random "^1.0.1" + randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: version "2.0.6" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" @@ -3721,11 +5366,53 @@ react-dev-utils@^6.1.1: strip-ansi "4.0.0" text-table "0.2.0" +react-dom@^16.7.0-alpha.2: + version "16.7.0-alpha.2" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.7.0-alpha.2.tgz#16632880ed43676315991d8b412cce6975a30282" + integrity sha512-o0mMw8jBlwHjGZEy/vvKd/6giAX0+skREMOTs3/QHmgi+yAhUClp4My4Z9lsKy3SXV+03uPdm1l/QM7NTcGuMw== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + scheduler "^0.12.0-alpha.2" + react-error-overlay@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-5.1.0.tgz#c516995a5652e7bfbed8b497910d5280df74a7e8" integrity sha512-akMy/BQT5m1J3iJIHkSb4qycq2wzllWsmmolaaFVnb+LPV9cIJ/nTud40ZsiiT0H3P+/wXIdbjx2fzF61OaeOQ== +react-is@^16.6.0: + version "16.6.3" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.6.3.tgz#d2d7462fcfcbe6ec0da56ad69047e47e56e7eac0" + integrity sha512-u7FDWtthB4rWibG/+mFbVd5FvdI20yde86qKGx4lVUTWmPlSWQ4QxbBIrrs+HnXGbxOUlUzTAP/VDmvCwaP2yA== + +react@^16.7.0-alpha.2: + version "16.7.0-alpha.2" + resolved "https://registry.yarnpkg.com/react/-/react-16.7.0-alpha.2.tgz#924f2ae843a46ea82d104a8def7a599fbf2c78ce" + integrity sha512-Xh1CC8KkqIojhC+LFXd21jxlVtzoVYdGnQAi/I2+dxbmos9ghbx5TQf9/nDxc4WxaFfUQJkya0w1k6rMeyIaxQ== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + scheduler "^0.12.0-alpha.2" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + read-pkg@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-4.0.1.tgz#963625378f3e1c4d48c85872b5a6ec7d5d093237" @@ -3757,6 +5444,13 @@ readdirp@^2.0.0: micromatch "^3.1.10" readable-stream "^2.0.2" +realpath-native@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.0.2.tgz#cd51ce089b513b45cf9b1516c82989b51ccc6560" + integrity sha512-+S3zTvVt9yTntFrBpm7TQmQ3tzpCrnA1a/y+3cUHAc9ZR6aIjG0WNLR+Rj79QpJktY+VeW/TQtFlQ1bzsehI8g== + dependencies: + util.promisify "^1.0.0" + recursive-readdir@2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.2.tgz#9946fb3274e1628de6e36b2f6714953b4845094f" @@ -3764,6 +5458,18 @@ recursive-readdir@2.2.2: dependencies: minimatch "3.0.4" +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== + dependencies: + is-equal-shallow "^0.1.3" + regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" @@ -3782,11 +5488,60 @@ repeat-element@^1.1.2: resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== -repeat-string@^1.6.1: +repeat-string@^1.5.2, repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= + dependencies: + is-finite "^1.0.0" + +request-promise-core@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6" + integrity sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY= + dependencies: + lodash "^4.13.1" + +request-promise-native@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.5.tgz#5281770f68e0c9719e5163fd3fab482215f4fda5" + integrity sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU= + dependencies: + request-promise-core "1.1.1" + stealthy-require "^1.1.0" + tough-cookie ">=2.3.3" + +request@^2.87.0: + version "2.88.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" + integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.0" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.4.3" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -3827,6 +5582,11 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= +resolve@1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= + resolve@^1.3.2, resolve@^1.5.0: version "1.8.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" @@ -3870,6 +5630,11 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" +rsvp@^3.3.3: + version "3.6.2" + resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" + integrity sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw== + run-async@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" @@ -3908,16 +5673,40 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -"safer-buffer@>= 2.1.2 < 3": +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +sane@^2.0.0: + version "2.5.2" + resolved "https://registry.yarnpkg.com/sane/-/sane-2.5.2.tgz#b4dc1861c21b427e929507a3e751e2a2cb8ab3fa" + integrity sha1-tNwYYcIbQn6SlQej51HiosuKs/o= + dependencies: + anymatch "^2.0.0" + capture-exit "^1.2.0" + exec-sh "^0.2.0" + fb-watchman "^2.0.0" + micromatch "^3.1.4" + minimist "^1.1.1" + walker "~1.0.5" + watch "~0.18.0" + optionalDependencies: + fsevents "^1.2.3" + sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== +scheduler@^0.12.0-alpha.2: + version "0.12.0-alpha.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.12.0-alpha.2.tgz#2a8bc8dc6ecdb75fa6480ceeedc1f187c9539970" + integrity sha512-bfqFzGH18MjjhePIzYQNR0uGQ1wMCX6Q83c2s+3fzyuqKT6zBI2wNQTpq01q72C7QItAp8if5w2LfMiXnI2SYw== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + schema-utils@^0.4.2, schema-utils@^0.4.4, schema-utils@^0.4.5: version "0.4.7" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" @@ -3952,7 +5741,7 @@ semver-compare@^1.0.0: resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= -"semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.3.0, semver@^5.5.0: +"semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.3.0, semver@^5.5, semver@^5.5.0: version "5.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== @@ -4029,7 +5818,7 @@ set-value@^2.0.0: is-plain-object "^2.0.3" split-string "^3.0.1" -setimmediate@^1.0.4: +setimmediate@^1.0.4, setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= @@ -4069,6 +5858,11 @@ shell-quote@1.6.1: array-reduce "~0.0.0" jsonify "~0.0.0" +shellwords@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" + integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== + signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" @@ -4081,6 +5875,11 @@ simple-git@^1.85.0: dependencies: debug "^4.0.1" +sisteransi@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-0.1.1.tgz#5431447d5f7d1675aac667ccd0b865a4994cb3ce" + integrity sha512-PmGOd02bM9YO5ifxpw36nrNMBTptEtfRl4qUYl9SndkolplkrZZOW7PGHjrZL53QvMVj9nQ+TKqUnRsw4tJa4g== + slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" @@ -4174,17 +5973,32 @@ source-map-resolve@^0.5.0: source-map-url "^0.4.0" urix "^0.1.0" +source-map-support@^0.4.15: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== + dependencies: + source-map "^0.5.6" + +source-map-support@^0.5.6: + version "0.5.9" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f" + integrity sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map-url@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= -source-map@^0.5.6: +source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= -source-map@^0.6.1, source-map@~0.6.1: +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== @@ -4252,6 +6066,21 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= +sshpk@^1.7.0: + version "1.15.2" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.15.2.tgz#c946d6bd9b1a39d0e8635763f5242d6ed6dcb629" + integrity sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + ssri@^5.2.4: version "5.3.0" resolved "https://registry.yarnpkg.com/ssri/-/ssri-5.3.0.tgz#ba3872c9c6d33a0704a7d71ff045e5ec48999d06" @@ -4259,6 +6088,11 @@ ssri@^5.2.4: dependencies: safe-buffer "^5.1.1" +stack-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" + integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== + staged-git-files@1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-1.1.2.tgz#4326d33886dc9ecfa29a6193bf511ba90a46454b" @@ -4282,6 +6116,11 @@ statuses@~1.4.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== +stealthy-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= + stream-browserify@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" @@ -4319,6 +6158,14 @@ string-argv@^0.0.2: resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.0.2.tgz#dac30408690c21f3c3630a3ff3a05877bdcbd736" integrity sha1-2sMECGkMIfPDYwo/86BYd73L1zY= +string-length@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" + integrity sha1-1A27aGo6zpYMHP/KVivyxF+DY+0= + dependencies: + astral-regex "^1.0.0" + strip-ansi "^4.0.0" + string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -4366,6 +6213,18 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1: dependencies: ansi-regex "^2.0.0" +strip-bom@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" @@ -4381,6 +6240,22 @@ style-value-types@^3.0.6, style-value-types@^3.0.7: resolved "https://registry.yarnpkg.com/style-value-types/-/style-value-types-3.0.7.tgz#6e7a22cc8b1a4465193268ed66ad5f2a82579054" integrity sha512-7vzeicDiPNnJjvTYfJbQhZ7P3OCkXfvkJOJQ+ifFnXNTA/7KBxMZacHLvlRjM5/TtXbVdrZE6u+2nzSUSPrbSQ== +styled-components@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-4.1.1.tgz#943922048fae556e286bcbfdd29da4f1399446bc" + integrity sha512-UzT/qyoOyKpYooeLdwKrPHZ85R8KWl8i0fbyH9I3z6B2WT9uGDCV7J4kbfKsBeSWFD9EytBriEODOkybcUFD/Q== + dependencies: + "@emotion/is-prop-valid" "^0.6.8" + "@emotion/unitless" "^0.7.0" + babel-plugin-styled-components ">= 1" + css-to-react-native "^2.2.2" + memoize-one "^4.0.0" + prop-types "^15.5.4" + react-is "^16.6.0" + stylis "^3.5.0" + stylis-rule-sheet "^0.0.10" + supports-color "^5.5.0" + stylefire@^2.0.7: version "2.2.1" resolved "https://registry.yarnpkg.com/stylefire/-/stylefire-2.2.1.tgz#3ae1f74477fa5117d410757cefe5878179708e38" @@ -4400,11 +6275,28 @@ stylefire@^2.3.1: hey-listen "^1.0.4" style-value-types "^3.0.6" +stylis-rule-sheet@^0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz#44e64a2b076643f4b52e5ff71efc04d8c3c4a430" + integrity sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw== + +stylis@^3.5.0: + version "3.5.4" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.4.tgz#f665f25f5e299cf3d64654ab949a57c768b73fbe" + integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q== + supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= +supports-color@^3.1.2: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= + dependencies: + has-flag "^1.0.0" + supports-color@^5.1.0, supports-color@^5.3.0, supports-color@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -4417,6 +6309,11 @@ symbol-observable@^1.1.0: resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== +symbol-tree@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" + integrity sha1-rifbOPZgp64uHDt9G8KQgZuFGeY= + tapable@^1.0.0, tapable@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.0.tgz#0d076a172e3d9ba088fd2272b2668fb8d194b78c" @@ -4435,11 +6332,27 @@ tar@^4: safe-buffer "^5.1.2" yallist "^3.0.2" +test-exclude@^4.2.1: + version "4.2.3" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.3.tgz#a9a5e64474e4398339245a0a769ad7c2f4a97c20" + integrity sha512-SYbXgY64PT+4GAL2ocI3HwPa4Q4TBKm0cwAVeKOt/Aoc0gSpNRjJX8w0pA1LMKZ3LBmd8pYBqApFNQLII9kavA== + dependencies: + arrify "^1.0.1" + micromatch "^2.3.11" + object-assign "^4.1.0" + read-pkg-up "^1.0.1" + require-main-filename "^1.0.1" + text-table@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= +throat@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" + integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo= + through2@^2.0.0: version "2.0.5" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" @@ -4472,11 +6385,26 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" +tmpl@1.0.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" + integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= + to-arraybuffer@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + to-object-path@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" @@ -4502,6 +6430,40 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" +tough-cookie@>=2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" + integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== + dependencies: + psl "^1.1.24" + punycode "^1.4.1" + +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= + dependencies: + punycode "^2.1.0" + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= + +ts-jest@^23.10.4: + version "23.10.4" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-23.10.4.tgz#a7a953f55c9165bcaa90ff91014a178e87fe0df8" + integrity sha512-oV/wBwGUS7olSk/9yWMiSIJWbz5xO4zhftnY3gwv6s4SMg6WHF1m8XZNBvQOKQRiTAexZ9754Z13dxBq3Zgssw== + dependencies: + bs-logger "0.x" + buffer-from "1.x" + fast-json-stable-stringify "2.x" + json5 "2.x" + make-error "1.x" + mkdirp "0.x" + semver "^5.5" + yargs-parser "10.x" + ts-loader@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-5.3.0.tgz#4bac24e57bc5189391ab14987d9898ce53ef5cf7" @@ -4562,6 +6524,25 @@ tty-browserify@0.0.0: resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + type-is@~1.6.16: version "1.6.16" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" @@ -4580,6 +6561,11 @@ typescript@^3.1.6: resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.6.tgz#b6543a83cfc8c2befb3f4c8fba6896f5b0c9be68" integrity sha512-tDMYfVtvpb96msS1lDX9MEdHrW4yOuZ4Kdc4Him9oU796XldPYF/t2+uKoX0BBa0hXXwDlqYQbXY5Rzjzc5hBA== +ua-parser-js@^0.7.18: + version "0.7.19" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.19.tgz#94151be4c0a7fb1d001af7022fdaca4642659e4b" + integrity sha512-T3PVJ6uz8i0HzPxOF9SWzWAlfN/DavlpQqepn22xgve/5QecC+XMCAtmUNnY7C9StehaV6exjUCI801lOI7QlQ== + uglify-es@^3.3.4: version "3.3.9" resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677" @@ -4588,6 +6574,14 @@ uglify-es@^3.3.4: commander "~2.13.0" source-map "~0.6.1" +uglify-js@^3.1.4: + version "3.4.9" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.9.tgz#af02f180c1207d76432e473ed24a28f4a782bae3" + integrity sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q== + dependencies: + commander "~2.17.1" + source-map "~0.6.1" + uglifyjs-webpack-plugin@^1.2.4: version "1.3.0" resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.3.0.tgz#75f548160858163a08643e086d5fefe18a5d67de" @@ -4682,6 +6676,14 @@ util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= +util.promisify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + util@0.10.3: version "0.10.3" resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" @@ -4724,6 +6726,15 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + vm-browserify@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" @@ -4731,6 +6742,28 @@ vm-browserify@0.0.4: dependencies: indexof "0.0.1" +w3c-hr-time@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045" + integrity sha1-gqwr/2PZUOqeMYmlimViX+3xkEU= + dependencies: + browser-process-hrtime "^0.1.2" + +walker@~1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" + integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs= + dependencies: + makeerror "1.0.x" + +watch@~0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986" + integrity sha1-KAlUdsbffJDJYxOJkMClQj60uYY= + dependencies: + exec-sh "^0.2.0" + minimist "^1.2.0" + watchpack@^1.5.0: version "1.6.0" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" @@ -4747,6 +6780,11 @@ wbuf@^1.1.0, wbuf@^1.7.2: dependencies: minimalistic-assert "^1.0.0" +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + webpack-cli@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.1.2.tgz#17d7e01b77f89f884a2bbf9db545f0f6a648e746" @@ -4866,12 +6904,47 @@ websocket-extensions@>=0.1.1: resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg== +whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: + version "1.0.5" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" + integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== + dependencies: + iconv-lite "0.4.24" + +whatwg-fetch@>=0.10.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" + integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== + +whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.2.0.tgz#a3d58ef10b76009b042d03e25591ece89b88d171" + integrity sha512-5YSO1nMd5D1hY3WzAQV3PzZL83W3YeyR1yW9PcH26Weh1t+Vzh9B6XkDh7aXm83HBZ4nSMvkjvN2H2ySWIvBgw== + +whatwg-url@^6.4.1: + version "6.5.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8" + integrity sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +whatwg-url@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.0.0.tgz#fde926fa54a599f3adf82dff25a9f7be02dc6edd" + integrity sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@^1.2.10, which@^1.2.14, which@^1.2.9: +which@^1.2.10, which@^1.2.12, which@^1.2.14, which@^1.2.9, which@^1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -4885,6 +6958,16 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= + +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + worker-farm@^1.5.2: version "1.6.0" resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.6.0.tgz#aecc405976fab5a95526180846f0dba288f3a4a0" @@ -4913,6 +6996,27 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= +write-file-atomic@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" + integrity sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA== + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + +ws@^5.2.0: + version "5.2.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" + integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== + dependencies: + async-limiter "~1.0.0" + +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== + xregexp@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-4.0.0.tgz#e698189de49dd2a18cc5687b05e17c8e43943020" @@ -4923,6 +7027,11 @@ xtend@^4.0.0, xtend@~4.0.1: resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= + "y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" @@ -4938,13 +7047,20 @@ yallist@^3.0.0, yallist@^3.0.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" integrity sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k= -yargs-parser@^10.1.0: +yargs-parser@10.x, yargs-parser@^10.1.0: version "10.1.0" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== dependencies: camelcase "^4.1.0" +yargs-parser@^9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077" + integrity sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc= + dependencies: + camelcase "^4.1.0" + yargs@12.0.2, yargs@^12.0.2: version "12.0.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.2.tgz#fe58234369392af33ecbef53819171eff0f5aadc" @@ -4962,3 +7078,21 @@ yargs@12.0.2, yargs@^12.0.2: which-module "^2.0.0" y18n "^3.2.1 || ^4.0.0" yargs-parser "^10.1.0" + +yargs@^11.0.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77" + integrity sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A== + dependencies: + cliui "^4.0.0" + decamelize "^1.1.1" + find-up "^2.1.0" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^9.0.2" From e78df9acb883513fdfc615459cc112a6a5de876c Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Tue, 20 Nov 2018 11:59:53 +0000 Subject: [PATCH 08/44] update todos --- TODO.md | 9 ++++++++- dev/examples/{test.tsx => pose-as-array-prop.tsx} | 0 dev/examples/pose-as-hook.tsx | 9 +++++++++ dev/examples/pose-as-string-prop.tsx | 9 +++++++++ dev/examples/render-component.tsx | 9 +++++++++ dev/examples/render-element.tsx | 9 +++++++++ src/utils/__tests__/pose-resolvers.test.ts | 2 +- 7 files changed, 45 insertions(+), 2 deletions(-) rename dev/examples/{test.tsx => pose-as-array-prop.tsx} (100%) create mode 100644 dev/examples/pose-as-hook.tsx create mode 100644 dev/examples/pose-as-string-prop.tsx create mode 100644 dev/examples/render-component.tsx create mode 100644 dev/examples/render-element.tsx diff --git a/TODO.md b/TODO.md index de9038affa..718e3dd335 100644 --- a/TODO.md +++ b/TODO.md @@ -1 +1,8 @@ -- Add Rollup for production bundle generation (will save multiple kb) \ No newline at end of file +# TODOs + +## Build system +- Add Rollup for production bundle generation (will save multiple kb) + +## Features +- Coordination across children (ie `staggerChildren`) +- Gestures \ No newline at end of file diff --git a/dev/examples/test.tsx b/dev/examples/pose-as-array-prop.tsx similarity index 100% rename from dev/examples/test.tsx rename to dev/examples/pose-as-array-prop.tsx diff --git a/dev/examples/pose-as-hook.tsx b/dev/examples/pose-as-hook.tsx new file mode 100644 index 0000000000..4bcf91e4c0 --- /dev/null +++ b/dev/examples/pose-as-hook.tsx @@ -0,0 +1,9 @@ +import * as React from 'react'; +import { motion } from '@framer'; +import { Box } from '../styled'; + +const MotionBox = motion(Box)(); + +export const App = () => { + return ; +}; diff --git a/dev/examples/pose-as-string-prop.tsx b/dev/examples/pose-as-string-prop.tsx new file mode 100644 index 0000000000..4bcf91e4c0 --- /dev/null +++ b/dev/examples/pose-as-string-prop.tsx @@ -0,0 +1,9 @@ +import * as React from 'react'; +import { motion } from '@framer'; +import { Box } from '../styled'; + +const MotionBox = motion(Box)(); + +export const App = () => { + return ; +}; diff --git a/dev/examples/render-component.tsx b/dev/examples/render-component.tsx new file mode 100644 index 0000000000..4bcf91e4c0 --- /dev/null +++ b/dev/examples/render-component.tsx @@ -0,0 +1,9 @@ +import * as React from 'react'; +import { motion } from '@framer'; +import { Box } from '../styled'; + +const MotionBox = motion(Box)(); + +export const App = () => { + return ; +}; diff --git a/dev/examples/render-element.tsx b/dev/examples/render-element.tsx new file mode 100644 index 0000000000..4bcf91e4c0 --- /dev/null +++ b/dev/examples/render-element.tsx @@ -0,0 +1,9 @@ +import * as React from 'react'; +import { motion } from '@framer'; +import { Box } from '../styled'; + +const MotionBox = motion(Box)(); + +export const App = () => { + return ; +}; diff --git a/src/utils/__tests__/pose-resolvers.test.ts b/src/utils/__tests__/pose-resolvers.test.ts index 46e8ab3b5e..b9b8fea5ae 100644 --- a/src/utils/__tests__/pose-resolvers.test.ts +++ b/src/utils/__tests__/pose-resolvers.test.ts @@ -10,6 +10,6 @@ describe('poseToArray', () => { }); it('Should remove falsey poses', () => { - expect(poseToArray(undefined)).toEqual([]); + expect(poseToArray()).toEqual([]); }); }); From ad6dedaf4876efcd3c080c631cf49b434a9e095b Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Tue, 20 Nov 2018 15:09:44 +0000 Subject: [PATCH 09/44] adding default transition definitions --- TODO.md | 3 +- dev/examples/custom-transition.tsx | 23 ++++ dev/examples/pose-as-array-prop.tsx | 19 ++- dev/examples/pose-as-hook.tsx | 16 ++- dev/examples/pose-as-string-prop.tsx | 16 ++- dev/examples/pose-default-override.tsx | 12 ++ dev/examples/pose-default.tsx | 11 ++ dev/examples/render-component.tsx | 2 +- dev/examples/render-element.tsx | 9 +- dev/inc/use-interval.ts | 8 ++ src/hooks/use-config.ts | 12 +- src/hooks/use-pose-resolver.ts | 40 +----- src/hooks/use-pose.ts | 13 +- src/hooks/use-posed-values.ts | 10 +- src/hooks/use-style-attr.ts | 6 +- src/motion/component.ts | 7 +- src/motion/types.ts | 165 ++++++++++++++++++++++--- src/utils/transitions.ts | 87 +++++++++++++ 18 files changed, 372 insertions(+), 87 deletions(-) create mode 100644 dev/examples/custom-transition.tsx create mode 100644 dev/examples/pose-default-override.tsx create mode 100644 dev/examples/pose-default.tsx create mode 100644 dev/inc/use-interval.ts create mode 100644 src/utils/transitions.ts diff --git a/TODO.md b/TODO.md index 718e3dd335..d1c69e2813 100644 --- a/TODO.md +++ b/TODO.md @@ -5,4 +5,5 @@ ## Features - Coordination across children (ie `staggerChildren`) -- Gestures \ No newline at end of file +- Gestures +- `setPose.cycle` \ No newline at end of file diff --git a/dev/examples/custom-transition.tsx b/dev/examples/custom-transition.tsx new file mode 100644 index 0000000000..1822a4f5d9 --- /dev/null +++ b/dev/examples/custom-transition.tsx @@ -0,0 +1,23 @@ +import * as React from 'react'; +import { motion, usePose } from '@framer'; +import { Box } from '../styled'; +import useInterval from '../inc/use-interval'; + +const MotionBox = motion(Box)({ + ping: { + x: 100, + y: '0vh', + transition: { duration: 23000 } + }, + pong: { x: -100, y: '20vh' } +}); + +export const App = () => { + const [pose, setPose] = usePose('ping'); + + useInterval(() => { + setPose(pose.get() === 'ping' ? 'pong' : 'ping'); + }, 1000); + + return ; +}; diff --git a/dev/examples/pose-as-array-prop.tsx b/dev/examples/pose-as-array-prop.tsx index 4bcf91e4c0..d6c8455306 100644 --- a/dev/examples/pose-as-array-prop.tsx +++ b/dev/examples/pose-as-array-prop.tsx @@ -1,9 +1,24 @@ import * as React from 'react'; import { motion } from '@framer'; import { Box } from '../styled'; +import useInterval from '../inc/use-interval'; -const MotionBox = motion(Box)(); +const MotionBox = motion(Box)({ + a: { scale: 2 }, + b: { scale: 0.5 }, + c: { background: '#00f' } +}); export const App = () => { - return ; + const [pose, setPose] = React.useState('a'); + + useInterval( + () => { + setPose(pose === 'a' ? 'b' : 'a'); + }, + 1000, + [pose] + ); + + return ; }; diff --git a/dev/examples/pose-as-hook.tsx b/dev/examples/pose-as-hook.tsx index 4bcf91e4c0..1d6869ed37 100644 --- a/dev/examples/pose-as-hook.tsx +++ b/dev/examples/pose-as-hook.tsx @@ -1,9 +1,19 @@ import * as React from 'react'; -import { motion } from '@framer'; +import { motion, usePose } from '@framer'; import { Box } from '../styled'; +import useInterval from '../inc/use-interval'; -const MotionBox = motion(Box)(); +const MotionBox = motion(Box)({ + ping: { x: 100 }, + pong: { x: -100 } +}); export const App = () => { - return ; + const [pose, setPose] = usePose('ping'); + + useInterval(() => { + setPose(pose.get() === 'ping' ? 'pong' : 'ping'); + }, 1000); + + return ; }; diff --git a/dev/examples/pose-as-string-prop.tsx b/dev/examples/pose-as-string-prop.tsx index 4bcf91e4c0..58d4e5e16f 100644 --- a/dev/examples/pose-as-string-prop.tsx +++ b/dev/examples/pose-as-string-prop.tsx @@ -1,9 +1,21 @@ import * as React from 'react'; +import { useState } from 'react'; import { motion } from '@framer'; import { Box } from '../styled'; -const MotionBox = motion(Box)(); +const MotionBox = motion(Box)({ + default: { scale: 1 }, + pressed: { scale: 1.2 } +}); export const App = () => { - return ; + const [pose, setPose] = useState('default'); + + return ( + setPose('pressed')} + onMouseUp={() => setPose('default')} + /> + ); }; diff --git a/dev/examples/pose-default-override.tsx b/dev/examples/pose-default-override.tsx new file mode 100644 index 0000000000..47a77c1ca1 --- /dev/null +++ b/dev/examples/pose-default-override.tsx @@ -0,0 +1,12 @@ +import * as React from 'react'; +import { motion } from '@framer'; +import { Box } from '../styled'; + +const MotionBox = motion(Box)({ + default: { rotate: 0, backgroundColor: '#f00' }, + foo: { rotate: 45, backgroundColor: '#0f0' } +}); + +export const App = () => { + return ; +}; diff --git a/dev/examples/pose-default.tsx b/dev/examples/pose-default.tsx new file mode 100644 index 0000000000..dd6d387ad6 --- /dev/null +++ b/dev/examples/pose-default.tsx @@ -0,0 +1,11 @@ +import * as React from 'react'; +import { motion } from '@framer'; +import { Box } from '../styled'; + +const MotionBox = motion(Box)({ + default: { scale: 2, backgroundColor: '#f00' } +}); + +export const App = () => { + return ; +}; diff --git a/dev/examples/render-component.tsx b/dev/examples/render-component.tsx index 4bcf91e4c0..19b79c0b87 100644 --- a/dev/examples/render-component.tsx +++ b/dev/examples/render-component.tsx @@ -5,5 +5,5 @@ import { Box } from '../styled'; const MotionBox = motion(Box)(); export const App = () => { - return ; + return ; }; diff --git a/dev/examples/render-element.tsx b/dev/examples/render-element.tsx index 4bcf91e4c0..63781e7fa4 100644 --- a/dev/examples/render-element.tsx +++ b/dev/examples/render-element.tsx @@ -1,9 +1,12 @@ import * as React from 'react'; import { motion } from '@framer'; -import { Box } from '../styled'; -const MotionBox = motion(Box)(); +const MotionBox = motion.ul(); export const App = () => { - return ; + return ( + + ); }; diff --git a/dev/inc/use-interval.ts b/dev/inc/use-interval.ts new file mode 100644 index 0000000000..d2c6deaf62 --- /dev/null +++ b/dev/inc/use-interval.ts @@ -0,0 +1,8 @@ +import { useEffect } from 'react'; + +export default (callback: () => void, interval: number = 1000, args = []) => { + useEffect(() => { + const int = setInterval(callback, interval); + return () => clearInterval(int); + }, args); +}; diff --git a/src/hooks/use-config.ts b/src/hooks/use-config.ts index 805b075b0e..81ae38436a 100644 --- a/src/hooks/use-config.ts +++ b/src/hooks/use-config.ts @@ -1,16 +1,12 @@ import { useMemo } from 'react'; -import { - MotionConfig, - MotionConfigFactory, - MotionProps -} from '../motion/types'; +import { PoseConfig, PoseConfigFactory, MotionProps } from '../motion/types'; const isResolver = ( - config: MotionConfig | MotionConfigFactory -): config is MotionConfigFactory => typeof config === 'function'; + config: PoseConfig | PoseConfigFactory +): config is PoseConfigFactory => typeof config === 'function'; const useConfig = ( - baseConfig: MotionConfig | MotionConfigFactory, + baseConfig: PoseConfig | PoseConfigFactory, props: MotionProps ) => useMemo(() => (isResolver(baseConfig) ? baseConfig(props) : baseConfig), []); diff --git a/src/hooks/use-pose-resolver.ts b/src/hooks/use-pose-resolver.ts index ba73c7a805..55da384178 100644 --- a/src/hooks/use-pose-resolver.ts +++ b/src/hooks/use-pose-resolver.ts @@ -1,47 +1,15 @@ import { useRef, useEffect, MutableRefObject } from 'react'; import { invariant } from 'hey-listen'; -import { tween, spring, keyframes, decay, physics } from 'popmotion'; +import getTransition from '../utils/transitions'; import { poseToArray } from '../utils/pose-resolvers'; import { MotionValue } from '../motion-value'; -import { - MotionConfig, - MotionProps, - PoseResolver, - Pose, - Transition, - TransitionMap -} from '../motion/types'; +import { PoseConfig, MotionProps, PoseResolver, Pose } from '../motion/types'; type PoseSubscriber = (v: string | string[]) => void; -const transitions = { tween, spring, keyframes, decay, physics }; - -const defaultTransition = { - type: 'spring', - stiffness: 800, - damping: 15 -}; - -const getTransition = ( - valueKey: string, - to: string | number, - transition?: Transition -) => { - const transitionDefinition = transition - ? transition[valueKey] || - (transition as TransitionMap).default || - transition - : defaultTransition; - - const action = transitions[transitionDefinition.type || 'tween']; - const opts = { ...transitionDefinition, to }; - - return [action, opts]; -}; - const createPoseResolver = ( values: Map, - config: MotionConfig, + config: PoseConfig, props: MotionProps ) => (poseList: string[]) => { poseList.forEach(poseKey => { @@ -79,7 +47,7 @@ const createPoseResolver = ( const usePoseResolver = ( values: Map, - config: MotionConfig, + config: PoseConfig, props: MotionProps ) => { const poseSubscriber: MutableRefObject = useRef(null); diff --git a/src/hooks/use-pose.ts b/src/hooks/use-pose.ts index 1230d965d0..94a59e9d59 100644 --- a/src/hooks/use-pose.ts +++ b/src/hooks/use-pose.ts @@ -1,14 +1,13 @@ import { useMemo } from 'react'; -import motionValue from '../motion-value'; -import { poseToArray } from '../utils/pose-resolvers'; +import motionValue, { MotionValue } from '../motion-value'; + +type PoseSetter = (pose: string | string[]) => void; const usePose = (initPose = 'default') => { - return useMemo(() => { - const pose = motionValue(initPose, { - transformer: (v: string | string[]) => poseToArray(v) - }); + return useMemo((): [MotionValue, PoseSetter] => { + const pose = motionValue(initPose); - const setPose = (newPose: string | string[]) => pose.set(newPose); + const setPose: PoseSetter = newPose => pose.set(newPose); return [pose, setPose]; }, []); diff --git a/src/hooks/use-posed-values.ts b/src/hooks/use-posed-values.ts index d104cfb861..3ee62a2712 100644 --- a/src/hooks/use-posed-values.ts +++ b/src/hooks/use-posed-values.ts @@ -1,11 +1,12 @@ import motionValue, { MotionValue } from '../motion-value'; import { resolvePoses } from '../utils/pose-resolvers'; -import { MotionConfig, MotionProps } from '../motion/types'; +import { PoseConfig, MotionProps } from '../motion/types'; import { useRef, useEffect, RefObject } from 'react'; import styler from 'stylefire'; +import { invariant } from 'hey-listen'; export default ( - config: MotionConfig, + config: PoseConfig, props: MotionProps, ref: RefObject ): [Map, Partial] => { @@ -48,6 +49,11 @@ export default ( // 3. Bind stylers when ref is ready useEffect(() => { + invariant( + ref.current !== null, + 'No DOM reference found. Ensure custom components use `forwardRef` to forward the `ref` property to the host DOM component.' + ); + if (!ref.current) return; const domStyler = styler(ref.current); diff --git a/src/hooks/use-style-attr.ts b/src/hooks/use-style-attr.ts index 60f1e11875..de673d0a15 100644 --- a/src/hooks/use-style-attr.ts +++ b/src/hooks/use-style-attr.ts @@ -7,10 +7,8 @@ export default ( styles?: CSSProperties ): CSSProperties => useMemo(() => { - const resolvedValues = Object.keys(values).reduce((acc, key) => { - acc[key] = values[key].get(); - return acc; - }, {}); + const resolvedValues = {}; + values.forEach((value, key) => (resolvedValues[key] = value.get())); return { ...styles, diff --git a/src/motion/component.ts b/src/motion/component.ts index 933b3eac20..6b2a9ef44f 100644 --- a/src/motion/component.ts +++ b/src/motion/component.ts @@ -4,7 +4,6 @@ import { createElement, Ref, ComponentType, - createRef, HTMLProps, SVGProps } from 'react'; @@ -17,11 +16,11 @@ import useStyleAttr from '../hooks/use-style-attr'; const createMotionComponent = ( Component: string | ComponentType -): ComponentFactory => (motionConfig = {}) => { +): ComponentFactory => (PoseConfig = {}) => { const MotionComponent = forwardRef( (props: MotionProps, externalRef?: Ref) => { const ref = useExternalRef(externalRef); - const config = useConfig(motionConfig, props); + const config = useConfig(PoseConfig, props); // Create motion values const [values, componentProps] = usePosedValues(config, props, ref); @@ -32,7 +31,7 @@ const createMotionComponent = ( return createElement | SVGProps & MotionProps>( Component, { - ref: createRef(), + ref, ...componentProps, style: useStyleAttr(values, props.style) } diff --git a/src/motion/types.ts b/src/motion/types.ts index 9ba2b66943..95b1aa968f 100644 --- a/src/motion/types.ts +++ b/src/motion/types.ts @@ -1,10 +1,8 @@ import { MotionValue } from '../motion-value'; import { RefObject, CSSProperties, ComponentType } from 'react'; -export type MotionConfigFactory = (props: MotionProps) => MotionConfig; - export type ComponentFactory = ( - config?: MotionConfigFactory | MotionConfig + config?: PoseConfigFactory | PoseConfig ) => ComponentType; export type Motion = { @@ -12,7 +10,9 @@ export type Motion = { [key: string]: ComponentFactory; }; -export type MotionConfig = { +export type PoseConfigFactory = (props: MotionProps) => PoseConfig; + +export type PoseConfig = { [key: string]: Pose | PoseResolver; }; @@ -23,15 +23,80 @@ export type MotionProps = { style: CSSProperties; }; -export type Tween = {}; +export type EasingFunction = (v: number) => number; + +export type Easing = + | CubicBezier + | 'linear' + | 'easeIn' + | 'easeOut' + | 'easeInOut' + | 'circIn' + | 'circOut' + | 'circInOut' + | 'backIn' + | 'backOut' + | 'backInOut' + | 'anticipate' + | EasingFunction; + +export type Tween = { + type?: 'tween'; + from?: number | string; + to?: number | string; + duration?: number; + ease?: Easing; + elapsed?: number; + loop?: number; + flip?: number; + yoyo?: number; +}; -export type Spring = {}; +export type Spring = { + type: 'spring'; + from?: number | string; + to?: number | string; + stiffness?: number; + damping?: number; + mass?: number; + velocity?: number; + restSpeed?: number; + restDelta?: number; +}; -export type Decay = {}; +export type Decay = { + type: 'decay'; + velocity?: number; + from?: number | string; + modifyTarget?: (v: number) => number; + power?: number; + timeConstant?: number; + restDelta?: number; +}; -export type Keyframes = {}; +export type CubicBezier = [number, number, number, number]; + +export type Keyframes = { + type: 'keyframes'; + values: number[] | string[]; + easings?: Easing[]; + easeAll?: Easing; + elapsed?: number; + duration?: number; + loop?: number; + flip?: number; + yoyo?: number; +}; -export type Physics = {}; +export type Physics = { + type: 'physics'; + from?: number | string; + acceleration?: number; + friction?: number; + velocity?: number; + restSpeed?: number | false; + to?: number | string; +}; export type Transition = Tween | Spring | Decay | Keyframes | Physics; @@ -39,14 +104,86 @@ export type TransitionMap = { [key: string]: Transition }; export type TransitionDefinition = Transition | TransitionMap; -export type PoseSettings = { +// Framer Motion accepts any value, not just those listed below. +// Add more here as found. +export type Pose = { + // Transforms + x?: number | string; + y?: number | string; + z?: number | string; + rotate?: number | string; + rotateX?: number | string; + rotateY?: number | string; + rotateZ?: number | string; + scale?: number | string; + scaleX?: number | string; + scaleY?: number | string; + scaleZ?: number | string; + skew?: number | string; + skewX?: number | string; + skewY?: number | string; + originX?: number | string; + originY?: number | string; + originZ?: number | string; + opacity?: number; + perspective?: number | string; + transform?: string; + + // Positioning + width?: number | string; + height?: number | string; + maxWidth?: number | string; + maxHeight?: number | string; + top?: number | string; + left?: number | string; + right?: number | string; + bottom?: number | string; + + // Spacing + padding?: number | string; + paddingTop?: number | string; + paddingRight?: number | string; + paddingBottom?: number | string; + paddingLeft?: number | string; + margin?: number | string; + marginTop?: number | string; + marginRight?: number | string; + marginBottom?: number | string; + marginLeft?: number | string; + + // Borders + borderColor?: number | string; + borderTopColor?: number | string; + borderRightColor?: number | string; + borderBottomColor?: number | string; + borderLeftColor?: number | string; + borderWidth?: number | string; + borderTopWidth?: number | string; + borderRightWidth?: number | string; + borderBottomWidth?: number | string; + borderLeftWidth?: number | string; + borderRadius?: number | string; + borderTopLeftRadius?: number | string; + borderTopRightRadius?: number | string; + borderBottomRightRadius?: number | string; + borderBottomLeftRadius?: number | string; + + // Colors + color?: string; + backgroundColor?: string; + outlineColor?: string; + fill?: string; + stroke?: string; + + // SVG + d?: string; + pathLength?: number; + pathSpacing?: number; + + // Options transition?: TransitionDefinition; staggerDirection?: number; staggerChildren?: number; }; -export type Pose = PoseSettings & { - [key: string]: number | string; -}; - export type PoseResolver = (props: { [key: string]: any }) => Pose; diff --git a/src/utils/transitions.ts b/src/utils/transitions.ts new file mode 100644 index 0000000000..7a0950a9f0 --- /dev/null +++ b/src/utils/transitions.ts @@ -0,0 +1,87 @@ +import { tween, spring, keyframes, decay, physics, easing } from 'popmotion'; +import { Transition, TransitionMap, Tween } from '../motion/types'; +import { invariant } from 'hey-listen'; + +const transitions = { tween, spring, keyframes, decay, physics }; + +const defaultTransition = { + type: 'spring', + stiffness: 800, + damping: 15 +}; + +const { + linear, + easeIn, + easeOut, + easeInOut, + circIn, + circOut, + circInOut, + backIn, + backOut, + backInOut, + anticipate +} = easing; + +const easingLookup: { [key: string]: (num: number) => number } = { + linear, + easeIn, + easeOut, + easeInOut, + circIn, + circOut, + circInOut, + backIn, + backOut, + backInOut, + anticipate +}; + +const transitionOptionParser = { + tween: (opts: Tween) => { + const { ease } = opts; + + if (Array.isArray(ease)) { + // If cubic bezier definition, create bezier curve + invariant( + ease.length === 4, + `Cubic bezier arrays must contain four numerical values.` + ); + + const [x1, y1, x2, y2] = ease; + opts.ease = easing.cubicBezier(x1, y1, x2, y2); + } else if (typeof ease === 'string') { + // Else lookup from table + invariant( + easingLookup[ease] !== undefined, + `Invalid easing type '${ease}'` + ); + opts.ease = easingLookup[ease]; + } + } +}; + +const preprocessOptions = ( + type: string, + opts: Partial +): Partial => + transitionOptionParser[type] ? transitionOptionParser[type](opts) : opts; + +export default ( + valueKey: string, + to: string | number, + transition?: Transition +) => { + const transitionDefinition = transition + ? transition[valueKey] || + (transition as TransitionMap).default || + transition + : defaultTransition; + + const type = transitionDefinition.type || 'tween'; + const action = transitions[type]; + const opts = preprocessOptions(type, { ...transitionDefinition, to }); + + return [action, opts]; +}; From 90a8b0281b727273ae500ac4cb2be4166eb959e5 Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Tue, 20 Nov 2018 16:10:08 +0000 Subject: [PATCH 10/44] passing current and velocity to dynamic poses --- TODO.md | 3 +++ dev/examples/dynamic-pose.tsx | 23 +++++++++++++++++++++ src/hooks/use-pose-resolver.ts | 7 ++++++- src/hooks/use-posed-values.ts | 2 +- src/hooks/use-style-attr.ts | 15 +++++++------- src/motion/types.ts | 37 ++++++++++++++++++---------------- src/utils/resolve-values.ts | 16 +++++++++++++++ src/utils/transitions.ts | 9 ++++++--- 8 files changed, 82 insertions(+), 30 deletions(-) create mode 100644 dev/examples/dynamic-pose.tsx create mode 100644 src/utils/resolve-values.ts diff --git a/TODO.md b/TODO.md index d1c69e2813..709ee3405a 100644 --- a/TODO.md +++ b/TODO.md @@ -4,6 +4,9 @@ - Add Rollup for production bundle generation (will save multiple kb) ## Features +- Fix prop types on `motion` +- Add intelligent defaults +- Add velocity tracking - Coordination across children (ie `staggerChildren`) - Gestures - `setPose.cycle` \ No newline at end of file diff --git a/dev/examples/dynamic-pose.tsx b/dev/examples/dynamic-pose.tsx new file mode 100644 index 0000000000..10e9a14844 --- /dev/null +++ b/dev/examples/dynamic-pose.tsx @@ -0,0 +1,23 @@ +import * as React from 'react'; +import { motion, usePose } from '@framer'; +import { Box } from '../styled'; +import useInterval from '../inc/use-interval'; + +const MotionBox = motion(Box)({ + ping: { + x: 100, + y: '0vh', + transition: { duration: 100 } + }, + pong: ({ target }) => ({ x: target, y: '0vh' }) +}); + +export const App = () => { + const [pose, setPose] = usePose('ping'); + + useInterval(() => { + setPose(pose.get() === 'ping' ? 'pong' : 'ping'); + }, 1000); + + return ; +}; diff --git a/src/hooks/use-pose-resolver.ts b/src/hooks/use-pose-resolver.ts index 55da384178..ba58709dd2 100644 --- a/src/hooks/use-pose-resolver.ts +++ b/src/hooks/use-pose-resolver.ts @@ -2,6 +2,7 @@ import { useRef, useEffect, MutableRefObject } from 'react'; import { invariant } from 'hey-listen'; import getTransition from '../utils/transitions'; import { poseToArray } from '../utils/pose-resolvers'; +import { resolveCurrent, resolveVelocity } from '../utils/resolve-values'; import { MotionValue } from '../motion-value'; import { PoseConfig, MotionProps, PoseResolver, Pose } from '../motion/types'; @@ -20,7 +21,11 @@ const createPoseResolver = ( const pose: Pose = typeof config[poseKey] === 'function' - ? (config[poseKey] as PoseResolver)(props) + ? (config[poseKey] as PoseResolver)( + props, + resolveCurrent(values), + resolveVelocity(values) + ) : (config[poseKey] as Pose); const { transition, ...thisPose } = pose; diff --git a/src/hooks/use-posed-values.ts b/src/hooks/use-posed-values.ts index 3ee62a2712..fbfa5371b5 100644 --- a/src/hooks/use-posed-values.ts +++ b/src/hooks/use-posed-values.ts @@ -37,7 +37,7 @@ export default ( if (!poseDef) return; const initialPose = - typeof poseDef === 'function' ? poseDef(props) : poseDef; + typeof poseDef === 'function' ? poseDef(props, {}, {}) : poseDef; // We'll need to filter out options like staggerChildren etc Object.keys(initialPose).forEach(valueKey => { diff --git a/src/hooks/use-style-attr.ts b/src/hooks/use-style-attr.ts index de673d0a15..e98c84faef 100644 --- a/src/hooks/use-style-attr.ts +++ b/src/hooks/use-style-attr.ts @@ -1,17 +1,16 @@ import { useMemo, CSSProperties } from 'react'; import { buildStyleProperty } from 'stylefire'; import { MotionValue } from '../motion-value'; +import { resolveCurrent } from '../utils/resolve-values'; export default ( values: Map, styles?: CSSProperties ): CSSProperties => - useMemo(() => { - const resolvedValues = {}; - values.forEach((value, key) => (resolvedValues[key] = value.get())); - - return { + useMemo( + () => ({ ...styles, - ...buildStyleProperty(resolvedValues) - }; - }, []); + ...buildStyleProperty(resolveCurrent(values)) + }), + [] + ); diff --git a/src/motion/types.ts b/src/motion/types.ts index 95b1aa968f..d16a8af5eb 100644 --- a/src/motion/types.ts +++ b/src/motion/types.ts @@ -25,6 +25,8 @@ export type MotionProps = { export type EasingFunction = (v: number) => number; +export type CubicBezier = [number, number, number, number]; + export type Easing = | CubicBezier | 'linear' @@ -40,10 +42,14 @@ export type Easing = | 'anticipate' | EasingFunction; -export type Tween = { - type?: 'tween'; +export type BaseTransition = { from?: number | string; to?: number | string; + velocity?: number; +}; + +export type Tween = BaseTransition & { + type?: 'tween'; duration?: number; ease?: Easing; elapsed?: number; @@ -52,31 +58,24 @@ export type Tween = { yoyo?: number; }; -export type Spring = { +export type Spring = BaseTransition & { type: 'spring'; - from?: number | string; - to?: number | string; stiffness?: number; damping?: number; mass?: number; - velocity?: number; restSpeed?: number; restDelta?: number; }; -export type Decay = { +export type Decay = BaseTransition & { type: 'decay'; - velocity?: number; - from?: number | string; modifyTarget?: (v: number) => number; power?: number; timeConstant?: number; restDelta?: number; }; -export type CubicBezier = [number, number, number, number]; - -export type Keyframes = { +export type Keyframes = BaseTransition & { type: 'keyframes'; values: number[] | string[]; easings?: Easing[]; @@ -88,14 +87,11 @@ export type Keyframes = { yoyo?: number; }; -export type Physics = { +export type Physics = BaseTransition & { type: 'physics'; - from?: number | string; acceleration?: number; friction?: number; - velocity?: number; restSpeed?: number | false; - to?: number | string; }; export type Transition = Tween | Spring | Decay | Keyframes | Physics; @@ -175,6 +171,9 @@ export type Pose = { fill?: string; stroke?: string; + // Misc + backgroundImage?: string; + // SVG d?: string; pathLength?: number; @@ -186,4 +185,8 @@ export type Pose = { staggerChildren?: number; }; -export type PoseResolver = (props: { [key: string]: any }) => Pose; +export type PoseResolver = ( + props: { [key: string]: any }, + current: { [key: string]: number | string }, + velocity: { [key: string]: number | false } +) => Pose; diff --git a/src/utils/resolve-values.ts b/src/utils/resolve-values.ts new file mode 100644 index 0000000000..705cf0dc4c --- /dev/null +++ b/src/utils/resolve-values.ts @@ -0,0 +1,16 @@ +import { MotionValue } from '../motion-value'; + +export type Resolver = (value: MotionValue) => any; + +const createValueResolver = (resolver: Resolver) => ( + values: Map +) => { + const resolvedValues = {}; + values.forEach((value, key) => (resolvedValues[key] = resolver(value))); + return resolvedValues; +}; + +export const resolveCurrent = createValueResolver(value => value.get()); +export const resolveVelocity = createValueResolver(value => + value.getVelocity() +); diff --git a/src/utils/transitions.ts b/src/utils/transitions.ts index 7a0950a9f0..b94f5a8d46 100644 --- a/src/utils/transitions.ts +++ b/src/utils/transitions.ts @@ -1,5 +1,5 @@ import { tween, spring, keyframes, decay, physics, easing } from 'popmotion'; -import { Transition, TransitionMap, Tween } from '../motion/types'; +import { Transition, TransitionMap, Tween, Keyframes } from '../motion/types'; import { invariant } from 'hey-listen'; const transitions = { tween, spring, keyframes, decay, physics }; @@ -39,7 +39,7 @@ const easingLookup: { [key: string]: (num: number) => number } = { }; const transitionOptionParser = { - tween: (opts: Tween) => { + tween: (opts: Tween): Tween => { const { ease } = opts; if (Array.isArray(ease)) { @@ -59,7 +59,10 @@ const transitionOptionParser = { ); opts.ease = easingLookup[ease]; } - } + + return opts; + }, + keyframes: ({ from, to, ...opts }: Keyframes) => opts }; const preprocessOptions = ( From a92f294598a0562f683b8a737290b7390add2f28 Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Tue, 20 Nov 2018 16:55:37 +0000 Subject: [PATCH 11/44] adding rollup --- .gitignore | 3 ++ package.json | 13 +++-- rollup.config.js | 77 ++++++++++++++++++++++++++++++ tsconfig.json | 7 +-- yarn.lock | 121 ++++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 208 insertions(+), 13 deletions(-) create mode 100644 rollup.config.js diff --git a/.gitignore b/.gitignore index bccfa11ce3..ab1b13107d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ /node_modules /.cache-loader .DS_Store +/dist +/lib +/tmp diff --git a/package.json b/package.json index d9fc7aadef..0f6f5187fd 100644 --- a/package.json +++ b/package.json @@ -2,15 +2,17 @@ "name": "framer-motion", "version": "0.0.1", "private": true, - "main": "build/framer.js", - "types": "build/framer.d.ts", + "main": "dist/framer-motion.js", + "types": "dist/framer-motion.d.ts", "author": "Framer Motion", "license": "MIT", "scripts": { "coverage": "jest --coverage", "test": "jest", "watch": "jest --watch", - "prettier": "prettier ./src/* --write" + "prettier": "prettier ./src/* --write", + "build": "rollup -c && yarn measure", + "measure": "gzip -c dist/framer-motion.js | wc -c" }, "peerDependencies": { "react": "^16.7", @@ -33,6 +35,11 @@ "react": "^16.7.0-alpha.2", "react-dev-utils": "^6.1.1", "react-dom": "^16.7.0-alpha.2", + "rollup": "^0.67.3", + "rollup-plugin-node-resolve": "^3.4.0", + "rollup-plugin-replace": "^2.1.0", + "rollup-plugin-typescript2": "^0.18.0", + "rollup-plugin-uglify": "^6.0.0", "styled-components": "^4.1.1", "ts-jest": "^23.10.4", "ts-loader": "^5.3.0", diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 0000000000..db413d866f --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,77 @@ +import typescript from 'rollup-plugin-typescript2'; +import resolve from 'rollup-plugin-node-resolve'; +import { uglify } from 'rollup-plugin-uglify'; +import replace from 'rollup-plugin-replace'; +import pkg from './package.json'; + +const typescriptConfig = { cacheRoot: 'tmp/.rpt2_cache' }; +const noDeclarationConfig = Object.assign({}, typescriptConfig, { + tsconfigOverride: { compilerOptions: { declaration: false } } +}); + +const config = { + input: 'src/index.ts' +}; + +const external = [ + 'react', + '@popmotion/popcorn', + 'framesync', + 'stylefire', + 'hey-listen', + 'popmotion' +]; + +const umd = Object.assign({}, config, { + output: { + file: `dist/${pkg.name}.dev.js`, + format: 'umd', + name: 'FramerMotion', + exports: 'named', + globals: { react: 'React' } + }, + external: ['react', 'react-dom'], + plugins: [ + typescript(noDeclarationConfig), + resolve(), + replace({ + 'process.env.NODE_ENV': JSON.stringify('development') + }) + ] +}); + +const umdProd = Object.assign({}, umd, { + output: Object.assign({}, umd.output, { + file: `dist/${pkg.name}.js` + }), + plugins: [ + typescript(noDeclarationConfig), + resolve(), + replace({ + 'process.env.NODE_ENV': JSON.stringify('production') + }), + uglify() + ] +}); + +const cjs = Object.assign({}, config, { + output: { + file: 'lib/index.js', + format: 'cjs', + exports: 'named' + }, + plugins: [typescript(typescriptConfig)], + external +}); + +const es = Object.assign({}, config, { + output: { + file: `dist/${pkg.name}.es.js`, + format: 'es', + exports: 'named' + }, + plugins: [typescript(noDeclarationConfig)], + external +}); + +export default [umd, umdProd, es, cjs]; diff --git a/tsconfig.json b/tsconfig.json index 7ec77f2df3..d2fb850a89 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { - "target": "es2015", - "module": "commonjs", + "target": "es5", + "module": "ESNext", "moduleResolution": "node", "isolatedModules": false, "jsx": "react", @@ -25,7 +25,8 @@ "noImplicitUseStrict": false, "noUnusedLocals": true, "noUnusedParameters": true, - "removeComments": true + "removeComments": true, + "lib": ["es5", "es6", "dom"], }, "compileOnSave": false, "buildOnSave": false, diff --git a/yarn.lock b/yarn.lock index 1c3a5e902e..1b791c08b5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -"@babel/code-frame@7.0.0", "@babel/code-frame@^7.0.0-beta.35": +"@babel/code-frame@7.0.0", "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.0.0-beta.35": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA== @@ -86,6 +86,11 @@ dependencies: any-observable "^0.3.0" +"@types/estree@0.0.39": + version "0.0.39" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" + integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== + "@types/jest@^23.3.9": version "23.3.9" resolved "https://registry.yarnpkg.com/@types/jest/-/jest-23.3.9.tgz#c16b55186ee73ae65e001fbee69d392c51337ad1" @@ -1006,6 +1011,11 @@ builtin-modules@^1.0.0, builtin-modules@^1.1.1: resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= +builtin-modules@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-2.0.0.tgz#60b7ef5ae6546bd7deefa74b08b62a43a232648e" + integrity sha512-3U5kUA5VPsRUA3nofm/BXX7GVHKfxz0hOBAPxXrIvHzlDRkQVqEn6yi8QJegxl4LzOHLdvb7XF5dVawa/VVYBg== + builtin-status-codes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" @@ -1948,6 +1958,11 @@ estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= +estree-walker@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.5.2.tgz#d3850be7529c9580d815600b53126515e146dd39" + integrity sha512-XpCnW/AE10ws/kDAs37cngSkvgIR8aN3G0MS85m7dUpuK2EREo9VJ00uvw6Dg/hXEpfsE1I1TvJOJr+Z+TL+ig== + esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" @@ -2439,6 +2454,15 @@ from2@^2.1.0: inherits "^2.0.1" readable-stream "^2.0.0" +fs-extra@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.0.tgz#8cc3f47ce07ef7b3593a11b9fb245f7e34c041d6" + integrity sha512-EglNDLRpmaTWiD/qraZn6HREAEAHJcJOmxNEYwq6xeMKnVMAy3GUcFB+wXt2C6k4CNvB/mP1y/U3dzvKKj5OtQ== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + fs-minipass@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" @@ -2630,7 +2654,7 @@ globby@^6.1.0: pify "^2.0.0" pinkie-promise "^2.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.2: +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: version "4.1.15" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== @@ -3226,6 +3250,11 @@ is-glob@^4.0.0: dependencies: is-extglob "^2.1.1" +is-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" + integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE= + is-number@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" @@ -3866,6 +3895,13 @@ json5@^0.5.0, json5@^0.5.1: resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + jsonify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" @@ -4120,6 +4156,13 @@ lru-cache@^4.0.1, lru-cache@^4.1.1: pseudomap "^1.0.2" yallist "^2.1.2" +magic-string@^0.25.1: + version "0.25.1" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.1.tgz#b1c248b399cd7485da0fe7385c2fc7011843266e" + integrity sha512-sCuTz6pYom8Rlt4ISPFn6wuFodbKMIHUMv4Qko9P17dpxb7s52KJTmRuZZqHdGmLCK9AOcDare039nRIcfdkEg== + dependencies: + sourcemap-codec "^1.4.1" + make-dir@^1.0.0: version "1.3.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" @@ -4323,7 +4366,7 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= -minimatch@3.0.4, minimatch@^3.0.3, minimatch@^3.0.4: +minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -5587,7 +5630,7 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@^1.3.2, resolve@^1.5.0: +resolve@1.8.1, resolve@^1.1.6, resolve@^1.3.2, resolve@^1.5.0: version "1.8.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA== @@ -5630,6 +5673,60 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" +rollup-plugin-node-resolve@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-3.4.0.tgz#908585eda12e393caac7498715a01e08606abc89" + integrity sha512-PJcd85dxfSBWih84ozRtBkB731OjXk0KnzN0oGp7WOWcarAFkVa71cV5hTJg2qpVsV2U8EUwrzHP3tvy9vS3qg== + dependencies: + builtin-modules "^2.0.0" + is-module "^1.0.0" + resolve "^1.1.6" + +rollup-plugin-replace@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-replace/-/rollup-plugin-replace-2.1.0.tgz#f9c07a4a89a2f8be912ee54b3f0f68d91e9ed0ae" + integrity sha512-SxrAIgpH/B5/W4SeULgreOemxcpEgKs2gcD42zXw50bhqGWmcnlXneVInQpAqzA/cIly4bJrOpeelmB9p4YXSQ== + dependencies: + magic-string "^0.25.1" + minimatch "^3.0.2" + rollup-pluginutils "^2.0.1" + +rollup-plugin-typescript2@^0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.18.0.tgz#ab3f7003f47c3858810d516e4d3fada546bfb1df" + integrity sha512-AL7LJl31bYO/x8zO1fuE7ACn/2nDs9DVYL3qjiWSYg5LC4EV/iKuCL4Fm6pjzEqCB4fFIMXoUuGUf5R+BLNKSg== + dependencies: + fs-extra "7.0.0" + resolve "1.8.1" + rollup-pluginutils "2.3.3" + tslib "1.9.3" + +rollup-plugin-uglify@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-uglify/-/rollup-plugin-uglify-6.0.0.tgz#15aa8919e5cdc63b7cfc9319c781788b40084ce4" + integrity sha512-XtzZd159QuOaXNvcxyBcbUCSoBsv5YYWK+7ZwUyujSmISst8avRfjWlp7cGu8T2O52OJnpEBvl+D4WLV1k1iQQ== + dependencies: + "@babel/code-frame" "^7.0.0" + jest-worker "^23.2.0" + serialize-javascript "^1.5.0" + uglify-js "^3.4.9" + +rollup-pluginutils@2.3.3, rollup-pluginutils@^2.0.1: + version "2.3.3" + resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.3.3.tgz#3aad9b1eb3e7fe8262820818840bf091e5ae6794" + integrity sha512-2XZwja7b6P5q4RZ5FhyX1+f46xi1Z3qBKigLRZ6VTZjwbN0K1IFGMlwm06Uu0Emcre2Z63l77nq/pzn+KxIEoA== + dependencies: + estree-walker "^0.5.2" + micromatch "^2.3.11" + +rollup@^0.67.3: + version "0.67.3" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.67.3.tgz#55475b1b62c43220c3b4bd7edc5846233932f50b" + integrity sha512-TyNQCz97rKuVVbsKUTXfwIjV7UljWyTVd7cTMuE+aqlQ7WJslkYF5QaYGjMLR2BlQtUOO5CAxSVnpQ55iYp5jg== + dependencies: + "@types/estree" "0.0.39" + "@types/node" "*" + rsvp@^3.3.3: version "3.6.2" resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" @@ -5765,7 +5862,7 @@ send@0.16.2: range-parser "~1.2.0" statuses "~1.4.0" -serialize-javascript@^1.4.0: +serialize-javascript@^1.4.0, serialize-javascript@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.5.0.tgz#1aa336162c88a890ddad5384baebc93a655161fe" integrity sha512-Ga8c8NjAAp46Br4+0oZ2WxJCwIzwP60Gq1YPgU+39PiTVxyed/iKE/zyZI6+UlVYH5Q4PaQdHhcegIFPZTUfoQ== @@ -6003,6 +6100,11 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +sourcemap-codec@^1.4.1: + version "1.4.3" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.3.tgz#0ba615b73ec35112f63c2f2d9e7c3f87282b0e33" + integrity sha512-vFrY/x/NdsD7Yc8mpTJXuao9S8lq08Z/kOITHz6b7YbfI9xL8Spe5EvSQUHOI7SbpY8bRPr0U3kKSsPuqEGSfA== + spdx-correct@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.2.tgz#19bb409e91b47b1ad54159243f7312a858db3c2e" @@ -6475,7 +6577,7 @@ ts-loader@^5.3.0: micromatch "^3.1.4" semver "^5.0.1" -tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.1: +tslib@1.9.3, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.1: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== @@ -6574,7 +6676,7 @@ uglify-es@^3.3.4: commander "~2.13.0" source-map "~0.6.1" -uglify-js@^3.1.4: +uglify-js@^3.1.4, uglify-js@^3.4.9: version "3.4.9" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.9.tgz#af02f180c1207d76432e473ed24a28f4a782bae3" integrity sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q== @@ -6620,6 +6722,11 @@ unique-slug@^2.0.0: dependencies: imurmurhash "^0.1.4" +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" From 3105d6f745159c5f193510a221154797459c6732 Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Wed, 21 Nov 2018 11:53:53 +0000 Subject: [PATCH 12/44] adding velocity to motion value --- TODO.md | 1 + dev/examples/custom-transition.tsx | 12 ++++- package.json | 1 + src/hooks/use-pose-resolver.ts | 75 +++++++++++++++++++++++------- src/hooks/use-posed-values.ts | 35 ++++---------- src/motion-value/index.ts | 50 ++++++++++++++++---- src/motion/component.ts | 2 +- src/motion/types.ts | 26 +++++++++-- src/utils/create-value.ts | 35 ++++++++++++++ src/utils/pose-resolvers.ts | 2 +- tsconfig.json | 2 +- 11 files changed, 178 insertions(+), 63 deletions(-) create mode 100644 src/utils/create-value.ts diff --git a/TODO.md b/TODO.md index 709ee3405a..c058df920c 100644 --- a/TODO.md +++ b/TODO.md @@ -4,6 +4,7 @@ - Add Rollup for production bundle generation (will save multiple kb) ## Features +- `false` for `transition` support. - Fix prop types on `motion` - Add intelligent defaults - Add velocity tracking diff --git a/dev/examples/custom-transition.tsx b/dev/examples/custom-transition.tsx index 1822a4f5d9..f0c41df89b 100644 --- a/dev/examples/custom-transition.tsx +++ b/dev/examples/custom-transition.tsx @@ -7,9 +7,17 @@ const MotionBox = motion(Box)({ ping: { x: 100, y: '0vh', - transition: { duration: 23000 } + opacity: 0, + transition: { duration: 300 }, + transitionEnd: { display: 'none' } }, - pong: { x: -100, y: '20vh' } + pong: { + x: -100, + y: '20vh', + opacity: 1, + display: 'block', + transition: { duration: 300 } + } }); export const App = () => { diff --git a/package.json b/package.json index 0f6f5187fd..244df033ea 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "@popmotion/popcorn": "^0.2.0", "hey-listen": "^1.0.5", "popmotion": "8.5.3", + "style-value-types": "^3.0.7", "stylefire": "^2.3.1" }, "prettier": { diff --git a/src/hooks/use-pose-resolver.ts b/src/hooks/use-pose-resolver.ts index ba58709dd2..7c7aac781f 100644 --- a/src/hooks/use-pose-resolver.ts +++ b/src/hooks/use-pose-resolver.ts @@ -1,19 +1,33 @@ -import { useRef, useEffect, MutableRefObject } from 'react'; +import { useRef, useEffect, MutableRefObject, RefObject } from 'react'; import { invariant } from 'hey-listen'; import getTransition from '../utils/transitions'; import { poseToArray } from '../utils/pose-resolvers'; import { resolveCurrent, resolveVelocity } from '../utils/resolve-values'; import { MotionValue } from '../motion-value'; -import { PoseConfig, MotionProps, PoseResolver, Pose } from '../motion/types'; +import { createValuesFromPose, bindValuesToRef } from '../utils/create-value'; +import { + PoseConfig, + MotionProps, + PoseResolver, + Pose, + MotionValueMap +} from '../motion/types'; +import { complex } from 'style-value-types'; type PoseSubscriber = (v: string | string[]) => void; +const isAnimatable = (value: string | number) => + typeof value === 'number' || complex.test(value); + const createPoseResolver = ( - values: Map, + values: MotionValueMap, config: PoseConfig, - props: MotionProps + { onTransitionEnd, props }: MotionProps, + ref: RefObject ) => (poseList: string[]) => { - poseList.forEach(poseKey => { + const poseTransitions: Promise[] = []; + + poseList.reverse().forEach(poseKey => { invariant( config[poseKey] !== undefined, `Pose with name ${poseKey} not found.` @@ -28,37 +42,62 @@ const createPoseResolver = ( ) : (config[poseKey] as Pose); - const { transition, ...thisPose } = pose; + const { transition, transitionEnd, ...thisPose } = pose; - // TODO: Check to see if `transition` exists and generate default - // based on keys being animated if not + const valueTransitions: Promise[] = []; - // Filter pose options like stagger children here Object.keys(thisPose).forEach(valueKey => { - const value = values.get(valueKey); const target = thisPose[valueKey]; - invariant( - value !== undefined, - 'Value not found. Ensure all animated values are created on component mount.' // Maybe create this value on the fly instead? - ); + // If this value doesn't exist in the value map, create it + if (!values.has(valueKey)) { + createValuesFromPose(values, pose); + bindValuesToRef(values, ref); + } + + const value: MotionValue = values.get(valueKey) as MotionValue; - const [action, opts] = getTransition(valueKey, target, transition); + if (isAnimatable(target)) { + // If we can animate this value, for instance 100, '100px' or '#fff' + const [action, opts] = getTransition(valueKey, target, transition); - value && value.control(action, opts); + if (value) { + valueTransitions.push(value.control(action, opts)); + } + } else { + // If this is not an animatable value, for instance `display: block`, just set it. + value.set(target); + } }); + + poseTransitions.push( + Promise.all(valueTransitions).then(() => { + if (!transitionEnd) return; + + Object.keys(transitionEnd).forEach(valueKey => { + if (values.has(valueKey)) { + (values.get(valueKey) as MotionValue).set(transitionEnd[valueKey]); + } + }); + }) + ); + }); + + Promise.all(poseTransitions).then(() => { + onTransitionEnd && onTransitionEnd(); }); }; const usePoseResolver = ( values: Map, config: PoseConfig, - props: MotionProps + props: MotionProps, + ref: RefObject ) => { const poseSubscriber: MutableRefObject = useRef(null); const { pose } = props; const poseIsSubscription = pose instanceof MotionValue; - const poseResolver = createPoseResolver(values, config, props); + const poseResolver = createPoseResolver(values, config, props, ref); // If we're controlled by props, fire resolver with latest pose const poseList = !poseIsSubscription diff --git a/src/hooks/use-posed-values.ts b/src/hooks/use-posed-values.ts index fbfa5371b5..cc26460074 100644 --- a/src/hooks/use-posed-values.ts +++ b/src/hooks/use-posed-values.ts @@ -1,23 +1,22 @@ -import motionValue, { MotionValue } from '../motion-value'; +import { MotionValue } from '../motion-value'; import { resolvePoses } from '../utils/pose-resolvers'; -import { PoseConfig, MotionProps } from '../motion/types'; +import { PoseConfig, MotionProps, MotionValueMap } from '../motion/types'; import { useRef, useEffect, RefObject } from 'react'; -import styler from 'stylefire'; -import { invariant } from 'hey-listen'; +import { createValuesFromPose, bindValuesToRef } from '../utils/create-value'; export default ( config: PoseConfig, props: MotionProps, ref: RefObject -): [Map, Partial] => { - const values = useRef(new Map()).current; +): [MotionValueMap, Partial] => { + const values: MotionValueMap = useRef(new Map()).current; const returnedProps = {}; // In this function we want to find the right approach to ensure // we successfully remove MotionValues from the returned props // in a performant way over subsequent renders. - // 1. Bind stylers to provided motion values via props + // 1. Add provided motion values via props to value map Object.keys(props).forEach(key => { const prop = props[key]; @@ -36,31 +35,15 @@ export default ( const poseDef = config[poseKey]; if (!poseDef) return; - const initialPose = + const pose = typeof poseDef === 'function' ? poseDef(props, {}, {}) : poseDef; - // We'll need to filter out options like staggerChildren etc - Object.keys(initialPose).forEach(valueKey => { - if (!values.has(valueKey)) { - values.set(valueKey, motionValue(initialPose[valueKey])); - } - }); + createValuesFromPose(values, pose); }); // 3. Bind stylers when ref is ready useEffect(() => { - invariant( - ref.current !== null, - 'No DOM reference found. Ensure custom components use `forwardRef` to forward the `ref` property to the host DOM component.' - ); - - if (!ref.current) return; - - const domStyler = styler(ref.current); - - values.forEach((value, key) => { - value.setOnRender((v: any) => domStyler.set(key, v)); - }); + bindValuesToRef(values, ref); return () => values.forEach(value => value.destroy()); }, []); diff --git a/src/motion-value/index.ts b/src/motion-value/index.ts index 73430a0b17..2cc014513e 100644 --- a/src/motion-value/index.ts +++ b/src/motion-value/index.ts @@ -1,5 +1,6 @@ -import sync from 'framesync'; +import sync, { getFrameData, FrameData } from 'framesync'; import { Action, ColdSubscription } from 'popmotion'; +import { velocityPerSecond } from '@popmotion/popcorn'; export type ValuePrimitive = any; @@ -19,29 +20,34 @@ export type ActionFactory = (actionConfig: ActionConfig) => Action; export class MotionValue { // Current state - current: ValuePrimitive; + private current: ValuePrimitive; // Previous state - prev: ValuePrimitive; + private prev: ValuePrimitive; + + private timeDelta: number = 0; + private lastUpdated: number = 0; // Children get updated onUpdate - children: Set; + private children: Set; // A reference to the value's parent - currently used for unregistering as a child, // but maybe it'd be better for this to be just a disconnect function - parent?: MotionValue; + private parent?: MotionValue; // onRender is fired on render step after update - onRender: Subscriber | null; + private onRender: Subscriber | null; // Fired - subscribers: Set; + private subscribers: Set; // If set, will pass `set` values through this function first - transformer?: Transformer; + private transformer?: Transformer; // A reference to the currently-controlling animation - controller?: ColdSubscription; + private controller?: ColdSubscription; + + private canTrackVelocity = false; constructor( init: ValuePrimitive, @@ -51,6 +57,7 @@ export class MotionValue { this.transformer = transformer; if (onRender) this.setOnRender(onRender); this.set(init); + this.canTrackVelocity = !isNaN(parseFloat(this.current)); } addChild(config: Config) { @@ -101,8 +108,22 @@ export class MotionValue { if (this.onRender) { sync.render(this.render); } + + // Update timestamp + const { delta, timestamp } = getFrameData(); + this.timeDelta = delta; + this.lastUpdated = timestamp; + sync.postRender(this.scheduleVelocityCheck); } + scheduleVelocityCheck = () => sync.postRender(this.velocityCheck); + + velocityCheck = ({ timestamp }: FrameData) => { + if (timestamp !== this.lastUpdated) { + this.prev = this.current; + } + }; + notifySubscribers = () => this.subscribers.forEach(this.setSubscriber); setSubscriber = (sub: Subscriber) => sub(this.current); setChild = (child: MotionValue) => child.set(this.current); @@ -112,7 +133,12 @@ export class MotionValue { } getVelocity() { - return 0; + return this.canTrackVelocity + ? velocityPerSecond( + parseFloat(this.prev) - parseFloat(this.current), + this.timeDelta + ) + : 0; } render = () => { @@ -153,6 +179,10 @@ export class MotionValue { this.parent && this.parent.removeChild(this); this.stop(); } + + hasOnRender() { + return !!this.onRender; + } } export default (init: ValuePrimitive, opts?: Config) => diff --git a/src/motion/component.ts b/src/motion/component.ts index 6b2a9ef44f..1f44b7d098 100644 --- a/src/motion/component.ts +++ b/src/motion/component.ts @@ -25,7 +25,7 @@ const createMotionComponent = ( // Create motion values const [values, componentProps] = usePosedValues(config, props, ref); - usePoseResolver(values, config, props); + usePoseResolver(values, config, props, ref); // Types here are a bit of a hack return createElement | SVGProps & MotionProps>( diff --git a/src/motion/types.ts b/src/motion/types.ts index d16a8af5eb..9b45d020dd 100644 --- a/src/motion/types.ts +++ b/src/motion/types.ts @@ -21,6 +21,7 @@ export type MotionProps = { ref: RefObject; pose: string | string[] | MotionValue; style: CSSProperties; + onTransitionEnd?: () => void; }; export type EasingFunction = (v: number) => number; @@ -46,6 +47,12 @@ export type BaseTransition = { from?: number | string; to?: number | string; velocity?: number; + delay?: number; + delayChildren?: number; + staggerDirection?: number; + staggerChildren?: number; + beforeChildren?: boolean; + afterChildren?: boolean; }; export type Tween = BaseTransition & { @@ -181,12 +188,23 @@ export type Pose = { // Options transition?: TransitionDefinition; - staggerDirection?: number; - staggerChildren?: number; + transitionEnd?: StyleProps | ResolveStyleProps; }; +export type ResolveStyleProps = ( + current: CurrentValues, + velocity: VelocityValues +) => StyleProps; + +export type StyleProps = { [key: string]: string | number }; + +export type CurrentValues = { [key: string]: string | number }; +export type VelocityValues = { [key: string]: number }; + export type PoseResolver = ( props: { [key: string]: any }, - current: { [key: string]: number | string }, - velocity: { [key: string]: number | false } + current: CurrentValues, + velocity: VelocityValues ) => Pose; + +export type MotionValueMap = Map; diff --git a/src/utils/create-value.ts b/src/utils/create-value.ts new file mode 100644 index 0000000000..ebaa27646c --- /dev/null +++ b/src/utils/create-value.ts @@ -0,0 +1,35 @@ +import { RefObject } from 'react'; +import { MotionValueMap, Pose } from '../motion/types'; +import motionValue from '../motion-value'; +import styler from 'stylefire'; +import { invariant } from 'hey-listen'; + +export const createValuesFromPose = ( + values: MotionValueMap, + { transition, transitionEnd, ...pose }: Pose +) => { + const valuesToAdd = { ...pose, ...transitionEnd }; + Object.keys(valuesToAdd).forEach(valueKey => { + if (!values.has(valueKey)) { + values.set(valueKey, motionValue(valuesToAdd[valueKey])); + } + }); +}; + +export const bindValuesToRef = ( + values: MotionValueMap, + ref: RefObject +) => { + invariant( + ref.current !== null, + 'No DOM reference found. Ensure custom components use `forwardRef` to forward the `ref` property to the host DOM component.' + ); + + if (!ref.current) return; + + const domStyler = styler(ref.current); + + values.forEach((value, key) => { + if (!value.onRender) value.setOnRender((v: any) => domStyler.set(key, v)); + }); +}; diff --git a/src/utils/pose-resolvers.ts b/src/utils/pose-resolvers.ts index 1ff9077250..ca91222105 100644 --- a/src/utils/pose-resolvers.ts +++ b/src/utils/pose-resolvers.ts @@ -5,7 +5,7 @@ type PoseName = string | PoseNameList; type UnresolvedPose = PoseName | MotionValue; export const poseToArray = (pose?: PoseName): PoseNameList => - Array.isArray(pose) ? [...pose].reverse() : pose ? [pose] : []; + Array.isArray(pose) ? [...pose] : pose ? [pose] : []; export const resolvePoses = (pose: UnresolvedPose): PoseNameList => { const unresolvedPose = diff --git a/tsconfig.json b/tsconfig.json index d2fb850a89..6727b3e069 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -26,7 +26,7 @@ "noUnusedLocals": true, "noUnusedParameters": true, "removeComments": true, - "lib": ["es5", "es6", "dom"], + "lib": ["es5", "es6", "dom"] }, "compileOnSave": false, "buildOnSave": false, From 6ee6ceec9598a69e82d2ad0a3af5958269c2c443 Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Wed, 21 Nov 2018 15:19:54 +0000 Subject: [PATCH 13/44] adding default transitions --- TODO.md | 1 - dev/examples/custom-transition.tsx | 5 +- dev/examples/pose-children.tsx | 53 ++++++++++++++++++++ dev/inc/use-interval.ts | 6 ++- rollup.config.js | 3 +- src/hooks/use-pose-resolver.ts | 2 +- src/motion-value/index.ts | 13 ++++- src/motion/component.ts | 45 ----------------- src/motion/component.tsx | 34 +++++++++++++ src/motion/types.ts | 22 ++++++--- src/utils/create-value.ts | 4 +- src/utils/default-transitions.ts | 43 ++++++++++++++++ src/utils/transitions.ts | 78 ++++++++++++++++++++++-------- 13 files changed, 228 insertions(+), 81 deletions(-) create mode 100644 dev/examples/pose-children.tsx delete mode 100644 src/motion/component.ts create mode 100644 src/motion/component.tsx create mode 100644 src/utils/default-transitions.ts diff --git a/TODO.md b/TODO.md index c058df920c..75e7ed3c4b 100644 --- a/TODO.md +++ b/TODO.md @@ -7,7 +7,6 @@ - `false` for `transition` support. - Fix prop types on `motion` - Add intelligent defaults -- Add velocity tracking - Coordination across children (ie `staggerChildren`) - Gestures - `setPose.cycle` \ No newline at end of file diff --git a/dev/examples/custom-transition.tsx b/dev/examples/custom-transition.tsx index f0c41df89b..ff7ed8164a 100644 --- a/dev/examples/custom-transition.tsx +++ b/dev/examples/custom-transition.tsx @@ -8,7 +8,10 @@ const MotionBox = motion(Box)({ x: 100, y: '0vh', opacity: 0, - transition: { duration: 300 }, + transition: { + x: false, + default: { duration: 4000 } + }, transitionEnd: { display: 'none' } }, pong: { diff --git a/dev/examples/pose-children.tsx b/dev/examples/pose-children.tsx new file mode 100644 index 0000000000..1319fb383d --- /dev/null +++ b/dev/examples/pose-children.tsx @@ -0,0 +1,53 @@ +import * as React from 'react'; +import { useState } from 'react'; +import { motion } from '@framer'; +import { Box } from '../styled'; +import useInterval from '../inc/use-interval'; + +const Parent = motion.div({ + visible: { + opacity: 1, + y: 0, + transition: { + staggerChildren: 50 + } + }, + hidden: { opacity: 0, y: 100 } +}); + +const Child = motion.div({ + visible: { opacity: 1, x: 0 }, + hidden: { opacity: 0, x: -100 } +}); + +const parentStyles = { + width: 400, + height: 500, + background: 'red', + padding: 10 +}; + +const childStyles = { + width: '100%', + height: 50, + background: 'black', + marginBottom: 30 +}; + +export const App = () => { + const [pose, setPose] = useState('hidden'); + + useInterval(() => setPose(pose === 'hidden' ? 'visible' : 'hidden'), 2000, [ + pose + ]); + + return ( + +
+ + + +
+
+ ); +}; diff --git a/dev/inc/use-interval.ts b/dev/inc/use-interval.ts index d2c6deaf62..916fec3b70 100644 --- a/dev/inc/use-interval.ts +++ b/dev/inc/use-interval.ts @@ -1,6 +1,10 @@ import { useEffect } from 'react'; -export default (callback: () => void, interval: number = 1000, args = []) => { +export default ( + callback: () => void, + interval: number = 1000, + args: any[] = [] +) => { useEffect(() => { const int = setInterval(callback, interval); return () => clearInterval(int); diff --git a/rollup.config.js b/rollup.config.js index db413d866f..3c7e60fcb4 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -19,7 +19,8 @@ const external = [ 'framesync', 'stylefire', 'hey-listen', - 'popmotion' + 'popmotion', + 'style-value-types' ]; const umd = Object.assign({}, config, { diff --git a/src/hooks/use-pose-resolver.ts b/src/hooks/use-pose-resolver.ts index 7c7aac781f..4f5db29213 100644 --- a/src/hooks/use-pose-resolver.ts +++ b/src/hooks/use-pose-resolver.ts @@ -83,7 +83,7 @@ const createPoseResolver = ( ); }); - Promise.all(poseTransitions).then(() => { + return Promise.all(poseTransitions).then(() => { onTransitionEnd && onTransitionEnd(); }); }; diff --git a/src/motion-value/index.ts b/src/motion-value/index.ts index 2cc014513e..fe5ecab2c8 100644 --- a/src/motion-value/index.ts +++ b/src/motion-value/index.ts @@ -1,5 +1,10 @@ import sync, { getFrameData, FrameData } from 'framesync'; -import { Action, ColdSubscription } from 'popmotion'; +import { + chain, + delay as delayAction, + Action, + ColdSubscription +} from 'popmotion'; import { velocityPerSecond } from '@popmotion/popcorn'; export type ValuePrimitive = any; @@ -147,7 +152,7 @@ export class MotionValue { control( controller: ActionFactory, - config: ActionConfig, + { delay, ...config }: ActionConfig, transformer?: Transformer ) { this.stop(); @@ -162,6 +167,10 @@ export class MotionValue { initialisedController = initialisedController.pipe(transformer); } + if (delay) { + initialisedController = chain(delayAction(delay), initialisedController); + } + return new Promise(complete => { this.controller = initialisedController.start({ update: (v: ValuePrimitive) => this.set(v), diff --git a/src/motion/component.ts b/src/motion/component.ts deleted file mode 100644 index 1f44b7d098..0000000000 --- a/src/motion/component.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { - memo, - forwardRef, - createElement, - Ref, - ComponentType, - HTMLProps, - SVGProps -} from 'react'; -import { MotionProps, ComponentFactory } from './types'; -import useConfig from '../hooks/use-config'; -import useExternalRef from '../hooks/use-external-ref'; -import usePosedValues from '../hooks/use-posed-values'; -import usePoseResolver from '../hooks/use-pose-resolver'; -import useStyleAttr from '../hooks/use-style-attr'; - -const createMotionComponent = ( - Component: string | ComponentType -): ComponentFactory => (PoseConfig = {}) => { - const MotionComponent = forwardRef( - (props: MotionProps, externalRef?: Ref) => { - const ref = useExternalRef(externalRef); - const config = useConfig(PoseConfig, props); - - // Create motion values - const [values, componentProps] = usePosedValues(config, props, ref); - - usePoseResolver(values, config, props, ref); - - // Types here are a bit of a hack - return createElement | SVGProps & MotionProps>( - Component, - { - ref, - ...componentProps, - style: useStyleAttr(values, props.style) - } - ); - } - ); - - return memo(MotionComponent); -}; - -export default createMotionComponent; diff --git a/src/motion/component.tsx b/src/motion/component.tsx new file mode 100644 index 0000000000..162209dd13 --- /dev/null +++ b/src/motion/component.tsx @@ -0,0 +1,34 @@ +import { memo, forwardRef, createElement, Ref, ComponentType } from 'react'; +import { MotionProps, ComponentFactory } from './types'; +import useConfig from '../hooks/use-config'; +import useExternalRef from '../hooks/use-external-ref'; +import usePosedValues from '../hooks/use-posed-values'; +import usePoseResolver from '../hooks/use-pose-resolver'; +import useStyleAttr from '../hooks/use-style-attr'; + +// TODO: tighten component type checking +type Props = { [key: string]: any }; + +const createMotionComponent = ( + Component: string | ComponentType +): ComponentFactory => (poseConfig = {}) => { + const MotionComponent = (props: MotionProps, externalRef?: Ref) => { + const ref = useExternalRef(externalRef); + const config = useConfig(poseConfig, props); + + // Create motion values + const [values, componentProps] = usePosedValues(config, props, ref); + + usePoseResolver(values, config, props, ref); + + return createElement(Component, { + ...componentProps, + ref, + style: useStyleAttr(values, props.style) + }); + }; + + return memo(forwardRef(MotionComponent)); +}; + +export default createMotionComponent; diff --git a/src/motion/types.ts b/src/motion/types.ts index 9b45d020dd..0d31dafcd4 100644 --- a/src/motion/types.ts +++ b/src/motion/types.ts @@ -44,15 +44,10 @@ export type Easing = | EasingFunction; export type BaseTransition = { + delay?: number; from?: number | string; to?: number | string; velocity?: number; - delay?: number; - delayChildren?: number; - staggerDirection?: number; - staggerChildren?: number; - beforeChildren?: boolean; - afterChildren?: boolean; }; export type Tween = BaseTransition & { @@ -101,7 +96,20 @@ export type Physics = BaseTransition & { restSpeed?: number | false; }; -export type Transition = Tween | Spring | Decay | Keyframes | Physics; +export type Just = BaseTransition & { + type: 'just'; +}; + +export type TransitionProp = + | Tween + | Spring + | Decay + | Keyframes + | Physics + | BaseTransition + | false; + +export type Transition = Tween | Spring | Decay | Keyframes | Physics | Just; export type TransitionMap = { [key: string]: Transition }; diff --git a/src/utils/create-value.ts b/src/utils/create-value.ts index ebaa27646c..7f5893d02f 100644 --- a/src/utils/create-value.ts +++ b/src/utils/create-value.ts @@ -30,6 +30,8 @@ export const bindValuesToRef = ( const domStyler = styler(ref.current); values.forEach((value, key) => { - if (!value.onRender) value.setOnRender((v: any) => domStyler.set(key, v)); + if (!value.hasOnRender()) { + value.setOnRender((v: any) => domStyler.set(key, v)); + } }); }; diff --git a/src/utils/default-transitions.ts b/src/utils/default-transitions.ts new file mode 100644 index 0000000000..1bc9eb657f --- /dev/null +++ b/src/utils/default-transitions.ts @@ -0,0 +1,43 @@ +import { Transition } from '../motion/types'; + +const underDampedSpring = () => ({ + type: 'spring', + stiffness: 500, + damping: 25, + restDelta: 0.5, + restSpeed: 10 +}); + +const overDampedSpring = (to: string | number) => ({ + type: 'spring', + stiffness: 700, + damping: to === 0 ? 100 : 35 +}); + +const linearTween = () => ({ + ease: 'linear', + duration: 250 +}); + +const defaultTransitions = { + x: underDampedSpring, + y: underDampedSpring, + z: underDampedSpring, + rotate: underDampedSpring, + rotateX: underDampedSpring, + rotateY: underDampedSpring, + rotateZ: underDampedSpring, + scaleX: overDampedSpring, + scaleY: overDampedSpring, + scale: overDampedSpring, + opacity: linearTween, + backgroundColor: linearTween, + color: linearTween, + default: overDampedSpring +}; + +export default (valueKey: string, to: string | number): Transition => { + const transitionFactory = + defaultTransitions[valueKey] || defaultTransitions.default; + return { ...transitionFactory(to), to }; +}; diff --git a/src/utils/transitions.ts b/src/utils/transitions.ts index b94f5a8d46..808672d1cc 100644 --- a/src/utils/transitions.ts +++ b/src/utils/transitions.ts @@ -1,14 +1,33 @@ -import { tween, spring, keyframes, decay, physics, easing } from 'popmotion'; -import { Transition, TransitionMap, Tween, Keyframes } from '../motion/types'; +import { + action, + tween, + spring, + keyframes, + decay, + physics, + easing, + Action +} from 'popmotion'; +import { + Transition, + TransitionProp, + Tween, + Keyframes, + EasingFunction, + TransitionMap, + Just +} from '../motion/types'; +import getDefaultTransition from './default-transitions'; import { invariant } from 'hey-listen'; -const transitions = { tween, spring, keyframes, decay, physics }; +type JustProps = { to: string | number }; +const just = ({ to }: JustProps): Action => + action(({ update, complete }) => { + update(to); + complete(); + }); -const defaultTransition = { - type: 'spring', - stiffness: 800, - damping: 15 -}; +const transitions = { tween, spring, keyframes, decay, physics, just }; const { linear, @@ -24,7 +43,7 @@ const { anticipate } = easing; -const easingLookup: { [key: string]: (num: number) => number } = { +const easingLookup: { [key: string]: EasingFunction } = { linear, easeIn, easeOut, @@ -65,26 +84,43 @@ const transitionOptionParser = { keyframes: ({ from, to, ...opts }: Keyframes) => opts }; -const preprocessOptions = ( - type: string, - opts: Partial -): Partial => +const getTransition = ( + valueKey: string, + to: string | number, + transitionProp?: TransitionProp +): Transition => { + if (transitionProp !== undefined) { + let transition: Transition = {}; + + if (transitionProp === false || transitionProp[valueKey] === false) { + transition = { type: 'just' }; + } else { + transition = + transitionProp[valueKey] || (transitionProp as TransitionMap).default; + } + + return { ...transition, to }; + } + + return getDefaultTransition(valueKey, to); +}; + +const preprocessOptions = (type: string, opts: Transition): Transition => transitionOptionParser[type] ? transitionOptionParser[type](opts) : opts; export default ( valueKey: string, to: string | number, - transition?: Transition + transition?: TransitionProp ) => { - const transitionDefinition = transition - ? transition[valueKey] || - (transition as TransitionMap).default || - transition - : defaultTransition; + const { type = 'tween', ...transitionDefinition } = getTransition( + valueKey, + to, + transition + ); - const type = transitionDefinition.type || 'tween'; const action = transitions[type]; - const opts = preprocessOptions(type, { ...transitionDefinition, to }); + const opts: Transition = preprocessOptions(type, transitionDefinition); return [action, opts]; }; From 3207e83f311f3ea84a98d5c0679cff53827adff5 Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Wed, 21 Nov 2018 15:25:19 +0000 Subject: [PATCH 14/44] adding transitions --- src/utils/transitions.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/utils/transitions.ts b/src/utils/transitions.ts index 808672d1cc..f0d9741f77 100644 --- a/src/utils/transitions.ts +++ b/src/utils/transitions.ts @@ -14,14 +14,14 @@ import { Tween, Keyframes, EasingFunction, - TransitionMap, - Just + TransitionMap } from '../motion/types'; import getDefaultTransition from './default-transitions'; import { invariant } from 'hey-listen'; +import { ActionFactory } from '../motion-value'; type JustProps = { to: string | number }; -const just = ({ to }: JustProps): Action => +const just: ActionFactory = ({ to }: JustProps): Action => action(({ update, complete }) => { update(to); complete(); @@ -112,14 +112,14 @@ export default ( valueKey: string, to: string | number, transition?: TransitionProp -) => { +): [ActionFactory, Transition] => { const { type = 'tween', ...transitionDefinition } = getTransition( valueKey, to, transition ); - const action = transitions[type]; + const action: ActionFactory = transitions[type]; const opts: Transition = preprocessOptions(type, transitionDefinition); return [action, opts]; From b20edcd0d595dcc64931ec5c237ef2ccda1b3919 Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Wed, 21 Nov 2018 16:27:51 +0000 Subject: [PATCH 15/44] adding cycle functionality --- TODO.md | 8 +------- src/hooks/use-pose.ts | 20 +++++++++++++++++--- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/TODO.md b/TODO.md index 75e7ed3c4b..5b42bbae83 100644 --- a/TODO.md +++ b/TODO.md @@ -1,12 +1,6 @@ # TODOs -## Build system -- Add Rollup for production bundle generation (will save multiple kb) - ## Features -- `false` for `transition` support. - Fix prop types on `motion` -- Add intelligent defaults -- Coordination across children (ie `staggerChildren`) -- Gestures +- Coordination across children (ie `staggerChildren`): (explore later) - `setPose.cycle` \ No newline at end of file diff --git a/src/hooks/use-pose.ts b/src/hooks/use-pose.ts index 94a59e9d59..3d328fbeee 100644 --- a/src/hooks/use-pose.ts +++ b/src/hooks/use-pose.ts @@ -1,16 +1,30 @@ import { useMemo } from 'react'; import motionValue, { MotionValue } from '../motion-value'; -type PoseSetter = (pose: string | string[]) => void; +type PoseSetter = { + (pose: string | string[]): void; + cycle: () => void; +}; -const usePose = (initPose = 'default') => { +const usePose = (initPose: string | string[] = 'default', poses?: string[]) => { return useMemo((): [MotionValue, PoseSetter] => { const pose = motionValue(initPose); const setPose: PoseSetter = newPose => pose.set(newPose); + // Add cycle functionality + let i = 0; + setPose.cycle = () => { + if (!poses) return; + + const numPoses = poses.length; + i++; + if (i >= numPoses) i = 0; + setPose(poses[i]); + }; + return [pose, setPose]; - }, []); + }, poses || []); }; export default usePose; From 5f2fe5d579e44075d11d47e181e91548cc35d07c Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Thu, 22 Nov 2018 15:43:18 +0000 Subject: [PATCH 16/44] adding latest tests --- jest.setup.ts | 2 + package.json | 6 +- src/hooks/use-pose-resolver.ts | 9 +- src/hooks/use-pose.ts | 11 +- src/hooks/use-posed-values.ts | 4 +- src/hooks/use-subsequent-render-effect.ts | 15 +++ src/motion/__tests__/component.test.tsx | 146 +++++++++++++++++++++ src/motion/{component.tsx => component.ts} | 11 +- src/motion/index.ts | 19 ++- src/motion/supported-elements.ts | 7 +- src/motion/types.ts | 24 ++-- yarn.lock | 64 ++++++++- 12 files changed, 281 insertions(+), 37 deletions(-) create mode 100644 jest.setup.ts create mode 100644 src/hooks/use-subsequent-render-effect.ts create mode 100644 src/motion/__tests__/component.test.tsx rename src/motion/{component.tsx => component.ts} (79%) diff --git a/jest.setup.ts b/jest.setup.ts new file mode 100644 index 0000000000..411a80cd5c --- /dev/null +++ b/jest.setup.ts @@ -0,0 +1,2 @@ +import 'jest-dom/extend-expect'; +import 'react-testing-library/cleanup-after-each'; diff --git a/package.json b/package.json index 244df033ea..9b8e5afff4 100644 --- a/package.json +++ b/package.json @@ -29,12 +29,14 @@ "fork-ts-checker-webpack-plugin": "^0.4.15", "husky": "^1.1.4", "jest": "^23.6.0", + "jest-dom": "^2.1.1", "lint-staged": "^8.0.4", "prettier": "^1.15.2", "progress-bar-webpack-plugin": "^1.11.0", "react": "^16.7.0-alpha.2", "react-dev-utils": "^6.1.1", "react-dom": "^16.7.0-alpha.2", + "react-testing-library": "^5.3.0", "rollup": "^0.67.3", "rollup-plugin-node-resolve": "^3.4.0", "rollup-plugin-replace": "^2.1.0", @@ -74,7 +76,7 @@ }, "jest": { "preset": "ts-jest", - "testEnvironment": "node", - "rootDir": "src" + "rootDir": "src", + "setupTestFrameworkScriptFile": "/../jest.setup.ts" } } diff --git a/src/hooks/use-pose-resolver.ts b/src/hooks/use-pose-resolver.ts index 4f5db29213..ddfbc49c8b 100644 --- a/src/hooks/use-pose-resolver.ts +++ b/src/hooks/use-pose-resolver.ts @@ -12,6 +12,7 @@ import { Pose, MotionValueMap } from '../motion/types'; +import useSubsequentRenderEffect from '../hooks/use-subsequent-render-effect'; import { complex } from 'style-value-types'; type PoseSubscriber = (v: string | string[]) => void; @@ -22,7 +23,7 @@ const isAnimatable = (value: string | number) => const createPoseResolver = ( values: MotionValueMap, config: PoseConfig, - { onTransitionEnd, props }: MotionProps, + { onPoseComplete, props }: MotionProps, ref: RefObject ) => (poseList: string[]) => { const poseTransitions: Promise[] = []; @@ -84,7 +85,8 @@ const createPoseResolver = ( }); return Promise.all(poseTransitions).then(() => { - onTransitionEnd && onTransitionEnd(); + onPoseComplete && + onPoseComplete(resolveCurrent(values), resolveVelocity(values)); }); }; @@ -103,7 +105,8 @@ const usePoseResolver = ( const poseList = !poseIsSubscription ? poseToArray(pose as string | string[]) : []; - useEffect(() => { + + useSubsequentRenderEffect(() => { if (!poseIsSubscription) poseResolver(poseList); }, poseList); diff --git a/src/hooks/use-pose.ts b/src/hooks/use-pose.ts index 3d328fbeee..fd061b5191 100644 --- a/src/hooks/use-pose.ts +++ b/src/hooks/use-pose.ts @@ -8,12 +8,19 @@ type PoseSetter = { const usePose = (initPose: string | string[] = 'default', poses?: string[]) => { return useMemo((): [MotionValue, PoseSetter] => { + let i = 0; + const pose = motionValue(initPose); - const setPose: PoseSetter = newPose => pose.set(newPose); + const setPose: PoseSetter = newPose => { + if (poses && typeof newPose === 'string') { + const poseIndex = poses.indexOf(newPose); + i = poseIndex > -1 ? poseIndex : i; + } + pose.set(newPose); + }; // Add cycle functionality - let i = 0; setPose.cycle = () => { if (!poses) return; diff --git a/src/hooks/use-posed-values.ts b/src/hooks/use-posed-values.ts index cc26460074..11164dd102 100644 --- a/src/hooks/use-posed-values.ts +++ b/src/hooks/use-posed-values.ts @@ -6,7 +6,7 @@ import { createValuesFromPose, bindValuesToRef } from '../utils/create-value'; export default ( config: PoseConfig, - props: MotionProps, + { onPoseComplete, ...props }: MotionProps, ref: RefObject ): [MotionValueMap, Partial] => { const values: MotionValueMap = useRef(new Map()).current; @@ -22,7 +22,7 @@ export default ( if (prop instanceof MotionValue) { values.set(key, prop); - } else { + } else if (key !== 'pose') { returnedProps[key] = prop; } }); diff --git a/src/hooks/use-subsequent-render-effect.ts b/src/hooks/use-subsequent-render-effect.ts new file mode 100644 index 0000000000..bb38eaf436 --- /dev/null +++ b/src/hooks/use-subsequent-render-effect.ts @@ -0,0 +1,15 @@ +import { useRef, useEffect } from 'react'; + +const useSubsequentRenderEffect = (callback: () => void, conditions: any[]) => { + const isInitialRender = useRef(true); + + return useEffect(() => { + if (isInitialRender.current) { + isInitialRender.current = false; + } else { + return callback(); + } + }, conditions); +}; + +export default useSubsequentRenderEffect; diff --git a/src/motion/__tests__/component.test.tsx b/src/motion/__tests__/component.test.tsx new file mode 100644 index 0000000000..8e7fe6bfc2 --- /dev/null +++ b/src/motion/__tests__/component.test.tsx @@ -0,0 +1,146 @@ +import { render } from 'react-testing-library'; +import motion from '../'; +import * as React from 'react'; + +//import useMotionValue from '../../hooks/use-motion-value'; +// +//import styled from 'styled-components'; + +// test('motion component renders', () => { +// const Box = motion.div(); +// const { container } = render(); +// expect(container.firstChild).toBeTruthy(); +// }); + +// test('motion component renders custom component', () => { +// const Box = motion.div(); +// const { getByTestId } = render( +// +//
+// +// ); +// expect(getByTestId('child')).toBeTruthy(); +// }); + +test('motion component accepts function ref', () => { + const Box = motion.div(); + + return new Promise(resolve => { + const setRef = (ref: Element) => { + console.log(ref); + resolve(); + }; + + const Container = () => { + return ; + }; + + render(); + + // const Container = () => { + // const setRef = (n?: Element) => { + // console.log(n); + // n ? resolve() : reject(); + // }; + // return ; + // }; + + // render(); + }); +}); + +// test('motion component accepts createRef', () => { +// const Box = motion.div(); + +// const { container } = render(); +// expect(container.firstChild).toBeTruthy(); +// }); + +// test('motion component generates style attr from pose', () => { +// const Box = motion.div({ +// default: { backgroundColor: '#fff' } +// }); +// const { container } = render(); +// expect(container.firstChild).toHaveStyle('background-color: #fff'); +// }); + +// test('motion component overwrites provided style attr with pose', () => { +// const Box = motion.div({ +// default: { backgroundColor: '#fff' } +// }); +// const { container } = render( +// +// ); +// expect(container.firstChild).toHaveStyle( +// 'background-color: #fff; left: 500px' +// ); +// }); + +// test('motion component renders styled component and overwrites style', () => { +// const Box = styled.div` +// background: #fff; +// `; +// const MotionBox = motion(Box)({ +// default: { background: '#000' } +// }); + +// const { container } = render(); + +// expect(container.firstChild).toHaveStyle('background: #000'); +// }); + +// test('motion component takes styles of defined initial pose', () => { +// const Box = motion.div({ +// default: { x: 0 }, +// foo: { x: 100, transitionEnd: { display: 'none' } } +// }); +// const { container } = render(); +// expect(container.firstChild).toHaveStyle( +// 'transform: translateX(100px) translateZ(0); display: none;' +// ); +// }); + +// test("motion component doesn't forward pose prop", () => { +// const Box = motion.div({ default: {} }); +// const { container } = render(); +// expect(container.firstChild).not.toHaveAttribute('pose'); +// }); + +// test('motion component accepts motion value', () => { +// const Box = motion.div(); + +// const Component = () => { +// const x = useMotionValue(800); +// return ; +// }; + +// const { container } = render(); +// expect(container.firstChild).toHaveStyle( +// 'transform: translateX(800px) translateZ(0)' +// ); +// }); + +// test('motion component fires onPoseComplete', done => { +// const Box = motion.div({ +// foo: { x: 100 }, +// bar: { x: 0, transition: false } +// }); + +// const { rerender } = render(); + +// rerender( +// { +// // We would ideally like to inspect the DOM itself at this point +// // but the node seems to be unmounted after sync ops have flushed +// expect(current.x).toBe(0); +// done(); +// }} +// /> +// ); +// }); + +// usePose + +// useTransform diff --git a/src/motion/component.tsx b/src/motion/component.ts similarity index 79% rename from src/motion/component.tsx rename to src/motion/component.ts index 162209dd13..4697219f48 100644 --- a/src/motion/component.tsx +++ b/src/motion/component.ts @@ -6,12 +6,9 @@ import usePosedValues from '../hooks/use-posed-values'; import usePoseResolver from '../hooks/use-pose-resolver'; import useStyleAttr from '../hooks/use-style-attr'; -// TODO: tighten component type checking -type Props = { [key: string]: any }; - -const createMotionComponent = ( - Component: string | ComponentType -): ComponentFactory => (poseConfig = {}) => { +const createMotionComponent =

( + Component: string | ComponentType

+): ComponentFactory

=> (poseConfig = {}): ComponentType

=> { const MotionComponent = (props: MotionProps, externalRef?: Ref) => { const ref = useExternalRef(externalRef); const config = useConfig(poseConfig, props); @@ -21,7 +18,7 @@ const createMotionComponent = ( usePoseResolver(values, config, props, ref); - return createElement(Component, { + return createElement(Component, { ...componentProps, ref, style: useStyleAttr(values, props.style) diff --git a/src/motion/index.ts b/src/motion/index.ts index 58e94ab34e..6e9d698e54 100644 --- a/src/motion/index.ts +++ b/src/motion/index.ts @@ -1,10 +1,23 @@ +import { HTMLProps, SVGProps, ComponentType } from 'react'; import createMotionComponent from './component'; -import supportedElements from './supported-elements'; -import { Motion } from './types'; +import { htmlElements, svgElements } from './supported-elements'; +import { ComponentFactory, MotionProps } from './types'; + +export type Motion = { + (component: ComponentType): ComponentFactory< + (HTMLProps | SVGProps) & MotionProps + >; + [key: string]: ComponentFactory< + (HTMLProps | SVGProps) & MotionProps + >; +}; const motion: Motion = createMotionComponent as Motion; -supportedElements.forEach( +htmlElements.forEach( + element => (motion[element] = createMotionComponent(element)) +); +svgElements.forEach( element => (motion[element] = createMotionComponent(element)) ); diff --git a/src/motion/supported-elements.ts b/src/motion/supported-elements.ts index 984834c011..efee76db34 100644 --- a/src/motion/supported-elements.ts +++ b/src/motion/supported-elements.ts @@ -1,4 +1,4 @@ -export default [ +export const htmlElements = [ 'a', 'article', 'aside', @@ -68,8 +68,10 @@ export default [ 'tr', 'ul', 'video', + 'svg' +]; - // SVG +export const svgElements = [ 'circle', 'clipPath', 'defs', @@ -86,7 +88,6 @@ export default [ 'radialGradient', 'rect', 'stop', - 'svg', 'text', 'tspan' ]; diff --git a/src/motion/types.ts b/src/motion/types.ts index 0d31dafcd4..73c16bf756 100644 --- a/src/motion/types.ts +++ b/src/motion/types.ts @@ -1,14 +1,9 @@ import { MotionValue } from '../motion-value'; -import { RefObject, CSSProperties, ComponentType } from 'react'; +import { CSSProperties, ComponentType, Ref } from 'react'; -export type ComponentFactory = ( +export type ComponentFactory = ( config?: PoseConfigFactory | PoseConfig -) => ComponentType; - -export type Motion = { - (component: ComponentType): ComponentFactory; - [key: string]: ComponentFactory; -}; +) => ComponentType; export type PoseConfigFactory = (props: MotionProps) => PoseConfig; @@ -18,10 +13,10 @@ export type PoseConfig = { export type MotionProps = { [key: string]: any; - ref: RefObject; - pose: string | string[] | MotionValue; - style: CSSProperties; - onTransitionEnd?: () => void; + ref?: Ref; + pose?: string | string[] | MotionValue; + style?: CSSProperties; + onPoseComplete?: (current: CurrentValues, velocity: VelocityValues) => void; }; export type EasingFunction = (v: number) => number; @@ -111,9 +106,9 @@ export type TransitionProp = export type Transition = Tween | Spring | Decay | Keyframes | Physics | Just; -export type TransitionMap = { [key: string]: Transition }; +export type TransitionMap = { [key: string]: TransitionProp }; -export type TransitionDefinition = Transition | TransitionMap; +export type TransitionDefinition = TransitionProp | TransitionMap; // Framer Motion accepts any value, not just those listed below. // Add more here as found. @@ -187,6 +182,7 @@ export type Pose = { stroke?: string; // Misc + background?: string; backgroundImage?: string; // SVG diff --git a/yarn.lock b/yarn.lock index 1b791c08b5..d1113013dc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -86,6 +86,11 @@ dependencies: any-observable "^0.3.0" +"@sheerun/mutationobserver-shim@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.2.tgz#8013f2af54a2b7d735f71560ff360d3a8176a87b" + integrity sha512-vTCdPp/T/Q3oSqwHmZ5Kpa9oI7iLtGl3RQaA/NyLHikvcrPxACkkKVr/XzkSPJWXHRhKGzVvb0urJsbMlRxi1Q== + "@types/estree@0.0.39": version "0.0.39" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" @@ -1507,6 +1512,16 @@ css-to-react-native@^2.2.2: fbjs "^0.8.5" postcss-value-parser "^3.3.0" +css@^2.2.3: + version "2.2.4" + resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929" + integrity sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw== + dependencies: + inherits "^2.0.3" + source-map "^0.6.1" + source-map-resolve "^0.5.2" + urix "^0.1.0" + cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": version "0.3.4" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.4.tgz#8cd52e8a3acfd68d3aed38ee0a640177d2f9d797" @@ -1776,6 +1791,15 @@ dns-txt@^2.0.2: dependencies: buffer-indexof "^1.0.0" +dom-testing-library@^3.12.0: + version "3.12.4" + resolved "https://registry.yarnpkg.com/dom-testing-library/-/dom-testing-library-3.12.4.tgz#393fd104563464c91c8db1b80c5b7feb1d766c72" + integrity sha512-0+HwCOhnFitZBenJFAUGiiCOmk72i5ui34sjf+i5oBFiOwe/3Jx4wNiPAjL/qAJmK76o0z50o7nRHutzSgvzgg== + dependencies: + "@sheerun/mutationobserver-shim" "^0.3.2" + pretty-format "^23.6.0" + wait-for-expect "^1.0.0" + domain-browser@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" @@ -3567,6 +3591,19 @@ jest-docblock@^23.2.0: dependencies: detect-newline "^2.1.0" +jest-dom@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/jest-dom/-/jest-dom-2.1.1.tgz#c75515ef31147bd9684c860b0cba9605638fd4dd" + integrity sha512-jE1LRnP/wVGdQy6sVJ+dPwMq6rXXuvYTnzWEb8hDwfxhQesoaaukJzZaZYi14JPpdmhrncdpUsZpagN7HjuTsw== + dependencies: + chalk "^2.4.1" + css "^2.2.3" + jest-diff "^23.6.0" + jest-matcher-utils "^23.6.0" + lodash "^4.17.11" + pretty-format "^23.6.0" + redent "^2.0.0" + jest-each@^23.6.0: version "23.6.0" resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-23.6.0.tgz#ba0c3a82a8054387016139c733a05242d3d71575" @@ -5429,6 +5466,13 @@ react-is@^16.6.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.6.3.tgz#d2d7462fcfcbe6ec0da56ad69047e47e56e7eac0" integrity sha512-u7FDWtthB4rWibG/+mFbVd5FvdI20yde86qKGx4lVUTWmPlSWQ4QxbBIrrs+HnXGbxOUlUzTAP/VDmvCwaP2yA== +react-testing-library@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/react-testing-library/-/react-testing-library-5.3.0.tgz#b88124441d8756438137b705eb26a99410de69cc" + integrity sha512-hUXurQC8b828s2Fyuyuibz1PvPbGWb5vSIDCb1ihcGVjzBP9OGnsAm6Dhpu7XqC1o/68KJ/5/QdkeiTDxS9gpw== + dependencies: + dom-testing-library "^3.12.0" + react@^16.7.0-alpha.2: version "16.7.0-alpha.2" resolved "https://registry.yarnpkg.com/react/-/react-16.7.0-alpha.2.tgz#924f2ae843a46ea82d104a8def7a599fbf2c78ce" @@ -5501,6 +5545,14 @@ recursive-readdir@2.2.2: dependencies: minimatch "3.0.4" +redent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa" + integrity sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo= + dependencies: + indent-string "^3.0.0" + strip-indent "^2.0.0" + regenerator-runtime@^0.11.0: version "0.11.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" @@ -6059,7 +6111,7 @@ source-list-map@^2.0.0: resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== -source-map-resolve@^0.5.0: +source-map-resolve@^0.5.0, source-map-resolve@^0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== @@ -6332,6 +6384,11 @@ strip-eof@^1.0.0: resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= +strip-indent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" + integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= + strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" @@ -6856,6 +6913,11 @@ w3c-hr-time@^1.0.1: dependencies: browser-process-hrtime "^0.1.2" +wait-for-expect@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/wait-for-expect/-/wait-for-expect-1.1.0.tgz#6607375c3f79d32add35cd2c87ce13f351a3d453" + integrity sha512-vQDokqxyMyknfX3luCDn16bSaRcOyH6gGuUXMIbxBLeTo6nWuEWYqMTT9a+44FmW8c2m6TRWBdNvBBjA1hwEKg== + walker@~1.0.5: version "1.0.7" resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" From 6827e85b2275c91bdbca500e1a30d056fb0a9e30 Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Fri, 23 Nov 2018 08:16:29 +0000 Subject: [PATCH 17/44] latest --- src/motion/__tests__/component.test.tsx | 29 ++++++------------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/src/motion/__tests__/component.test.tsx b/src/motion/__tests__/component.test.tsx index 8e7fe6bfc2..2b3d933a45 100644 --- a/src/motion/__tests__/component.test.tsx +++ b/src/motion/__tests__/component.test.tsx @@ -22,31 +22,16 @@ import * as React from 'react'; // expect(getByTestId('child')).toBeTruthy(); // }); -test('motion component accepts function ref', () => { +test('motion component accepts function ref', async () => { const Box = motion.div(); - return new Promise(resolve => { - const setRef = (ref: Element) => { - console.log(ref); - resolve(); - }; - - const Container = () => { - return ; - }; - - render(); - - // const Container = () => { - // const setRef = (n?: Element) => { - // console.log(n); - // n ? resolve() : reject(); - // }; - // return ; - // }; - - // render(); + const promise = new Promise(resolve => { + const Component = () => ; + const { rerender } = render(); + rerender(); }); + + await expect(promise).resolves.toBeTruthy(); }); // test('motion component accepts createRef', () => { From 0af90e95ecf53f51ed88a790bd1aea7a1aa71b25 Mon Sep 17 00:00:00 2001 From: Niels van Hoorn Date: Fri, 23 Nov 2018 08:42:37 +0100 Subject: [PATCH 18/44] Added `make test` --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 28efc4d799..88e2ec20e7 100644 --- a/Makefile +++ b/Makefile @@ -22,4 +22,7 @@ dev: bootstrap lint: bootstrap tslint --project tsconfig.json +test: bootstrap + yarn test + .PHONY: dev lint From 10c1879cc5c0e255eac73037783b099ee7841c58 Mon Sep 17 00:00:00 2001 From: Niels van Hoorn Date: Fri, 23 Nov 2018 09:00:58 +0100 Subject: [PATCH 19/44] Added .prettierrc.json --- .prettierrc.json | 6 + dev/examples/custom-transition.tsx | 54 ++-- dev/examples/dynamic-pose.tsx | 34 +- dev/examples/pose-as-array-prop.tsx | 36 +-- dev/examples/pose-as-hook.tsx | 26 +- dev/examples/pose-as-string-prop.tsx | 26 +- dev/examples/pose-children.tsx | 80 +++-- dev/examples/pose-default-override.tsx | 16 +- dev/examples/pose-default.tsx | 14 +- dev/examples/render-component.tsx | 12 +- dev/examples/render-element.tsx | 14 +- dev/inc/use-interval.ts | 18 +- dev/styled.ts | 24 +- dev/webpack/examples.tsx | 117 ++++--- dev/webpack/index.tsx | 8 +- jest.setup.ts | 4 +- package.json | 2 +- src/hooks/use-config.ts | 17 +- src/hooks/use-external-ref.ts | 23 +- src/hooks/use-motion-value.ts | 6 +- src/hooks/use-pose-resolver.ts | 218 ++++++------- src/hooks/use-pose.ts | 70 ++--- src/hooks/use-posed-values.ts | 77 +++-- src/hooks/use-style-attr.ts | 27 +- src/hooks/use-subsequent-render-effect.ts | 22 +- src/hooks/use-transform.ts | 36 +-- src/index.ts | 10 +- src/motion-value/index.ts | 288 ++++++++--------- src/motion/component.ts | 50 +-- src/motion/index.ts | 30 +- src/motion/supported-elements.ts | 180 +++++------ src/motion/types.ts | 348 ++++++++++----------- src/utils/__tests__/pose-resolvers.test.ts | 24 +- src/utils/create-value.ts | 58 ++-- src/utils/default-transitions.ts | 65 ++-- src/utils/pose-resolvers.ts | 18 +- src/utils/resolve-values.ts | 22 +- src/utils/transitions.ts | 191 +++++------ 38 files changed, 1068 insertions(+), 1203 deletions(-) create mode 100644 .prettierrc.json diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000000..fba04f25fa --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,6 @@ +{ + "printWidth": 120, + "tabWidth": 4, + "semi": false, + "trailingComma": "es5" +} diff --git a/dev/examples/custom-transition.tsx b/dev/examples/custom-transition.tsx index ff7ed8164a..0ddc4b9320 100644 --- a/dev/examples/custom-transition.tsx +++ b/dev/examples/custom-transition.tsx @@ -1,34 +1,34 @@ -import * as React from 'react'; -import { motion, usePose } from '@framer'; -import { Box } from '../styled'; -import useInterval from '../inc/use-interval'; +import * as React from "react" +import { motion, usePose } from "@framer" +import { Box } from "../styled" +import useInterval from "../inc/use-interval" const MotionBox = motion(Box)({ - ping: { - x: 100, - y: '0vh', - opacity: 0, - transition: { - x: false, - default: { duration: 4000 } + ping: { + x: 100, + y: "0vh", + opacity: 0, + transition: { + x: false, + default: { duration: 4000 }, + }, + transitionEnd: { display: "none" }, }, - transitionEnd: { display: 'none' } - }, - pong: { - x: -100, - y: '20vh', - opacity: 1, - display: 'block', - transition: { duration: 300 } - } -}); + pong: { + x: -100, + y: "20vh", + opacity: 1, + display: "block", + transition: { duration: 300 }, + }, +}) export const App = () => { - const [pose, setPose] = usePose('ping'); + const [pose, setPose] = usePose("ping") - useInterval(() => { - setPose(pose.get() === 'ping' ? 'pong' : 'ping'); - }, 1000); + useInterval(() => { + setPose(pose.get() === "ping" ? "pong" : "ping") + }, 1000) - return ; -}; + return +} diff --git a/dev/examples/dynamic-pose.tsx b/dev/examples/dynamic-pose.tsx index 10e9a14844..50445b292e 100644 --- a/dev/examples/dynamic-pose.tsx +++ b/dev/examples/dynamic-pose.tsx @@ -1,23 +1,23 @@ -import * as React from 'react'; -import { motion, usePose } from '@framer'; -import { Box } from '../styled'; -import useInterval from '../inc/use-interval'; +import * as React from "react" +import { motion, usePose } from "@framer" +import { Box } from "../styled" +import useInterval from "../inc/use-interval" const MotionBox = motion(Box)({ - ping: { - x: 100, - y: '0vh', - transition: { duration: 100 } - }, - pong: ({ target }) => ({ x: target, y: '0vh' }) -}); + ping: { + x: 100, + y: "0vh", + transition: { duration: 100 }, + }, + pong: ({ target }) => ({ x: target, y: "0vh" }), +}) export const App = () => { - const [pose, setPose] = usePose('ping'); + const [pose, setPose] = usePose("ping") - useInterval(() => { - setPose(pose.get() === 'ping' ? 'pong' : 'ping'); - }, 1000); + useInterval(() => { + setPose(pose.get() === "ping" ? "pong" : "ping") + }, 1000) - return ; -}; + return +} diff --git a/dev/examples/pose-as-array-prop.tsx b/dev/examples/pose-as-array-prop.tsx index d6c8455306..3223ff1d5c 100644 --- a/dev/examples/pose-as-array-prop.tsx +++ b/dev/examples/pose-as-array-prop.tsx @@ -1,24 +1,24 @@ -import * as React from 'react'; -import { motion } from '@framer'; -import { Box } from '../styled'; -import useInterval from '../inc/use-interval'; +import * as React from "react" +import { motion } from "@framer" +import { Box } from "../styled" +import useInterval from "../inc/use-interval" const MotionBox = motion(Box)({ - a: { scale: 2 }, - b: { scale: 0.5 }, - c: { background: '#00f' } -}); + a: { scale: 2 }, + b: { scale: 0.5 }, + c: { background: "#00f" }, +}) export const App = () => { - const [pose, setPose] = React.useState('a'); + const [pose, setPose] = React.useState("a") - useInterval( - () => { - setPose(pose === 'a' ? 'b' : 'a'); - }, - 1000, - [pose] - ); + useInterval( + () => { + setPose(pose === "a" ? "b" : "a") + }, + 1000, + [pose] + ) - return ; -}; + return +} diff --git a/dev/examples/pose-as-hook.tsx b/dev/examples/pose-as-hook.tsx index 1d6869ed37..230982c244 100644 --- a/dev/examples/pose-as-hook.tsx +++ b/dev/examples/pose-as-hook.tsx @@ -1,19 +1,19 @@ -import * as React from 'react'; -import { motion, usePose } from '@framer'; -import { Box } from '../styled'; -import useInterval from '../inc/use-interval'; +import * as React from "react" +import { motion, usePose } from "@framer" +import { Box } from "../styled" +import useInterval from "../inc/use-interval" const MotionBox = motion(Box)({ - ping: { x: 100 }, - pong: { x: -100 } -}); + ping: { x: 100 }, + pong: { x: -100 }, +}) export const App = () => { - const [pose, setPose] = usePose('ping'); + const [pose, setPose] = usePose("ping") - useInterval(() => { - setPose(pose.get() === 'ping' ? 'pong' : 'ping'); - }, 1000); + useInterval(() => { + setPose(pose.get() === "ping" ? "pong" : "ping") + }, 1000) - return ; -}; + return +} diff --git a/dev/examples/pose-as-string-prop.tsx b/dev/examples/pose-as-string-prop.tsx index 58d4e5e16f..06d1a4d678 100644 --- a/dev/examples/pose-as-string-prop.tsx +++ b/dev/examples/pose-as-string-prop.tsx @@ -1,21 +1,15 @@ -import * as React from 'react'; -import { useState } from 'react'; -import { motion } from '@framer'; -import { Box } from '../styled'; +import * as React from "react" +import { useState } from "react" +import { motion } from "@framer" +import { Box } from "../styled" const MotionBox = motion(Box)({ - default: { scale: 1 }, - pressed: { scale: 1.2 } -}); + default: { scale: 1 }, + pressed: { scale: 1.2 }, +}) export const App = () => { - const [pose, setPose] = useState('default'); + const [pose, setPose] = useState("default") - return ( - setPose('pressed')} - onMouseUp={() => setPose('default')} - /> - ); -}; + return setPose("pressed")} onMouseUp={() => setPose("default")} /> +} diff --git a/dev/examples/pose-children.tsx b/dev/examples/pose-children.tsx index 1319fb383d..35b7871456 100644 --- a/dev/examples/pose-children.tsx +++ b/dev/examples/pose-children.tsx @@ -1,53 +1,51 @@ -import * as React from 'react'; -import { useState } from 'react'; -import { motion } from '@framer'; -import { Box } from '../styled'; -import useInterval from '../inc/use-interval'; +import * as React from "react" +import { useState } from "react" +import { motion } from "@framer" +import { Box } from "../styled" +import useInterval from "../inc/use-interval" const Parent = motion.div({ - visible: { - opacity: 1, - y: 0, - transition: { - staggerChildren: 50 - } - }, - hidden: { opacity: 0, y: 100 } -}); + visible: { + opacity: 1, + y: 0, + transition: { + staggerChildren: 50, + }, + }, + hidden: { opacity: 0, y: 100 }, +}) const Child = motion.div({ - visible: { opacity: 1, x: 0 }, - hidden: { opacity: 0, x: -100 } -}); + visible: { opacity: 1, x: 0 }, + hidden: { opacity: 0, x: -100 }, +}) const parentStyles = { - width: 400, - height: 500, - background: 'red', - padding: 10 -}; + width: 400, + height: 500, + background: "red", + padding: 10, +} const childStyles = { - width: '100%', - height: 50, - background: 'black', - marginBottom: 30 -}; + width: "100%", + height: 50, + background: "black", + marginBottom: 30, +} export const App = () => { - const [pose, setPose] = useState('hidden'); + const [pose, setPose] = useState("hidden") - useInterval(() => setPose(pose === 'hidden' ? 'visible' : 'hidden'), 2000, [ - pose - ]); + useInterval(() => setPose(pose === "hidden" ? "visible" : "hidden"), 2000, [pose]) - return ( - -

- - - -
- - ); -}; + return ( + +
+ + + +
+
+ ) +} diff --git a/dev/examples/pose-default-override.tsx b/dev/examples/pose-default-override.tsx index 47a77c1ca1..1d99fb3701 100644 --- a/dev/examples/pose-default-override.tsx +++ b/dev/examples/pose-default-override.tsx @@ -1,12 +1,12 @@ -import * as React from 'react'; -import { motion } from '@framer'; -import { Box } from '../styled'; +import * as React from "react" +import { motion } from "@framer" +import { Box } from "../styled" const MotionBox = motion(Box)({ - default: { rotate: 0, backgroundColor: '#f00' }, - foo: { rotate: 45, backgroundColor: '#0f0' } -}); + default: { rotate: 0, backgroundColor: "#f00" }, + foo: { rotate: 45, backgroundColor: "#0f0" }, +}) export const App = () => { - return ; -}; + return +} diff --git a/dev/examples/pose-default.tsx b/dev/examples/pose-default.tsx index dd6d387ad6..dc7ea6a8ca 100644 --- a/dev/examples/pose-default.tsx +++ b/dev/examples/pose-default.tsx @@ -1,11 +1,11 @@ -import * as React from 'react'; -import { motion } from '@framer'; -import { Box } from '../styled'; +import * as React from "react" +import { motion } from "@framer" +import { Box } from "../styled" const MotionBox = motion(Box)({ - default: { scale: 2, backgroundColor: '#f00' } -}); + default: { scale: 2, backgroundColor: "#f00" }, +}) export const App = () => { - return ; -}; + return +} diff --git a/dev/examples/render-component.tsx b/dev/examples/render-component.tsx index 19b79c0b87..2051978946 100644 --- a/dev/examples/render-component.tsx +++ b/dev/examples/render-component.tsx @@ -1,9 +1,9 @@ -import * as React from 'react'; -import { motion } from '@framer'; -import { Box } from '../styled'; +import * as React from "react" +import { motion } from "@framer" +import { Box } from "../styled" -const MotionBox = motion(Box)(); +const MotionBox = motion(Box)() export const App = () => { - return ; -}; + return +} diff --git a/dev/examples/render-element.tsx b/dev/examples/render-element.tsx index 63781e7fa4..1cb1636158 100644 --- a/dev/examples/render-element.tsx +++ b/dev/examples/render-element.tsx @@ -1,12 +1,8 @@ -import * as React from 'react'; -import { motion } from '@framer'; +import * as React from "react" +import { motion } from "@framer" -const MotionBox = motion.ul(); +const MotionBox = motion.ul() export const App = () => { - return ( - - ); -}; + return +} diff --git a/dev/inc/use-interval.ts b/dev/inc/use-interval.ts index 916fec3b70..791a3e05a0 100644 --- a/dev/inc/use-interval.ts +++ b/dev/inc/use-interval.ts @@ -1,12 +1,8 @@ -import { useEffect } from 'react'; +import { useEffect } from "react" -export default ( - callback: () => void, - interval: number = 1000, - args: any[] = [] -) => { - useEffect(() => { - const int = setInterval(callback, interval); - return () => clearInterval(int); - }, args); -}; +export default (callback: () => void, interval: number = 1000, args: any[] = []) => { + useEffect(() => { + const int = setInterval(callback, interval) + return () => clearInterval(int) + }, args) +} diff --git a/dev/styled.ts b/dev/styled.ts index 9591a4b89e..a7ebbb4767 100644 --- a/dev/styled.ts +++ b/dev/styled.ts @@ -1,16 +1,16 @@ -import styled from 'styled-components'; +import styled from "styled-components" export const Container = styled.div` - min-width: 100vw; - min-height: 100vh; - background: #343d48; - display: flex; - align-items: center; - justify-content: center; -`; + min-width: 100vw; + min-height: 100vh; + background: #343d48; + display: flex; + align-items: center; + justify-content: center; +` export const Box = styled.div` - width: 100px; - height: 100px; - background: #fff; -`; + width: 100px; + height: 100px; + background: #fff; +` diff --git a/dev/webpack/examples.tsx b/dev/webpack/examples.tsx index 8b8d27a852..aea6adab8e 100644 --- a/dev/webpack/examples.tsx +++ b/dev/webpack/examples.tsx @@ -1,78 +1,73 @@ -import * as React from 'react'; -import { basename, extname } from 'path'; -import { Container } from '../styled'; +import * as React from "react" +import { basename, extname } from "path" +import { Container } from "../styled" -const context = require['context']('../examples', true, /\.(tsx?)$/); +const context = require["context"]("../examples", true, /\.(tsx?)$/) const fileName = (pathName: string) => { - return basename(pathName, extname(pathName)); -}; + return basename(pathName, extname(pathName)) +} const style: React.CSSProperties = { - font: "16px/1.6em 'Helvetica Neue'", - textRendering: 'optimizeLegibility', - margin: '64px' -}; + font: "16px/1.6em 'Helvetica Neue'", + textRendering: "optimizeLegibility", + margin: "64px", +} const Code: React.SFC = props => { - return ( - - {props.children} - - ); -}; + return {props.children} +} const ExampleList = () => { - return ( -
-

Framer Examples

-

- You can edit any of these in the dev/examples folder. -

-
    - {context.keys().map((name: string) => ( -
  • - {fileName(name)}{' '} - {name.replace('./', 'examples/')} -
  • - ))} -
-
- ); -}; + return ( +
+

Framer Examples

+

+ You can edit any of these in the dev/examples folder. +

+
    + {context.keys().map((name: string) => ( +
  • + {fileName(name)}{" "} + {name.replace("./", "examples/")} +
  • + ))} +
+
+ ) +} export class App extends React.Component { - render() { - const url = new URL(window.location.href); - const example = url.searchParams.get('example'); + render() { + const url = new URL(window.location.href) + const example = url.searchParams.get("example") - if (!example) { - return ; - } + if (!example) { + return + } - const exampleName = fileName(example); - const exampleApp = require(`../examples/${exampleName}`); + const exampleName = fileName(example) + const exampleApp = require(`../examples/${exampleName}`) - if (exampleApp) { - if (exampleApp.App) { - // Update the document title to the example - document.title = exampleName; + if (exampleApp) { + if (exampleApp.App) { + // Update the document title to the example + document.title = exampleName - return ( - - - - ); - } else { - return ( -

- examples/{example} does not have a export named{' '} - App -

- ); - } - } + return ( + + + + ) + } else { + return ( +

+ examples/{example} does not have a export named App +

+ ) + } + } - return ; - } + return + } } diff --git a/dev/webpack/index.tsx b/dev/webpack/index.tsx index 3bab16a925..c6058686b9 100644 --- a/dev/webpack/index.tsx +++ b/dev/webpack/index.tsx @@ -1,6 +1,6 @@ -import * as React from 'react'; -import * as ReactDOM from 'react-dom'; +import * as React from "react" +import * as ReactDOM from "react-dom" -const App = require('./examples').App; +const App = require("./examples").App -ReactDOM.render(, document.getElementById('root')); +ReactDOM.render(, document.getElementById("root")) diff --git a/jest.setup.ts b/jest.setup.ts index 411a80cd5c..644d82175c 100644 --- a/jest.setup.ts +++ b/jest.setup.ts @@ -1,2 +1,2 @@ -import 'jest-dom/extend-expect'; -import 'react-testing-library/cleanup-after-each'; +import "jest-dom/extend-expect" +import "react-testing-library/cleanup-after-each" diff --git a/package.json b/package.json index 9b8e5afff4..876c266c31 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ }, "lint-staged": { "*.{ts,tsx}": [ - "prettier --write", + "prettier --write --config .prettierrc.json", "git add" ] }, diff --git a/src/hooks/use-config.ts b/src/hooks/use-config.ts index 81ae38436a..11aaf6203d 100644 --- a/src/hooks/use-config.ts +++ b/src/hooks/use-config.ts @@ -1,14 +1,9 @@ -import { useMemo } from 'react'; -import { PoseConfig, PoseConfigFactory, MotionProps } from '../motion/types'; +import { useMemo } from "react" +import { PoseConfig, PoseConfigFactory, MotionProps } from "../motion/types" -const isResolver = ( - config: PoseConfig | PoseConfigFactory -): config is PoseConfigFactory => typeof config === 'function'; +const isResolver = (config: PoseConfig | PoseConfigFactory): config is PoseConfigFactory => typeof config === "function" -const useConfig = ( - baseConfig: PoseConfig | PoseConfigFactory, - props: MotionProps -) => - useMemo(() => (isResolver(baseConfig) ? baseConfig(props) : baseConfig), []); +const useConfig = (baseConfig: PoseConfig | PoseConfigFactory, props: MotionProps) => + useMemo(() => (isResolver(baseConfig) ? baseConfig(props) : baseConfig), []) -export default useConfig; +export default useConfig diff --git a/src/hooks/use-external-ref.ts b/src/hooks/use-external-ref.ts index f7a68dc009..fda136c1a8 100644 --- a/src/hooks/use-external-ref.ts +++ b/src/hooks/use-external-ref.ts @@ -1,18 +1,17 @@ -import { useEffect, useRef, Ref, MutableRefObject } from 'react'; +import { useEffect, useRef, Ref, MutableRefObject } from "react" const useExternalRef = (external?: Ref) => { - const ref = - !external || typeof external === 'function' ? useRef(null) : external; + const ref = !external || typeof external === "function" ? useRef(null) : external - useEffect(() => { - if (external && typeof external === 'function') { - external((ref as MutableRefObject).current); + useEffect(() => { + if (external && typeof external === "function") { + external((ref as MutableRefObject).current) - return () => external(null); - } - }); + return () => external(null) + } + }) - return ref; -}; + return ref +} -export default useExternalRef; +export default useExternalRef diff --git a/src/hooks/use-motion-value.ts b/src/hooks/use-motion-value.ts index 04504f15a4..23fbc4616e 100644 --- a/src/hooks/use-motion-value.ts +++ b/src/hooks/use-motion-value.ts @@ -1,4 +1,4 @@ -import { useMemo } from 'react'; -import motionValue from '../motion-value'; +import { useMemo } from "react" +import motionValue from "../motion-value" -export default (init: number | string) => useMemo(() => motionValue(init), []); +export default (init: number | string) => useMemo(() => motionValue(init), []) diff --git a/src/hooks/use-pose-resolver.ts b/src/hooks/use-pose-resolver.ts index ddfbc49c8b..45be8fb00f 100644 --- a/src/hooks/use-pose-resolver.ts +++ b/src/hooks/use-pose-resolver.ts @@ -1,129 +1,111 @@ -import { useRef, useEffect, MutableRefObject, RefObject } from 'react'; -import { invariant } from 'hey-listen'; -import getTransition from '../utils/transitions'; -import { poseToArray } from '../utils/pose-resolvers'; -import { resolveCurrent, resolveVelocity } from '../utils/resolve-values'; -import { MotionValue } from '../motion-value'; -import { createValuesFromPose, bindValuesToRef } from '../utils/create-value'; -import { - PoseConfig, - MotionProps, - PoseResolver, - Pose, - MotionValueMap -} from '../motion/types'; -import useSubsequentRenderEffect from '../hooks/use-subsequent-render-effect'; -import { complex } from 'style-value-types'; - -type PoseSubscriber = (v: string | string[]) => void; - -const isAnimatable = (value: string | number) => - typeof value === 'number' || complex.test(value); +import { useRef, useEffect, MutableRefObject, RefObject } from "react" +import { invariant } from "hey-listen" +import getTransition from "../utils/transitions" +import { poseToArray } from "../utils/pose-resolvers" +import { resolveCurrent, resolveVelocity } from "../utils/resolve-values" +import { MotionValue } from "../motion-value" +import { createValuesFromPose, bindValuesToRef } from "../utils/create-value" +import { PoseConfig, MotionProps, PoseResolver, Pose, MotionValueMap } from "../motion/types" +import useSubsequentRenderEffect from "../hooks/use-subsequent-render-effect" +import { complex } from "style-value-types" -const createPoseResolver = ( - values: MotionValueMap, - config: PoseConfig, - { onPoseComplete, props }: MotionProps, - ref: RefObject -) => (poseList: string[]) => { - const poseTransitions: Promise[] = []; - - poseList.reverse().forEach(poseKey => { - invariant( - config[poseKey] !== undefined, - `Pose with name ${poseKey} not found.` - ); +type PoseSubscriber = (v: string | string[]) => void - const pose: Pose = - typeof config[poseKey] === 'function' - ? (config[poseKey] as PoseResolver)( - props, - resolveCurrent(values), - resolveVelocity(values) - ) - : (config[poseKey] as Pose); +const isAnimatable = (value: string | number) => typeof value === "number" || complex.test(value) - const { transition, transitionEnd, ...thisPose } = pose; +const createPoseResolver = ( + values: MotionValueMap, + config: PoseConfig, + { onPoseComplete, props }: MotionProps, + ref: RefObject +) => (poseList: string[]) => { + const poseTransitions: Promise[] = [] + + poseList.reverse().forEach(poseKey => { + invariant(config[poseKey] !== undefined, `Pose with name ${poseKey} not found.`) + + const pose: Pose = + typeof config[poseKey] === "function" + ? (config[poseKey] as PoseResolver)(props, resolveCurrent(values), resolveVelocity(values)) + : (config[poseKey] as Pose) + + const { transition, transitionEnd, ...thisPose } = pose + + const valueTransitions: Promise[] = [] + + Object.keys(thisPose).forEach(valueKey => { + const target = thisPose[valueKey] + + // If this value doesn't exist in the value map, create it + if (!values.has(valueKey)) { + createValuesFromPose(values, pose) + bindValuesToRef(values, ref) + } + + const value: MotionValue = values.get(valueKey) as MotionValue + + if (isAnimatable(target)) { + // If we can animate this value, for instance 100, '100px' or '#fff' + const [action, opts] = getTransition(valueKey, target, transition) + + if (value) { + valueTransitions.push(value.control(action, opts)) + } + } else { + // If this is not an animatable value, for instance `display: block`, just set it. + value.set(target) + } + }) + + poseTransitions.push( + Promise.all(valueTransitions).then(() => { + if (!transitionEnd) return + + Object.keys(transitionEnd).forEach(valueKey => { + if (values.has(valueKey)) { + ;(values.get(valueKey) as MotionValue).set(transitionEnd[valueKey]) + } + }) + }) + ) + }) + + return Promise.all(poseTransitions).then(() => { + onPoseComplete && onPoseComplete(resolveCurrent(values), resolveVelocity(values)) + }) +} - const valueTransitions: Promise[] = []; +const usePoseResolver = ( + values: Map, + config: PoseConfig, + props: MotionProps, + ref: RefObject +) => { + const poseSubscriber: MutableRefObject = useRef(null) + const { pose } = props + const poseIsSubscription = pose instanceof MotionValue + const poseResolver = createPoseResolver(values, config, props, ref) - Object.keys(thisPose).forEach(valueKey => { - const target = thisPose[valueKey]; + // If we're controlled by props, fire resolver with latest pose + const poseList = !poseIsSubscription ? poseToArray(pose as string | string[]) : [] - // If this value doesn't exist in the value map, create it - if (!values.has(valueKey)) { - createValuesFromPose(values, pose); - bindValuesToRef(values, ref); - } + useSubsequentRenderEffect(() => { + if (!poseIsSubscription) poseResolver(poseList) + }, poseList) - const value: MotionValue = values.get(valueKey) as MotionValue; + // Or if we're using a pose subscription, manage subscriptions + useEffect(() => { + if (!poseIsSubscription) return - if (isAnimatable(target)) { - // If we can animate this value, for instance 100, '100px' or '#fff' - const [action, opts] = getTransition(valueKey, target, transition); + poseSubscriber.current = (v: string | string[]) => poseResolver(poseToArray(v)) + ;(pose as MotionValue).addSubscriber(poseSubscriber.current) - if (value) { - valueTransitions.push(value.control(action, opts)); + return () => { + if (poseSubscriber.current) { + ;(pose as MotionValue).removeSubscriber(poseSubscriber.current) + } } - } else { - // If this is not an animatable value, for instance `display: block`, just set it. - value.set(target); - } - }); - - poseTransitions.push( - Promise.all(valueTransitions).then(() => { - if (!transitionEnd) return; - - Object.keys(transitionEnd).forEach(valueKey => { - if (values.has(valueKey)) { - (values.get(valueKey) as MotionValue).set(transitionEnd[valueKey]); - } - }); - }) - ); - }); - - return Promise.all(poseTransitions).then(() => { - onPoseComplete && - onPoseComplete(resolveCurrent(values), resolveVelocity(values)); - }); -}; + }) +} -const usePoseResolver = ( - values: Map, - config: PoseConfig, - props: MotionProps, - ref: RefObject -) => { - const poseSubscriber: MutableRefObject = useRef(null); - const { pose } = props; - const poseIsSubscription = pose instanceof MotionValue; - const poseResolver = createPoseResolver(values, config, props, ref); - - // If we're controlled by props, fire resolver with latest pose - const poseList = !poseIsSubscription - ? poseToArray(pose as string | string[]) - : []; - - useSubsequentRenderEffect(() => { - if (!poseIsSubscription) poseResolver(poseList); - }, poseList); - - // Or if we're using a pose subscription, manage subscriptions - useEffect(() => { - if (!poseIsSubscription) return; - - poseSubscriber.current = (v: string | string[]) => - poseResolver(poseToArray(v)); - (pose as MotionValue).addSubscriber(poseSubscriber.current); - - return () => { - if (poseSubscriber.current) { - (pose as MotionValue).removeSubscriber(poseSubscriber.current); - } - }; - }); -}; - -export default usePoseResolver; +export default usePoseResolver diff --git a/src/hooks/use-pose.ts b/src/hooks/use-pose.ts index fd061b5191..b7261eb155 100644 --- a/src/hooks/use-pose.ts +++ b/src/hooks/use-pose.ts @@ -1,37 +1,37 @@ -import { useMemo } from 'react'; -import motionValue, { MotionValue } from '../motion-value'; +import { useMemo } from "react" +import motionValue, { MotionValue } from "../motion-value" type PoseSetter = { - (pose: string | string[]): void; - cycle: () => void; -}; - -const usePose = (initPose: string | string[] = 'default', poses?: string[]) => { - return useMemo((): [MotionValue, PoseSetter] => { - let i = 0; - - const pose = motionValue(initPose); - - const setPose: PoseSetter = newPose => { - if (poses && typeof newPose === 'string') { - const poseIndex = poses.indexOf(newPose); - i = poseIndex > -1 ? poseIndex : i; - } - pose.set(newPose); - }; - - // Add cycle functionality - setPose.cycle = () => { - if (!poses) return; - - const numPoses = poses.length; - i++; - if (i >= numPoses) i = 0; - setPose(poses[i]); - }; - - return [pose, setPose]; - }, poses || []); -}; - -export default usePose; + (pose: string | string[]): void + cycle: () => void +} + +const usePose = (initPose: string | string[] = "default", poses?: string[]) => { + return useMemo((): [MotionValue, PoseSetter] => { + let i = 0 + + const pose = motionValue(initPose) + + const setPose: PoseSetter = newPose => { + if (poses && typeof newPose === "string") { + const poseIndex = poses.indexOf(newPose) + i = poseIndex > -1 ? poseIndex : i + } + pose.set(newPose) + } + + // Add cycle functionality + setPose.cycle = () => { + if (!poses) return + + const numPoses = poses.length + i++ + if (i >= numPoses) i = 0 + setPose(poses[i]) + } + + return [pose, setPose] + }, poses || []) +} + +export default usePose diff --git a/src/hooks/use-posed-values.ts b/src/hooks/use-posed-values.ts index 11164dd102..3938965311 100644 --- a/src/hooks/use-posed-values.ts +++ b/src/hooks/use-posed-values.ts @@ -1,52 +1,51 @@ -import { MotionValue } from '../motion-value'; -import { resolvePoses } from '../utils/pose-resolvers'; -import { PoseConfig, MotionProps, MotionValueMap } from '../motion/types'; -import { useRef, useEffect, RefObject } from 'react'; -import { createValuesFromPose, bindValuesToRef } from '../utils/create-value'; +import { MotionValue } from "../motion-value" +import { resolvePoses } from "../utils/pose-resolvers" +import { PoseConfig, MotionProps, MotionValueMap } from "../motion/types" +import { useRef, useEffect, RefObject } from "react" +import { createValuesFromPose, bindValuesToRef } from "../utils/create-value" export default ( - config: PoseConfig, - { onPoseComplete, ...props }: MotionProps, - ref: RefObject + config: PoseConfig, + { onPoseComplete, ...props }: MotionProps, + ref: RefObject ): [MotionValueMap, Partial] => { - const values: MotionValueMap = useRef(new Map()).current; - const returnedProps = {}; + const values: MotionValueMap = useRef(new Map()).current + const returnedProps = {} - // In this function we want to find the right approach to ensure - // we successfully remove MotionValues from the returned props - // in a performant way over subsequent renders. + // In this function we want to find the right approach to ensure + // we successfully remove MotionValues from the returned props + // in a performant way over subsequent renders. - // 1. Add provided motion values via props to value map - Object.keys(props).forEach(key => { - const prop = props[key]; + // 1. Add provided motion values via props to value map + Object.keys(props).forEach(key => { + const prop = props[key] - if (prop instanceof MotionValue) { - values.set(key, prop); - } else if (key !== 'pose') { - returnedProps[key] = prop; - } - }); + if (prop instanceof MotionValue) { + values.set(key, prop) + } else if (key !== "pose") { + returnedProps[key] = prop + } + }) - // 2. Create values from poses - const { pose = 'default' } = props; - const initialPoses = resolvePoses(pose); + // 2. Create values from poses + const { pose = "default" } = props + const initialPoses = resolvePoses(pose) - initialPoses.forEach(poseKey => { - const poseDef = config[poseKey]; - if (!poseDef) return; + initialPoses.forEach(poseKey => { + const poseDef = config[poseKey] + if (!poseDef) return - const pose = - typeof poseDef === 'function' ? poseDef(props, {}, {}) : poseDef; + const pose = typeof poseDef === "function" ? poseDef(props, {}, {}) : poseDef - createValuesFromPose(values, pose); - }); + createValuesFromPose(values, pose) + }) - // 3. Bind stylers when ref is ready - useEffect(() => { - bindValuesToRef(values, ref); + // 3. Bind stylers when ref is ready + useEffect(() => { + bindValuesToRef(values, ref) - return () => values.forEach(value => value.destroy()); - }, []); + return () => values.forEach(value => value.destroy()) + }, []) - return [values, returnedProps]; -}; + return [values, returnedProps] +} diff --git a/src/hooks/use-style-attr.ts b/src/hooks/use-style-attr.ts index e98c84faef..1a0a69b50e 100644 --- a/src/hooks/use-style-attr.ts +++ b/src/hooks/use-style-attr.ts @@ -1,16 +1,13 @@ -import { useMemo, CSSProperties } from 'react'; -import { buildStyleProperty } from 'stylefire'; -import { MotionValue } from '../motion-value'; -import { resolveCurrent } from '../utils/resolve-values'; +import { useMemo, CSSProperties } from "react" +import { buildStyleProperty } from "stylefire" +import { MotionValue } from "../motion-value" +import { resolveCurrent } from "../utils/resolve-values" -export default ( - values: Map, - styles?: CSSProperties -): CSSProperties => - useMemo( - () => ({ - ...styles, - ...buildStyleProperty(resolveCurrent(values)) - }), - [] - ); +export default (values: Map, styles?: CSSProperties): CSSProperties => + useMemo( + () => ({ + ...styles, + ...buildStyleProperty(resolveCurrent(values)), + }), + [] + ) diff --git a/src/hooks/use-subsequent-render-effect.ts b/src/hooks/use-subsequent-render-effect.ts index bb38eaf436..e908c9102b 100644 --- a/src/hooks/use-subsequent-render-effect.ts +++ b/src/hooks/use-subsequent-render-effect.ts @@ -1,15 +1,15 @@ -import { useRef, useEffect } from 'react'; +import { useRef, useEffect } from "react" const useSubsequentRenderEffect = (callback: () => void, conditions: any[]) => { - const isInitialRender = useRef(true); + const isInitialRender = useRef(true) - return useEffect(() => { - if (isInitialRender.current) { - isInitialRender.current = false; - } else { - return callback(); - } - }, conditions); -}; + return useEffect(() => { + if (isInitialRender.current) { + isInitialRender.current = false + } else { + return callback() + } + }, conditions) +} -export default useSubsequentRenderEffect; +export default useSubsequentRenderEffect diff --git a/src/hooks/use-transform.ts b/src/hooks/use-transform.ts index 6aa3d53809..3737487678 100644 --- a/src/hooks/use-transform.ts +++ b/src/hooks/use-transform.ts @@ -1,22 +1,18 @@ -import { useMemo, useRef, MutableRefObject } from 'react'; -import { MotionValue } from '../motion-value'; -import { interpolate } from '@popmotion/popcorn'; +import { useMemo, useRef, MutableRefObject } from "react" +import { MotionValue } from "../motion-value" +import { interpolate } from "@popmotion/popcorn" -export default ( - value: MotionValue, - from: number[], - to: string[] | number[] -) => { - const transformedValue: MutableRefObject = useRef(null); +export default (value: MotionValue, from: number[], to: string[] | number[]) => { + const transformedValue: MutableRefObject = useRef(null) - return useMemo( - () => { - if (transformedValue.current) transformedValue.current.destroy(); - transformedValue.current = value.addChild({ - transformer: interpolate(from, to) - }); - return transformedValue.current; - }, - [value, ...from, ...to] - ); -}; + return useMemo( + () => { + if (transformedValue.current) transformedValue.current.destroy() + transformedValue.current = value.addChild({ + transformer: interpolate(from, to), + }) + return transformedValue.current + }, + [value, ...from, ...to] + ) +} diff --git a/src/index.ts b/src/index.ts index 5a43d09b28..24e11d8c5f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ -import motion from './motion'; -import useMotionValue from './hooks/use-motion-value'; -import useTransform from './hooks/use-transform'; -import usePose from './hooks/use-pose'; +import motion from "./motion" +import useMotionValue from "./hooks/use-motion-value" +import useTransform from "./hooks/use-transform" +import usePose from "./hooks/use-pose" -export { motion, useMotionValue, useTransform, usePose }; +export { motion, useMotionValue, useTransform, usePose } diff --git a/src/motion-value/index.ts b/src/motion-value/index.ts index fe5ecab2c8..31737f606b 100644 --- a/src/motion-value/index.ts +++ b/src/motion-value/index.ts @@ -1,198 +1,182 @@ -import sync, { getFrameData, FrameData } from 'framesync'; -import { - chain, - delay as delayAction, - Action, - ColdSubscription -} from 'popmotion'; -import { velocityPerSecond } from '@popmotion/popcorn'; +import sync, { getFrameData, FrameData } from "framesync" +import { chain, delay as delayAction, Action, ColdSubscription } from "popmotion" +import { velocityPerSecond } from "@popmotion/popcorn" -export type ValuePrimitive = any; +export type ValuePrimitive = any -export type Transformer = (v: ValuePrimitive) => ValuePrimitive; +export type Transformer = (v: ValuePrimitive) => ValuePrimitive -export type Subscriber = (v: ValuePrimitive) => void; +export type Subscriber = (v: ValuePrimitive) => void export type Config = { - transformer?: Transformer; - onRender?: Subscriber; - parent?: MotionValue; -}; + transformer?: Transformer + onRender?: Subscriber + parent?: MotionValue +} -export type ActionConfig = { [key: string]: any }; +export type ActionConfig = { [key: string]: any } -export type ActionFactory = (actionConfig: ActionConfig) => Action; +export type ActionFactory = (actionConfig: ActionConfig) => Action export class MotionValue { - // Current state - private current: ValuePrimitive; + // Current state + private current: ValuePrimitive - // Previous state - private prev: ValuePrimitive; + // Previous state + private prev: ValuePrimitive - private timeDelta: number = 0; - private lastUpdated: number = 0; + private timeDelta: number = 0 + private lastUpdated: number = 0 - // Children get updated onUpdate - private children: Set; + // Children get updated onUpdate + private children: Set - // A reference to the value's parent - currently used for unregistering as a child, - // but maybe it'd be better for this to be just a disconnect function - private parent?: MotionValue; + // A reference to the value's parent - currently used for unregistering as a child, + // but maybe it'd be better for this to be just a disconnect function + private parent?: MotionValue - // onRender is fired on render step after update - private onRender: Subscriber | null; + // onRender is fired on render step after update + private onRender: Subscriber | null - // Fired - private subscribers: Set; + // Fired + private subscribers: Set - // If set, will pass `set` values through this function first - private transformer?: Transformer; + // If set, will pass `set` values through this function first + private transformer?: Transformer - // A reference to the currently-controlling animation - private controller?: ColdSubscription; + // A reference to the currently-controlling animation + private controller?: ColdSubscription - private canTrackVelocity = false; + private canTrackVelocity = false - constructor( - init: ValuePrimitive, - { onRender, transformer, parent }: Config = {} - ) { - this.parent = parent; - this.transformer = transformer; - if (onRender) this.setOnRender(onRender); - this.set(init); - this.canTrackVelocity = !isNaN(parseFloat(this.current)); - } + constructor(init: ValuePrimitive, { onRender, transformer, parent }: Config = {}) { + this.parent = parent + this.transformer = transformer + if (onRender) this.setOnRender(onRender) + this.set(init) + this.canTrackVelocity = !isNaN(parseFloat(this.current)) + } - addChild(config: Config) { - const child = new MotionValue(this.current, { - parent: this, - ...config - }); + addChild(config: Config) { + const child = new MotionValue(this.current, { + parent: this, + ...config, + }) - if (!this.children) this.children = new Set(); + if (!this.children) this.children = new Set() - this.children.add(child); + this.children.add(child) - return child; - } + return child + } - removeChild(child: MotionValue) { - this.children.delete(child); - } + removeChild(child: MotionValue) { + this.children.delete(child) + } - setOnRender(onRender: Subscriber | null) { - this.onRender = onRender; - if (this.onRender) sync.render(this.render); - } + setOnRender(onRender: Subscriber | null) { + this.onRender = onRender + if (this.onRender) sync.render(this.render) + } - addSubscriber(sub: Subscriber) { - if (!this.subscribers) this.subscribers = new Set(); - this.subscribers.add(sub); - } + addSubscriber(sub: Subscriber) { + if (!this.subscribers) this.subscribers = new Set() + this.subscribers.add(sub) + } - removeSubscriber(sub: Subscriber) { - if (this.subscribers) { - this.subscribers.delete(sub); + removeSubscriber(sub: Subscriber) { + if (this.subscribers) { + this.subscribers.delete(sub) + } } - } - set(v: ValuePrimitive) { - this.prev = this.current; - this.current = this.transformer ? this.transformer(v) : v; + set(v: ValuePrimitive) { + this.prev = this.current + this.current = this.transformer ? this.transformer(v) : v - if (this.subscribers) { - sync.update(this.notifySubscribers, false, true); - } + if (this.subscribers) { + sync.update(this.notifySubscribers, false, true) + } + + if (this.children) { + this.children.forEach(this.setChild) + } - if (this.children) { - this.children.forEach(this.setChild); + if (this.onRender) { + sync.render(this.render) + } + + // Update timestamp + const { delta, timestamp } = getFrameData() + this.timeDelta = delta + this.lastUpdated = timestamp + sync.postRender(this.scheduleVelocityCheck) } - if (this.onRender) { - sync.render(this.render); + scheduleVelocityCheck = () => sync.postRender(this.velocityCheck) + + velocityCheck = ({ timestamp }: FrameData) => { + if (timestamp !== this.lastUpdated) { + this.prev = this.current + } } - // Update timestamp - const { delta, timestamp } = getFrameData(); - this.timeDelta = delta; - this.lastUpdated = timestamp; - sync.postRender(this.scheduleVelocityCheck); - } + notifySubscribers = () => this.subscribers.forEach(this.setSubscriber) + setSubscriber = (sub: Subscriber) => sub(this.current) + setChild = (child: MotionValue) => child.set(this.current) - scheduleVelocityCheck = () => sync.postRender(this.velocityCheck); + get() { + return this.current + } - velocityCheck = ({ timestamp }: FrameData) => { - if (timestamp !== this.lastUpdated) { - this.prev = this.current; + getVelocity() { + return this.canTrackVelocity + ? velocityPerSecond(parseFloat(this.prev) - parseFloat(this.current), this.timeDelta) + : 0 } - }; - - notifySubscribers = () => this.subscribers.forEach(this.setSubscriber); - setSubscriber = (sub: Subscriber) => sub(this.current); - setChild = (child: MotionValue) => child.set(this.current); - - get() { - return this.current; - } - - getVelocity() { - return this.canTrackVelocity - ? velocityPerSecond( - parseFloat(this.prev) - parseFloat(this.current), - this.timeDelta - ) - : 0; - } - - render = () => { - if (this.onRender) this.onRender(this.current); - }; - - control( - controller: ActionFactory, - { delay, ...config }: ActionConfig, - transformer?: Transformer - ) { - this.stop(); - let initialisedController = controller({ - from: this.get(), - velocity: this.getVelocity(), - ...config - }); + render = () => { + if (this.onRender) this.onRender(this.current) + } + + control(controller: ActionFactory, { delay, ...config }: ActionConfig, transformer?: Transformer) { + this.stop() + + let initialisedController = controller({ + from: this.get(), + velocity: this.getVelocity(), + ...config, + }) + + if (transformer) { + initialisedController = initialisedController.pipe(transformer) + } + + if (delay) { + initialisedController = chain(delayAction(delay), initialisedController) + } + + return new Promise(complete => { + this.controller = initialisedController.start({ + update: (v: ValuePrimitive) => this.set(v), + complete, + }) + }) + } - if (transformer) { - initialisedController = initialisedController.pipe(transformer); + stop() { + if (this.controller) this.controller.stop() } - if (delay) { - initialisedController = chain(delayAction(delay), initialisedController); + destroy() { + this.setOnRender(null) + this.parent && this.parent.removeChild(this) + this.stop() } - return new Promise(complete => { - this.controller = initialisedController.start({ - update: (v: ValuePrimitive) => this.set(v), - complete - }); - }); - } - - stop() { - if (this.controller) this.controller.stop(); - } - - destroy() { - this.setOnRender(null); - this.parent && this.parent.removeChild(this); - this.stop(); - } - - hasOnRender() { - return !!this.onRender; - } + hasOnRender() { + return !!this.onRender + } } -export default (init: ValuePrimitive, opts?: Config) => - new MotionValue(init, opts); +export default (init: ValuePrimitive, opts?: Config) => new MotionValue(init, opts) diff --git a/src/motion/component.ts b/src/motion/component.ts index 4697219f48..e080ab617b 100644 --- a/src/motion/component.ts +++ b/src/motion/component.ts @@ -1,31 +1,31 @@ -import { memo, forwardRef, createElement, Ref, ComponentType } from 'react'; -import { MotionProps, ComponentFactory } from './types'; -import useConfig from '../hooks/use-config'; -import useExternalRef from '../hooks/use-external-ref'; -import usePosedValues from '../hooks/use-posed-values'; -import usePoseResolver from '../hooks/use-pose-resolver'; -import useStyleAttr from '../hooks/use-style-attr'; +import { memo, forwardRef, createElement, Ref, ComponentType } from "react" +import { MotionProps, ComponentFactory } from "./types" +import useConfig from "../hooks/use-config" +import useExternalRef from "../hooks/use-external-ref" +import usePosedValues from "../hooks/use-posed-values" +import usePoseResolver from "../hooks/use-pose-resolver" +import useStyleAttr from "../hooks/use-style-attr" -const createMotionComponent =

( - Component: string | ComponentType

-): ComponentFactory

=> (poseConfig = {}): ComponentType

=> { - const MotionComponent = (props: MotionProps, externalRef?: Ref) => { - const ref = useExternalRef(externalRef); - const config = useConfig(poseConfig, props); +const createMotionComponent =

(Component: string | ComponentType

): ComponentFactory

=> ( + poseConfig = {} +): ComponentType

=> { + const MotionComponent = (props: MotionProps, externalRef?: Ref) => { + const ref = useExternalRef(externalRef) + const config = useConfig(poseConfig, props) - // Create motion values - const [values, componentProps] = usePosedValues(config, props, ref); + // Create motion values + const [values, componentProps] = usePosedValues(config, props, ref) - usePoseResolver(values, config, props, ref); + usePoseResolver(values, config, props, ref) - return createElement(Component, { - ...componentProps, - ref, - style: useStyleAttr(values, props.style) - }); - }; + return createElement(Component, { + ...componentProps, + ref, + style: useStyleAttr(values, props.style), + }) + } - return memo(forwardRef(MotionComponent)); -}; + return memo(forwardRef(MotionComponent)) +} -export default createMotionComponent; +export default createMotionComponent diff --git a/src/motion/index.ts b/src/motion/index.ts index 6e9d698e54..db7fd5d9c9 100644 --- a/src/motion/index.ts +++ b/src/motion/index.ts @@ -1,24 +1,16 @@ -import { HTMLProps, SVGProps, ComponentType } from 'react'; -import createMotionComponent from './component'; -import { htmlElements, svgElements } from './supported-elements'; -import { ComponentFactory, MotionProps } from './types'; +import { HTMLProps, SVGProps, ComponentType } from "react" +import createMotionComponent from "./component" +import { htmlElements, svgElements } from "./supported-elements" +import { ComponentFactory, MotionProps } from "./types" export type Motion = { - (component: ComponentType): ComponentFactory< - (HTMLProps | SVGProps) & MotionProps - >; - [key: string]: ComponentFactory< - (HTMLProps | SVGProps) & MotionProps - >; -}; + (component: ComponentType): ComponentFactory<(HTMLProps | SVGProps) & MotionProps> + [key: string]: ComponentFactory<(HTMLProps | SVGProps) & MotionProps> +} -const motion: Motion = createMotionComponent as Motion; +const motion: Motion = createMotionComponent as Motion -htmlElements.forEach( - element => (motion[element] = createMotionComponent(element)) -); -svgElements.forEach( - element => (motion[element] = createMotionComponent(element)) -); +htmlElements.forEach(element => (motion[element] = createMotionComponent(element))) +svgElements.forEach(element => (motion[element] = createMotionComponent(element))) -export default motion; +export default motion diff --git a/src/motion/supported-elements.ts b/src/motion/supported-elements.ts index efee76db34..b6deb25d3a 100644 --- a/src/motion/supported-elements.ts +++ b/src/motion/supported-elements.ts @@ -1,93 +1,93 @@ export const htmlElements = [ - 'a', - 'article', - 'aside', - 'audio', - 'b', - 'blockquote', - 'body', - 'br', - 'button', - 'canvas', - 'caption', - 'cite', - 'code', - 'col', - 'colgroup', - 'data', - 'datalist', - 'dialog', - 'div', - 'em', - 'embed', - 'fieldset', - 'figcaption', - 'figure', - 'footer', - 'form', - 'h1', - 'h2', - 'h3', - 'h4', - 'h5', - 'h6', - 'head', - 'header', - 'hgroup', - 'hr', - 'i', - 'iframe', - 'img', - 'input', - 'label', - 'legend', - 'li', - 'nav', - 'object', - 'ol', - 'option', - 'p', - 'param', - 'picture', - 'pre', - 'progress', - 'q', - 'section', - 'select', - 'span', - 'strong', - 'table', - 'tbody', - 'td', - 'textarea', - 'tfoot', - 'th', - 'thead', - 'time', - 'title', - 'tr', - 'ul', - 'video', - 'svg' -]; + "a", + "article", + "aside", + "audio", + "b", + "blockquote", + "body", + "br", + "button", + "canvas", + "caption", + "cite", + "code", + "col", + "colgroup", + "data", + "datalist", + "dialog", + "div", + "em", + "embed", + "fieldset", + "figcaption", + "figure", + "footer", + "form", + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "head", + "header", + "hgroup", + "hr", + "i", + "iframe", + "img", + "input", + "label", + "legend", + "li", + "nav", + "object", + "ol", + "option", + "p", + "param", + "picture", + "pre", + "progress", + "q", + "section", + "select", + "span", + "strong", + "table", + "tbody", + "td", + "textarea", + "tfoot", + "th", + "thead", + "time", + "title", + "tr", + "ul", + "video", + "svg", +] export const svgElements = [ - 'circle', - 'clipPath', - 'defs', - 'ellipse', - 'g', - 'image', - 'line', - 'linearGradient', - 'mask', - 'path', - 'pattern', - 'polygon', - 'polyline', - 'radialGradient', - 'rect', - 'stop', - 'text', - 'tspan' -]; + "circle", + "clipPath", + "defs", + "ellipse", + "g", + "image", + "line", + "linearGradient", + "mask", + "path", + "pattern", + "polygon", + "polyline", + "radialGradient", + "rect", + "stop", + "text", + "tspan", +] diff --git a/src/motion/types.ts b/src/motion/types.ts index 73c16bf756..0d804c7112 100644 --- a/src/motion/types.ts +++ b/src/motion/types.ts @@ -1,214 +1,198 @@ -import { MotionValue } from '../motion-value'; -import { CSSProperties, ComponentType, Ref } from 'react'; +import { MotionValue } from "../motion-value" +import { CSSProperties, ComponentType, Ref } from "react" -export type ComponentFactory = ( - config?: PoseConfigFactory | PoseConfig -) => ComponentType; +export type ComponentFactory = (config?: PoseConfigFactory | PoseConfig) => ComponentType -export type PoseConfigFactory = (props: MotionProps) => PoseConfig; +export type PoseConfigFactory = (props: MotionProps) => PoseConfig export type PoseConfig = { - [key: string]: Pose | PoseResolver; -}; + [key: string]: Pose | PoseResolver +} export type MotionProps = { - [key: string]: any; - ref?: Ref; - pose?: string | string[] | MotionValue; - style?: CSSProperties; - onPoseComplete?: (current: CurrentValues, velocity: VelocityValues) => void; -}; + [key: string]: any + ref?: Ref + pose?: string | string[] | MotionValue + style?: CSSProperties + onPoseComplete?: (current: CurrentValues, velocity: VelocityValues) => void +} -export type EasingFunction = (v: number) => number; +export type EasingFunction = (v: number) => number -export type CubicBezier = [number, number, number, number]; +export type CubicBezier = [number, number, number, number] export type Easing = - | CubicBezier - | 'linear' - | 'easeIn' - | 'easeOut' - | 'easeInOut' - | 'circIn' - | 'circOut' - | 'circInOut' - | 'backIn' - | 'backOut' - | 'backInOut' - | 'anticipate' - | EasingFunction; + | CubicBezier + | "linear" + | "easeIn" + | "easeOut" + | "easeInOut" + | "circIn" + | "circOut" + | "circInOut" + | "backIn" + | "backOut" + | "backInOut" + | "anticipate" + | EasingFunction export type BaseTransition = { - delay?: number; - from?: number | string; - to?: number | string; - velocity?: number; -}; + delay?: number + from?: number | string + to?: number | string + velocity?: number +} export type Tween = BaseTransition & { - type?: 'tween'; - duration?: number; - ease?: Easing; - elapsed?: number; - loop?: number; - flip?: number; - yoyo?: number; -}; + type?: "tween" + duration?: number + ease?: Easing + elapsed?: number + loop?: number + flip?: number + yoyo?: number +} export type Spring = BaseTransition & { - type: 'spring'; - stiffness?: number; - damping?: number; - mass?: number; - restSpeed?: number; - restDelta?: number; -}; + type: "spring" + stiffness?: number + damping?: number + mass?: number + restSpeed?: number + restDelta?: number +} export type Decay = BaseTransition & { - type: 'decay'; - modifyTarget?: (v: number) => number; - power?: number; - timeConstant?: number; - restDelta?: number; -}; + type: "decay" + modifyTarget?: (v: number) => number + power?: number + timeConstant?: number + restDelta?: number +} export type Keyframes = BaseTransition & { - type: 'keyframes'; - values: number[] | string[]; - easings?: Easing[]; - easeAll?: Easing; - elapsed?: number; - duration?: number; - loop?: number; - flip?: number; - yoyo?: number; -}; + type: "keyframes" + values: number[] | string[] + easings?: Easing[] + easeAll?: Easing + elapsed?: number + duration?: number + loop?: number + flip?: number + yoyo?: number +} export type Physics = BaseTransition & { - type: 'physics'; - acceleration?: number; - friction?: number; - restSpeed?: number | false; -}; + type: "physics" + acceleration?: number + friction?: number + restSpeed?: number | false +} export type Just = BaseTransition & { - type: 'just'; -}; + type: "just" +} -export type TransitionProp = - | Tween - | Spring - | Decay - | Keyframes - | Physics - | BaseTransition - | false; +export type TransitionProp = Tween | Spring | Decay | Keyframes | Physics | BaseTransition | false -export type Transition = Tween | Spring | Decay | Keyframes | Physics | Just; +export type Transition = Tween | Spring | Decay | Keyframes | Physics | Just -export type TransitionMap = { [key: string]: TransitionProp }; +export type TransitionMap = { [key: string]: TransitionProp } -export type TransitionDefinition = TransitionProp | TransitionMap; +export type TransitionDefinition = TransitionProp | TransitionMap // Framer Motion accepts any value, not just those listed below. // Add more here as found. export type Pose = { - // Transforms - x?: number | string; - y?: number | string; - z?: number | string; - rotate?: number | string; - rotateX?: number | string; - rotateY?: number | string; - rotateZ?: number | string; - scale?: number | string; - scaleX?: number | string; - scaleY?: number | string; - scaleZ?: number | string; - skew?: number | string; - skewX?: number | string; - skewY?: number | string; - originX?: number | string; - originY?: number | string; - originZ?: number | string; - opacity?: number; - perspective?: number | string; - transform?: string; - - // Positioning - width?: number | string; - height?: number | string; - maxWidth?: number | string; - maxHeight?: number | string; - top?: number | string; - left?: number | string; - right?: number | string; - bottom?: number | string; - - // Spacing - padding?: number | string; - paddingTop?: number | string; - paddingRight?: number | string; - paddingBottom?: number | string; - paddingLeft?: number | string; - margin?: number | string; - marginTop?: number | string; - marginRight?: number | string; - marginBottom?: number | string; - marginLeft?: number | string; - - // Borders - borderColor?: number | string; - borderTopColor?: number | string; - borderRightColor?: number | string; - borderBottomColor?: number | string; - borderLeftColor?: number | string; - borderWidth?: number | string; - borderTopWidth?: number | string; - borderRightWidth?: number | string; - borderBottomWidth?: number | string; - borderLeftWidth?: number | string; - borderRadius?: number | string; - borderTopLeftRadius?: number | string; - borderTopRightRadius?: number | string; - borderBottomRightRadius?: number | string; - borderBottomLeftRadius?: number | string; - - // Colors - color?: string; - backgroundColor?: string; - outlineColor?: string; - fill?: string; - stroke?: string; - - // Misc - background?: string; - backgroundImage?: string; - - // SVG - d?: string; - pathLength?: number; - pathSpacing?: number; - - // Options - transition?: TransitionDefinition; - transitionEnd?: StyleProps | ResolveStyleProps; -}; - -export type ResolveStyleProps = ( - current: CurrentValues, - velocity: VelocityValues -) => StyleProps; - -export type StyleProps = { [key: string]: string | number }; - -export type CurrentValues = { [key: string]: string | number }; -export type VelocityValues = { [key: string]: number }; - -export type PoseResolver = ( - props: { [key: string]: any }, - current: CurrentValues, - velocity: VelocityValues -) => Pose; - -export type MotionValueMap = Map; + // Transforms + x?: number | string + y?: number | string + z?: number | string + rotate?: number | string + rotateX?: number | string + rotateY?: number | string + rotateZ?: number | string + scale?: number | string + scaleX?: number | string + scaleY?: number | string + scaleZ?: number | string + skew?: number | string + skewX?: number | string + skewY?: number | string + originX?: number | string + originY?: number | string + originZ?: number | string + opacity?: number + perspective?: number | string + transform?: string + + // Positioning + width?: number | string + height?: number | string + maxWidth?: number | string + maxHeight?: number | string + top?: number | string + left?: number | string + right?: number | string + bottom?: number | string + + // Spacing + padding?: number | string + paddingTop?: number | string + paddingRight?: number | string + paddingBottom?: number | string + paddingLeft?: number | string + margin?: number | string + marginTop?: number | string + marginRight?: number | string + marginBottom?: number | string + marginLeft?: number | string + + // Borders + borderColor?: number | string + borderTopColor?: number | string + borderRightColor?: number | string + borderBottomColor?: number | string + borderLeftColor?: number | string + borderWidth?: number | string + borderTopWidth?: number | string + borderRightWidth?: number | string + borderBottomWidth?: number | string + borderLeftWidth?: number | string + borderRadius?: number | string + borderTopLeftRadius?: number | string + borderTopRightRadius?: number | string + borderBottomRightRadius?: number | string + borderBottomLeftRadius?: number | string + + // Colors + color?: string + backgroundColor?: string + outlineColor?: string + fill?: string + stroke?: string + + // Misc + background?: string + backgroundImage?: string + + // SVG + d?: string + pathLength?: number + pathSpacing?: number + + // Options + transition?: TransitionDefinition + transitionEnd?: StyleProps | ResolveStyleProps +} + +export type ResolveStyleProps = (current: CurrentValues, velocity: VelocityValues) => StyleProps + +export type StyleProps = { [key: string]: string | number } + +export type CurrentValues = { [key: string]: string | number } +export type VelocityValues = { [key: string]: number } + +export type PoseResolver = (props: { [key: string]: any }, current: CurrentValues, velocity: VelocityValues) => Pose + +export type MotionValueMap = Map diff --git a/src/utils/__tests__/pose-resolvers.test.ts b/src/utils/__tests__/pose-resolvers.test.ts index b9b8fea5ae..44928e300b 100644 --- a/src/utils/__tests__/pose-resolvers.test.ts +++ b/src/utils/__tests__/pose-resolvers.test.ts @@ -1,15 +1,15 @@ -import { poseToArray } from '../pose-resolvers'; +import { poseToArray } from "../pose-resolvers" -describe('poseToArray', () => { - it('Should correctly convert single string to array', () => { - expect(poseToArray('a')).toEqual(['a']); - }); +describe("poseToArray", () => { + it("Should correctly convert single string to array", () => { + expect(poseToArray("a")).toEqual(["a"]) + }) - it('Should leave arrays as-is', () => { - expect(poseToArray(['a', 'b'])).toEqual(['a', 'b']); - }); + it("Should leave arrays as-is", () => { + expect(poseToArray(["a", "b"])).toEqual(["a", "b"]) + }) - it('Should remove falsey poses', () => { - expect(poseToArray()).toEqual([]); - }); -}); + it("Should remove falsey poses", () => { + expect(poseToArray()).toEqual([]) + }) +}) diff --git a/src/utils/create-value.ts b/src/utils/create-value.ts index 7f5893d02f..19588009be 100644 --- a/src/utils/create-value.ts +++ b/src/utils/create-value.ts @@ -1,37 +1,31 @@ -import { RefObject } from 'react'; -import { MotionValueMap, Pose } from '../motion/types'; -import motionValue from '../motion-value'; -import styler from 'stylefire'; -import { invariant } from 'hey-listen'; +import { RefObject } from "react" +import { MotionValueMap, Pose } from "../motion/types" +import motionValue from "../motion-value" +import styler from "stylefire" +import { invariant } from "hey-listen" -export const createValuesFromPose = ( - values: MotionValueMap, - { transition, transitionEnd, ...pose }: Pose -) => { - const valuesToAdd = { ...pose, ...transitionEnd }; - Object.keys(valuesToAdd).forEach(valueKey => { - if (!values.has(valueKey)) { - values.set(valueKey, motionValue(valuesToAdd[valueKey])); - } - }); -}; +export const createValuesFromPose = (values: MotionValueMap, { transition, transitionEnd, ...pose }: Pose) => { + const valuesToAdd = { ...pose, ...transitionEnd } + Object.keys(valuesToAdd).forEach(valueKey => { + if (!values.has(valueKey)) { + values.set(valueKey, motionValue(valuesToAdd[valueKey])) + } + }) +} -export const bindValuesToRef = ( - values: MotionValueMap, - ref: RefObject -) => { - invariant( - ref.current !== null, - 'No DOM reference found. Ensure custom components use `forwardRef` to forward the `ref` property to the host DOM component.' - ); +export const bindValuesToRef = (values: MotionValueMap, ref: RefObject) => { + invariant( + ref.current !== null, + "No DOM reference found. Ensure custom components use `forwardRef` to forward the `ref` property to the host DOM component." + ) - if (!ref.current) return; + if (!ref.current) return - const domStyler = styler(ref.current); + const domStyler = styler(ref.current) - values.forEach((value, key) => { - if (!value.hasOnRender()) { - value.setOnRender((v: any) => domStyler.set(key, v)); - } - }); -}; + values.forEach((value, key) => { + if (!value.hasOnRender()) { + value.setOnRender((v: any) => domStyler.set(key, v)) + } + }) +} diff --git a/src/utils/default-transitions.ts b/src/utils/default-transitions.ts index 1bc9eb657f..ca45384394 100644 --- a/src/utils/default-transitions.ts +++ b/src/utils/default-transitions.ts @@ -1,43 +1,42 @@ -import { Transition } from '../motion/types'; +import { Transition } from "../motion/types" const underDampedSpring = () => ({ - type: 'spring', - stiffness: 500, - damping: 25, - restDelta: 0.5, - restSpeed: 10 -}); + type: "spring", + stiffness: 500, + damping: 25, + restDelta: 0.5, + restSpeed: 10, +}) const overDampedSpring = (to: string | number) => ({ - type: 'spring', - stiffness: 700, - damping: to === 0 ? 100 : 35 -}); + type: "spring", + stiffness: 700, + damping: to === 0 ? 100 : 35, +}) const linearTween = () => ({ - ease: 'linear', - duration: 250 -}); + ease: "linear", + duration: 250, +}) const defaultTransitions = { - x: underDampedSpring, - y: underDampedSpring, - z: underDampedSpring, - rotate: underDampedSpring, - rotateX: underDampedSpring, - rotateY: underDampedSpring, - rotateZ: underDampedSpring, - scaleX: overDampedSpring, - scaleY: overDampedSpring, - scale: overDampedSpring, - opacity: linearTween, - backgroundColor: linearTween, - color: linearTween, - default: overDampedSpring -}; + x: underDampedSpring, + y: underDampedSpring, + z: underDampedSpring, + rotate: underDampedSpring, + rotateX: underDampedSpring, + rotateY: underDampedSpring, + rotateZ: underDampedSpring, + scaleX: overDampedSpring, + scaleY: overDampedSpring, + scale: overDampedSpring, + opacity: linearTween, + backgroundColor: linearTween, + color: linearTween, + default: overDampedSpring, +} export default (valueKey: string, to: string | number): Transition => { - const transitionFactory = - defaultTransitions[valueKey] || defaultTransitions.default; - return { ...transitionFactory(to), to }; -}; + const transitionFactory = defaultTransitions[valueKey] || defaultTransitions.default + return { ...transitionFactory(to), to } +} diff --git a/src/utils/pose-resolvers.ts b/src/utils/pose-resolvers.ts index ca91222105..f20ff9a9bd 100644 --- a/src/utils/pose-resolvers.ts +++ b/src/utils/pose-resolvers.ts @@ -1,15 +1,13 @@ -import { MotionValue } from '../motion-value'; +import { MotionValue } from "../motion-value" -type PoseNameList = string[]; -type PoseName = string | PoseNameList; -type UnresolvedPose = PoseName | MotionValue; +type PoseNameList = string[] +type PoseName = string | PoseNameList +type UnresolvedPose = PoseName | MotionValue -export const poseToArray = (pose?: PoseName): PoseNameList => - Array.isArray(pose) ? [...pose] : pose ? [pose] : []; +export const poseToArray = (pose?: PoseName): PoseNameList => (Array.isArray(pose) ? [...pose] : pose ? [pose] : []) export const resolvePoses = (pose: UnresolvedPose): PoseNameList => { - const unresolvedPose = - pose instanceof MotionValue ? (pose.get() as string) : pose; + const unresolvedPose = pose instanceof MotionValue ? (pose.get() as string) : pose - return poseToArray(unresolvedPose); -}; + return poseToArray(unresolvedPose) +} diff --git a/src/utils/resolve-values.ts b/src/utils/resolve-values.ts index 705cf0dc4c..2daa4e1327 100644 --- a/src/utils/resolve-values.ts +++ b/src/utils/resolve-values.ts @@ -1,16 +1,12 @@ -import { MotionValue } from '../motion-value'; +import { MotionValue } from "../motion-value" -export type Resolver = (value: MotionValue) => any; +export type Resolver = (value: MotionValue) => any -const createValueResolver = (resolver: Resolver) => ( - values: Map -) => { - const resolvedValues = {}; - values.forEach((value, key) => (resolvedValues[key] = resolver(value))); - return resolvedValues; -}; +const createValueResolver = (resolver: Resolver) => (values: Map) => { + const resolvedValues = {} + values.forEach((value, key) => (resolvedValues[key] = resolver(value))) + return resolvedValues +} -export const resolveCurrent = createValueResolver(value => value.get()); -export const resolveVelocity = createValueResolver(value => - value.getVelocity() -); +export const resolveCurrent = createValueResolver(value => value.get()) +export const resolveVelocity = createValueResolver(value => value.getVelocity()) diff --git a/src/utils/transitions.ts b/src/utils/transitions.ts index f0d9741f77..38b0a3e3f4 100644 --- a/src/utils/transitions.ts +++ b/src/utils/transitions.ts @@ -1,126 +1,91 @@ -import { - action, - tween, - spring, - keyframes, - decay, - physics, - easing, - Action -} from 'popmotion'; -import { - Transition, - TransitionProp, - Tween, - Keyframes, - EasingFunction, - TransitionMap -} from '../motion/types'; -import getDefaultTransition from './default-transitions'; -import { invariant } from 'hey-listen'; -import { ActionFactory } from '../motion-value'; - -type JustProps = { to: string | number }; +import { action, tween, spring, keyframes, decay, physics, easing, Action } from "popmotion" +import { Transition, TransitionProp, Tween, Keyframes, EasingFunction, TransitionMap } from "../motion/types" +import getDefaultTransition from "./default-transitions" +import { invariant } from "hey-listen" +import { ActionFactory } from "../motion-value" + +type JustProps = { to: string | number } const just: ActionFactory = ({ to }: JustProps): Action => - action(({ update, complete }) => { - update(to); - complete(); - }); + action(({ update, complete }) => { + update(to) + complete() + }) -const transitions = { tween, spring, keyframes, decay, physics, just }; +const transitions = { tween, spring, keyframes, decay, physics, just } const { - linear, - easeIn, - easeOut, - easeInOut, - circIn, - circOut, - circInOut, - backIn, - backOut, - backInOut, - anticipate -} = easing; + linear, + easeIn, + easeOut, + easeInOut, + circIn, + circOut, + circInOut, + backIn, + backOut, + backInOut, + anticipate, +} = easing const easingLookup: { [key: string]: EasingFunction } = { - linear, - easeIn, - easeOut, - easeInOut, - circIn, - circOut, - circInOut, - backIn, - backOut, - backInOut, - anticipate -}; + linear, + easeIn, + easeOut, + easeInOut, + circIn, + circOut, + circInOut, + backIn, + backOut, + backInOut, + anticipate, +} const transitionOptionParser = { - tween: (opts: Tween): Tween => { - const { ease } = opts; - - if (Array.isArray(ease)) { - // If cubic bezier definition, create bezier curve - invariant( - ease.length === 4, - `Cubic bezier arrays must contain four numerical values.` - ); - - const [x1, y1, x2, y2] = ease; - opts.ease = easing.cubicBezier(x1, y1, x2, y2); - } else if (typeof ease === 'string') { - // Else lookup from table - invariant( - easingLookup[ease] !== undefined, - `Invalid easing type '${ease}'` - ); - opts.ease = easingLookup[ease]; + tween: (opts: Tween): Tween => { + const { ease } = opts + + if (Array.isArray(ease)) { + // If cubic bezier definition, create bezier curve + invariant(ease.length === 4, `Cubic bezier arrays must contain four numerical values.`) + + const [x1, y1, x2, y2] = ease + opts.ease = easing.cubicBezier(x1, y1, x2, y2) + } else if (typeof ease === "string") { + // Else lookup from table + invariant(easingLookup[ease] !== undefined, `Invalid easing type '${ease}'`) + opts.ease = easingLookup[ease] + } + + return opts + }, + keyframes: ({ from, to, ...opts }: Keyframes) => opts, +} + +const getTransition = (valueKey: string, to: string | number, transitionProp?: TransitionProp): Transition => { + if (transitionProp !== undefined) { + let transition: Transition = {} + + if (transitionProp === false || transitionProp[valueKey] === false) { + transition = { type: "just" } + } else { + transition = transitionProp[valueKey] || (transitionProp as TransitionMap).default + } + + return { ...transition, to } } - return opts; - }, - keyframes: ({ from, to, ...opts }: Keyframes) => opts -}; - -const getTransition = ( - valueKey: string, - to: string | number, - transitionProp?: TransitionProp -): Transition => { - if (transitionProp !== undefined) { - let transition: Transition = {}; - - if (transitionProp === false || transitionProp[valueKey] === false) { - transition = { type: 'just' }; - } else { - transition = - transitionProp[valueKey] || (transitionProp as TransitionMap).default; - } + return getDefaultTransition(valueKey, to) +} - return { ...transition, to }; - } +const preprocessOptions = (type: string, opts: Transition): Transition => + transitionOptionParser[type] ? transitionOptionParser[type](opts) : opts - return getDefaultTransition(valueKey, to); -}; +export default (valueKey: string, to: string | number, transition?: TransitionProp): [ActionFactory, Transition] => { + const { type = "tween", ...transitionDefinition } = getTransition(valueKey, to, transition) -const preprocessOptions = (type: string, opts: Transition): Transition => - transitionOptionParser[type] ? transitionOptionParser[type](opts) : opts; - -export default ( - valueKey: string, - to: string | number, - transition?: TransitionProp -): [ActionFactory, Transition] => { - const { type = 'tween', ...transitionDefinition } = getTransition( - valueKey, - to, - transition - ); - - const action: ActionFactory = transitions[type]; - const opts: Transition = preprocessOptions(type, transitionDefinition); - - return [action, opts]; -}; + const action: ActionFactory = transitions[type] + const opts: Transition = preprocessOptions(type, transitionDefinition) + + return [action, opts] +} From d53d69edc358183ed2eef56a103339deff1acb31 Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Fri, 23 Nov 2018 08:47:06 +0000 Subject: [PATCH 20/44] test --- src/motion/__tests__/component.test.tsx | 244 +++++++++++++----------- 1 file changed, 134 insertions(+), 110 deletions(-) diff --git a/src/motion/__tests__/component.test.tsx b/src/motion/__tests__/component.test.tsx index 2b3d933a45..a8994de64e 100644 --- a/src/motion/__tests__/component.test.tsx +++ b/src/motion/__tests__/component.test.tsx @@ -1,26 +1,33 @@ import { render } from 'react-testing-library'; import motion from '../'; import * as React from 'react'; +import useMotionValue from '../../hooks/use-motion-value'; +import styled from 'styled-components'; + +/** + * Note: + * + * There's currently a "bug" inherent in testing components using React hooks. + * Components aren't really mounted/rendered with the initial render and it + * requires a `rerender` to force this behaviour. The React team are working + * to offer a way to flush effects but until then we have these rerenders in async tests. + */ + +test('motion component renders', () => { + const Box = motion.div(); + const { container } = render(); + expect(container.firstChild).toBeTruthy(); +}); -//import useMotionValue from '../../hooks/use-motion-value'; -// -//import styled from 'styled-components'; - -// test('motion component renders', () => { -// const Box = motion.div(); -// const { container } = render(); -// expect(container.firstChild).toBeTruthy(); -// }); - -// test('motion component renders custom component', () => { -// const Box = motion.div(); -// const { getByTestId } = render( -// -//

-// -// ); -// expect(getByTestId('child')).toBeTruthy(); -// }); +test('motion component renders custom component', () => { + const Box = motion.div(); + const { getByTestId } = render( + +
+ + ); + expect(getByTestId('child')).toBeTruthy(); +}); test('motion component accepts function ref', async () => { const Box = motion.div(); @@ -34,97 +41,114 @@ test('motion component accepts function ref', async () => { await expect(promise).resolves.toBeTruthy(); }); -// test('motion component accepts createRef', () => { -// const Box = motion.div(); - -// const { container } = render(); -// expect(container.firstChild).toBeTruthy(); -// }); - -// test('motion component generates style attr from pose', () => { -// const Box = motion.div({ -// default: { backgroundColor: '#fff' } -// }); -// const { container } = render(); -// expect(container.firstChild).toHaveStyle('background-color: #fff'); -// }); - -// test('motion component overwrites provided style attr with pose', () => { -// const Box = motion.div({ -// default: { backgroundColor: '#fff' } -// }); -// const { container } = render( -// -// ); -// expect(container.firstChild).toHaveStyle( -// 'background-color: #fff; left: 500px' -// ); -// }); - -// test('motion component renders styled component and overwrites style', () => { -// const Box = styled.div` -// background: #fff; -// `; -// const MotionBox = motion(Box)({ -// default: { background: '#000' } -// }); - -// const { container } = render(); - -// expect(container.firstChild).toHaveStyle('background: #000'); -// }); - -// test('motion component takes styles of defined initial pose', () => { -// const Box = motion.div({ -// default: { x: 0 }, -// foo: { x: 100, transitionEnd: { display: 'none' } } -// }); -// const { container } = render(); -// expect(container.firstChild).toHaveStyle( -// 'transform: translateX(100px) translateZ(0); display: none;' -// ); -// }); - -// test("motion component doesn't forward pose prop", () => { -// const Box = motion.div({ default: {} }); -// const { container } = render(); -// expect(container.firstChild).not.toHaveAttribute('pose'); -// }); - -// test('motion component accepts motion value', () => { -// const Box = motion.div(); - -// const Component = () => { -// const x = useMotionValue(800); -// return ; -// }; - -// const { container } = render(); -// expect(container.firstChild).toHaveStyle( -// 'transform: translateX(800px) translateZ(0)' -// ); -// }); - -// test('motion component fires onPoseComplete', done => { -// const Box = motion.div({ -// foo: { x: 100 }, -// bar: { x: 0, transition: false } -// }); - -// const { rerender } = render(); - -// rerender( -// { -// // We would ideally like to inspect the DOM itself at this point -// // but the node seems to be unmounted after sync ops have flushed -// expect(current.x).toBe(0); -// done(); -// }} -// /> -// ); -// }); +test('motion component accepts createRef', async () => { + const Box = motion.div(); + + const promise = new Promise(resolve => { + const ref = React.createRef(); + const Component = () => { + React.useEffect(() => { + resolve(ref.current); + }); + return ; + }; + const { rerender } = render(); + rerender(); + }); + + await expect(promise).resolves.toBeTruthy(); +}); + +test('motion component generates style attr from pose', () => { + const Box = motion.div({ + default: { backgroundColor: '#fff' } + }); + const { container } = render(); + expect(container.firstChild).toHaveStyle('background-color: #fff'); +}); + +test('motion component overwrites provided style attr with pose', () => { + const Box = motion.div({ + default: { backgroundColor: '#fff' } + }); + const { container } = render( + + ); + expect(container.firstChild).toHaveStyle( + 'background-color: #fff; left: 500px' + ); +}); + +test('motion component renders styled component and overwrites style', () => { + const Box = styled.div` + background: #fff; + `; + const MotionBox = motion(Box)({ + default: { background: '#000' } + }); + + const { container } = render(); + + expect(container.firstChild).toHaveStyle('background: #000'); +}); + +test('motion component takes styles of defined initial pose', () => { + const Box = motion.div({ + default: { x: 0 }, + foo: { x: 100, transitionEnd: { display: 'none' } } + }); + const { container } = render(); + expect(container.firstChild).toHaveStyle( + 'transform: translateX(100px) translateZ(0); display: none;' + ); +}); + +test("motion component doesn't forward pose prop", () => { + const Box = motion.div({ default: {} }); + const { container } = render(); + expect(container.firstChild).not.toHaveAttribute('pose'); +}); + +test('motion component accepts motion value', () => { + const Box = motion.div(); + + const Component = () => { + const x = useMotionValue(800); + return ; + }; + + const { container } = render(); + expect(container.firstChild).toHaveStyle( + 'transform: translateX(800px) translateZ(0)' + ); +}); + +test('motion component fires onPoseComplete', async () => { + const Box = motion.div({ + foo: { x: 100 }, + bar: { x: 0, transition: false } + }); + + const promise = new Promise(resolve => { + const { rerender } = render(); + rerender( + { + // We would ideally like to inspect the DOM itself at this point + // but the node seems to be unmounted after sync ops have flushed + expect(current.x).toBe(0); + resolve('fired'); + }} + /> + ); + + // To fire effects + rerender(); + }); + + await expect(promise).resolves.toEqual('fired'); +}); // usePose From 03142bf27e5bf88014b0625071f8646ec4892c2e Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Fri, 23 Nov 2018 09:26:48 +0000 Subject: [PATCH 21/44] latest tests --- src/hooks/use-pose.ts | 2 +- src/motion/__tests__/component.test.tsx | 357 ++++++++++++++---------- 2 files changed, 217 insertions(+), 142 deletions(-) diff --git a/src/hooks/use-pose.ts b/src/hooks/use-pose.ts index b7261eb155..844329d771 100644 --- a/src/hooks/use-pose.ts +++ b/src/hooks/use-pose.ts @@ -8,7 +8,7 @@ type PoseSetter = { const usePose = (initPose: string | string[] = "default", poses?: string[]) => { return useMemo((): [MotionValue, PoseSetter] => { - let i = 0 + let i = typeof initPose === "string" && poses ? poses.indexOf(initPose) : 0 const pose = motionValue(initPose) diff --git a/src/motion/__tests__/component.test.tsx b/src/motion/__tests__/component.test.tsx index a8994de64e..9b035238da 100644 --- a/src/motion/__tests__/component.test.tsx +++ b/src/motion/__tests__/component.test.tsx @@ -1,8 +1,9 @@ -import { render } from 'react-testing-library'; -import motion from '../'; -import * as React from 'react'; -import useMotionValue from '../../hooks/use-motion-value'; -import styled from 'styled-components'; +import { fireEvent, render } from "react-testing-library" +import motion from "../" +import * as React from "react" +import useMotionValue from "../../hooks/use-motion-value" +import usePose from "../../hooks/use-pose" +import styled from "styled-components" /** * Note: @@ -13,143 +14,217 @@ import styled from 'styled-components'; * to offer a way to flush effects but until then we have these rerenders in async tests. */ -test('motion component renders', () => { - const Box = motion.div(); - const { container } = render(); - expect(container.firstChild).toBeTruthy(); -}); - -test('motion component renders custom component', () => { - const Box = motion.div(); - const { getByTestId } = render( - -
- - ); - expect(getByTestId('child')).toBeTruthy(); -}); - -test('motion component accepts function ref', async () => { - const Box = motion.div(); - - const promise = new Promise(resolve => { - const Component = () => ; - const { rerender } = render(); - rerender(); - }); - - await expect(promise).resolves.toBeTruthy(); -}); - -test('motion component accepts createRef', async () => { - const Box = motion.div(); - - const promise = new Promise(resolve => { - const ref = React.createRef(); - const Component = () => { - React.useEffect(() => { - resolve(ref.current); - }); - return ; - }; - const { rerender } = render(); - rerender(); - }); - - await expect(promise).resolves.toBeTruthy(); -}); - -test('motion component generates style attr from pose', () => { - const Box = motion.div({ - default: { backgroundColor: '#fff' } - }); - const { container } = render(); - expect(container.firstChild).toHaveStyle('background-color: #fff'); -}); - -test('motion component overwrites provided style attr with pose', () => { - const Box = motion.div({ - default: { backgroundColor: '#fff' } - }); - const { container } = render( - - ); - expect(container.firstChild).toHaveStyle( - 'background-color: #fff; left: 500px' - ); -}); - -test('motion component renders styled component and overwrites style', () => { - const Box = styled.div` - background: #fff; - `; - const MotionBox = motion(Box)({ - default: { background: '#000' } - }); - - const { container } = render(); - - expect(container.firstChild).toHaveStyle('background: #000'); -}); - -test('motion component takes styles of defined initial pose', () => { - const Box = motion.div({ - default: { x: 0 }, - foo: { x: 100, transitionEnd: { display: 'none' } } - }); - const { container } = render(); - expect(container.firstChild).toHaveStyle( - 'transform: translateX(100px) translateZ(0); display: none;' - ); -}); +test("motion component renders", () => { + const Box = motion.div() + const { container } = render() + expect(container.firstChild).toBeTruthy() +}) + +test("motion component renders custom component", () => { + const Box = motion.div() + const { getByTestId } = render( + +
+ + ) + expect(getByTestId("child")).toBeTruthy() +}) + +test("motion component accepts function ref", async () => { + const Box = motion.div() + + const promise = new Promise(resolve => { + const Component = () => + const { rerender } = render() + rerender() + }) + + await expect(promise).resolves.toBeTruthy() +}) + +test("motion component accepts createRef", async () => { + const Box = motion.div() + + const promise = new Promise(resolve => { + const ref = React.createRef() + const Component = () => { + React.useEffect(() => { + resolve(ref.current) + }) + return + } + const { rerender } = render() + rerender() + }) + + await expect(promise).resolves.toBeTruthy() +}) + +test("motion component generates style attr from pose", () => { + const Box = motion.div({ + default: { backgroundColor: "#fff" }, + }) + const { container } = render() + expect(container.firstChild).toHaveStyle("background-color: #fff") +}) + +test("motion component overwrites provided style attr with pose", () => { + const Box = motion.div({ + default: { backgroundColor: "#fff" }, + }) + const { container } = render() + expect(container.firstChild).toHaveStyle("background-color: #fff; left: 500px") +}) + +test("motion component renders styled component and overwrites style", () => { + const Box = styled.div` + background: #fff; + ` + const MotionBox = motion(Box)({ + default: { background: "#000" }, + }) + + const { container } = render() + + expect(container.firstChild).toHaveStyle("background: #000") +}) + +test("motion component takes styles of defined initial pose", () => { + const Box = motion.div({ + default: { x: 0 }, + foo: { x: 100, transitionEnd: { display: "none" } }, + }) + const { container } = render() + expect(container.firstChild).toHaveStyle("transform: translateX(100px) translateZ(0); display: none;") +}) test("motion component doesn't forward pose prop", () => { - const Box = motion.div({ default: {} }); - const { container } = render(); - expect(container.firstChild).not.toHaveAttribute('pose'); -}); - -test('motion component accepts motion value', () => { - const Box = motion.div(); - - const Component = () => { - const x = useMotionValue(800); - return ; - }; - - const { container } = render(); - expect(container.firstChild).toHaveStyle( - 'transform: translateX(800px) translateZ(0)' - ); -}); - -test('motion component fires onPoseComplete', async () => { - const Box = motion.div({ - foo: { x: 100 }, - bar: { x: 0, transition: false } - }); - - const promise = new Promise(resolve => { - const { rerender } = render(); - rerender( - { - // We would ideally like to inspect the DOM itself at this point - // but the node seems to be unmounted after sync ops have flushed - expect(current.x).toBe(0); - resolve('fired'); - }} - /> - ); - - // To fire effects - rerender(); - }); - - await expect(promise).resolves.toEqual('fired'); -}); - -// usePose + const Box = motion.div({ default: {} }) + const { container } = render() + expect(container.firstChild).not.toHaveAttribute("pose") +}) + +test("motion component accepts motion value", () => { + const Box = motion.div() + + const Component = () => { + const x = useMotionValue(800) + return + } + + const { container } = render() + expect(container.firstChild).toHaveStyle("transform: translateX(800px) translateZ(0)") +}) + +test("motion component fires onPoseComplete", async () => { + const Box = motion.div({ + foo: { x: 100 }, + bar: { x: 0, transition: false }, + }) + + const promise = new Promise(resolve => { + const { rerender } = render() + rerender( + { + // We would ideally like to inspect the DOM itself at this point + // but the node seems to be unmounted after sync ops have flushed + expect(current.x).toBe(0) + resolve("fired") + }} + /> + ) + + // To fire effects + rerender() + }) + + await expect(promise).resolves.toEqual("fired") +}) + +test("usePose changes pose", async () => { + const Box = motion.div({ + foo: { scale: 3, transition: false }, + bar: { scale: 2, transition: false }, + }) + + const promise = new Promise(resolve => { + const Component = () => { + const [pose, setPose] = usePose("foo") + + return setPose("bar")} onPoseComplete={current => resolve(current.scale)} /> + } + + const { container, rerender } = render() + + expect(container.firstChild).toHaveStyle("transform: scale(3) translateZ(0)") + + rerender() + + fireEvent.click(container.firstChild as Element) + }) + + await expect(promise).resolves.toEqual(2) +}) + +test("setPose.cycle cycles through poses", async () => { + const Box = motion.div({ + foo: { scale: 3, transition: false }, + bar: { scale: 2, transition: false }, + foobar: { scale: 4, transition: false }, + }) + + const promise = new Promise(resolve => { + const Component = () => { + const [pose, setPose] = usePose("bar", ["bar", "foo", "foobar"]) + + return ( + setPose.cycle()} onPoseComplete={current => resolve(current.scale)} /> + ) + } + + const { container, rerender } = render() + + expect(container.firstChild).toHaveStyle("transform: scale(2) translateZ(0)") + + rerender() + + fireEvent.click(container.firstChild as Element) + fireEvent.click(container.firstChild as Element) + }) + + await expect(promise).resolves.toEqual(4) +}) + +test("setPose.cycle starts at the initially-defined pose", async () => { + const Box = motion.div({ + foo: { scale: 3, transition: false }, + bar: { scale: 2, transition: false }, + foobar: { scale: 4, transition: false }, + }) + + const promise = new Promise(resolve => { + const Component = () => { + const [pose, setPose] = usePose("foo", ["bar", "foo", "foobar"]) + + return ( + setPose.cycle()} onPoseComplete={current => resolve(current.scale)} /> + ) + } + + const { container, rerender } = render() + + expect(container.firstChild).toHaveStyle("transform: scale(3) translateZ(0)") + + rerender() + + fireEvent.click(container.firstChild as Element) + fireEvent.click(container.firstChild as Element) + }) + + await expect(promise).resolves.toEqual(2) +}) +// usePose setPose.cycle // useTransform From 82737721d76435fd96a461eb9806892856c79c89 Mon Sep 17 00:00:00 2001 From: Niels van Hoorn Date: Fri, 23 Nov 2018 10:24:53 +0100 Subject: [PATCH 22/44] Remove prettier config from package.json --- package.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/package.json b/package.json index 876c266c31..94f0f3f2b0 100644 --- a/package.json +++ b/package.json @@ -59,10 +59,6 @@ "style-value-types": "^3.0.7", "stylefire": "^2.3.1" }, - "prettier": { - "parser": "typescript", - "singleQuote": true - }, "husky": { "hooks": { "pre-commit": "lint-staged" @@ -70,7 +66,7 @@ }, "lint-staged": { "*.{ts,tsx}": [ - "prettier --write --config .prettierrc.json", + "prettier --write", "git add" ] }, From fe7481faa6d05323b9dc5775004fa5753e307647 Mon Sep 17 00:00:00 2001 From: Niels van Hoorn Date: Fri, 23 Nov 2018 10:25:12 +0100 Subject: [PATCH 23/44] Added make pretty and make lint --- Makefile | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 88e2ec20e7..bcf44b2531 100644 --- a/Makefile +++ b/Makefile @@ -19,10 +19,13 @@ bootstrap:: node_modules/.yarn-integrity dev: bootstrap webpack-dev-server --config=dev/webpack/config.js -lint: bootstrap - tslint --project tsconfig.json - test: bootstrap yarn test +lint: bootstrap + tslint --project tsconfig.json --fix + +pretty: bootstrap + prettier --write */**/*.tsx */**/*.ts + .PHONY: dev lint From 74f8610594cde0b4d6e8ec0eb99629f37165a8cf Mon Sep 17 00:00:00 2001 From: Niels van Hoorn Date: Fri, 23 Nov 2018 10:28:20 +0100 Subject: [PATCH 24/44] Let prettier handle the semicolons --- tslint.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tslint.json b/tslint.json index b06e6efd81..d35efab82e 100644 --- a/tslint.json +++ b/tslint.json @@ -23,7 +23,7 @@ "quotemark": [true, "double", "avoid-escape"], "react-this-binding-issue": true, "react-unused-props-and-state": true, - "semicolon": [true, "never"], + "semicolon": false, "triple-equals": [true], "typedef-whitespace": [ true, From 73e104f5670ee9d36c2fd89dff624e51deb48abf Mon Sep 17 00:00:00 2001 From: Niels van Hoorn Date: Fri, 23 Nov 2018 10:53:10 +0100 Subject: [PATCH 25/44] Banning all default exports --- dev/examples/custom-transition.tsx | 2 +- dev/examples/dynamic-pose.tsx | 2 +- dev/examples/pose-as-array-prop.tsx | 2 +- dev/examples/pose-as-hook.tsx | 2 +- dev/examples/pose-children.tsx | 3 +-- dev/inc/use-interval.ts | 2 +- src/hooks/use-config.ts | 7 +++---- src/hooks/use-external-ref.ts | 4 +--- src/hooks/use-motion-value.ts | 4 ++-- src/hooks/use-pose-resolver.ts | 8 +++----- src/hooks/use-pose.ts | 6 ++---- src/hooks/use-posed-values.ts | 6 +++--- src/hooks/use-style-attr.ts | 2 +- src/hooks/use-subsequent-render-effect.ts | 4 +--- src/hooks/use-transform.ts | 2 +- src/index.ts | 8 ++++---- src/motion-value/index.ts | 2 +- src/motion/component.ts | 18 ++++++++---------- src/motion/index.ts | 6 ++---- src/utils/create-value.ts | 2 +- src/utils/default-transitions.ts | 2 +- src/utils/transitions.ts | 16 ++++++++++------ 22 files changed, 50 insertions(+), 60 deletions(-) diff --git a/dev/examples/custom-transition.tsx b/dev/examples/custom-transition.tsx index 0ddc4b9320..2a0c512db1 100644 --- a/dev/examples/custom-transition.tsx +++ b/dev/examples/custom-transition.tsx @@ -1,7 +1,7 @@ import * as React from "react" import { motion, usePose } from "@framer" import { Box } from "../styled" -import useInterval from "../inc/use-interval" +import { useInterval } from "../inc/use-interval" const MotionBox = motion(Box)({ ping: { diff --git a/dev/examples/dynamic-pose.tsx b/dev/examples/dynamic-pose.tsx index 50445b292e..b37e1f41f2 100644 --- a/dev/examples/dynamic-pose.tsx +++ b/dev/examples/dynamic-pose.tsx @@ -1,7 +1,7 @@ import * as React from "react" import { motion, usePose } from "@framer" import { Box } from "../styled" -import useInterval from "../inc/use-interval" +import { useInterval } from "../inc/use-interval" const MotionBox = motion(Box)({ ping: { diff --git a/dev/examples/pose-as-array-prop.tsx b/dev/examples/pose-as-array-prop.tsx index 3223ff1d5c..bcae9dbdb2 100644 --- a/dev/examples/pose-as-array-prop.tsx +++ b/dev/examples/pose-as-array-prop.tsx @@ -1,7 +1,7 @@ import * as React from "react" import { motion } from "@framer" import { Box } from "../styled" -import useInterval from "../inc/use-interval" +import { useInterval } from "../inc/use-interval" const MotionBox = motion(Box)({ a: { scale: 2 }, diff --git a/dev/examples/pose-as-hook.tsx b/dev/examples/pose-as-hook.tsx index 230982c244..96303076c5 100644 --- a/dev/examples/pose-as-hook.tsx +++ b/dev/examples/pose-as-hook.tsx @@ -1,7 +1,7 @@ import * as React from "react" import { motion, usePose } from "@framer" import { Box } from "../styled" -import useInterval from "../inc/use-interval" +import { useInterval } from "../inc/use-interval" const MotionBox = motion(Box)({ ping: { x: 100 }, diff --git a/dev/examples/pose-children.tsx b/dev/examples/pose-children.tsx index 35b7871456..77b0568fb5 100644 --- a/dev/examples/pose-children.tsx +++ b/dev/examples/pose-children.tsx @@ -1,8 +1,7 @@ import * as React from "react" import { useState } from "react" import { motion } from "@framer" -import { Box } from "../styled" -import useInterval from "../inc/use-interval" +import { useInterval } from "../inc/use-interval" const Parent = motion.div({ visible: { diff --git a/dev/inc/use-interval.ts b/dev/inc/use-interval.ts index 791a3e05a0..9305afd607 100644 --- a/dev/inc/use-interval.ts +++ b/dev/inc/use-interval.ts @@ -1,6 +1,6 @@ import { useEffect } from "react" -export default (callback: () => void, interval: number = 1000, args: any[] = []) => { +export const useInterval = (callback: () => void, interval: number = 1000, args: any[] = []) => { useEffect(() => { const int = setInterval(callback, interval) return () => clearInterval(int) diff --git a/src/hooks/use-config.ts b/src/hooks/use-config.ts index 11aaf6203d..b759f93604 100644 --- a/src/hooks/use-config.ts +++ b/src/hooks/use-config.ts @@ -3,7 +3,6 @@ import { PoseConfig, PoseConfigFactory, MotionProps } from "../motion/types" const isResolver = (config: PoseConfig | PoseConfigFactory): config is PoseConfigFactory => typeof config === "function" -const useConfig = (baseConfig: PoseConfig | PoseConfigFactory, props: MotionProps) => - useMemo(() => (isResolver(baseConfig) ? baseConfig(props) : baseConfig), []) - -export default useConfig +export const useConfig = (baseConfig: PoseConfig | PoseConfigFactory, props: MotionProps) => { + return useMemo(() => (isResolver(baseConfig) ? baseConfig(props) : baseConfig), []) +} diff --git a/src/hooks/use-external-ref.ts b/src/hooks/use-external-ref.ts index fda136c1a8..1e8431d026 100644 --- a/src/hooks/use-external-ref.ts +++ b/src/hooks/use-external-ref.ts @@ -1,6 +1,6 @@ import { useEffect, useRef, Ref, MutableRefObject } from "react" -const useExternalRef = (external?: Ref) => { +export const useExternalRef = (external?: Ref) => { const ref = !external || typeof external === "function" ? useRef(null) : external useEffect(() => { @@ -13,5 +13,3 @@ const useExternalRef = (external?: Ref) => { return ref } - -export default useExternalRef diff --git a/src/hooks/use-motion-value.ts b/src/hooks/use-motion-value.ts index 23fbc4616e..841c694bb0 100644 --- a/src/hooks/use-motion-value.ts +++ b/src/hooks/use-motion-value.ts @@ -1,4 +1,4 @@ import { useMemo } from "react" -import motionValue from "../motion-value" +import { motionValue } from "../motion-value" -export default (init: number | string) => useMemo(() => motionValue(init), []) +export const useMotionValue = (init: number | string) => useMemo(() => motionValue(init), []) diff --git a/src/hooks/use-pose-resolver.ts b/src/hooks/use-pose-resolver.ts index 45be8fb00f..66525982ee 100644 --- a/src/hooks/use-pose-resolver.ts +++ b/src/hooks/use-pose-resolver.ts @@ -1,12 +1,12 @@ import { useRef, useEffect, MutableRefObject, RefObject } from "react" import { invariant } from "hey-listen" -import getTransition from "../utils/transitions" +import { getTransition } from "../utils/transitions" import { poseToArray } from "../utils/pose-resolvers" import { resolveCurrent, resolveVelocity } from "../utils/resolve-values" import { MotionValue } from "../motion-value" import { createValuesFromPose, bindValuesToRef } from "../utils/create-value" import { PoseConfig, MotionProps, PoseResolver, Pose, MotionValueMap } from "../motion/types" -import useSubsequentRenderEffect from "../hooks/use-subsequent-render-effect" +import { useSubsequentRenderEffect } from "../hooks/use-subsequent-render-effect" import { complex } from "style-value-types" type PoseSubscriber = (v: string | string[]) => void @@ -75,7 +75,7 @@ const createPoseResolver = ( }) } -const usePoseResolver = ( +export const usePoseResolver = ( values: Map, config: PoseConfig, props: MotionProps, @@ -107,5 +107,3 @@ const usePoseResolver = ( } }) } - -export default usePoseResolver diff --git a/src/hooks/use-pose.ts b/src/hooks/use-pose.ts index 844329d771..1455b67e06 100644 --- a/src/hooks/use-pose.ts +++ b/src/hooks/use-pose.ts @@ -1,12 +1,12 @@ import { useMemo } from "react" -import motionValue, { MotionValue } from "../motion-value" +import { MotionValue, motionValue } from "../motion-value" type PoseSetter = { (pose: string | string[]): void cycle: () => void } -const usePose = (initPose: string | string[] = "default", poses?: string[]) => { +export const usePose = (initPose: string | string[] = "default", poses?: string[]) => { return useMemo((): [MotionValue, PoseSetter] => { let i = typeof initPose === "string" && poses ? poses.indexOf(initPose) : 0 @@ -33,5 +33,3 @@ const usePose = (initPose: string | string[] = "default", poses?: string[]) => { return [pose, setPose] }, poses || []) } - -export default usePose diff --git a/src/hooks/use-posed-values.ts b/src/hooks/use-posed-values.ts index 3938965311..ec598ad032 100644 --- a/src/hooks/use-posed-values.ts +++ b/src/hooks/use-posed-values.ts @@ -4,7 +4,7 @@ import { PoseConfig, MotionProps, MotionValueMap } from "../motion/types" import { useRef, useEffect, RefObject } from "react" import { createValuesFromPose, bindValuesToRef } from "../utils/create-value" -export default ( +export const usePosedValues = ( config: PoseConfig, { onPoseComplete, ...props }: MotionProps, ref: RefObject @@ -35,9 +35,9 @@ export default ( const poseDef = config[poseKey] if (!poseDef) return - const pose = typeof poseDef === "function" ? poseDef(props, {}, {}) : poseDef + const currentPose = typeof poseDef === "function" ? poseDef(props, {}, {}) : poseDef - createValuesFromPose(values, pose) + createValuesFromPose(values, currentPose) }) // 3. Bind stylers when ref is ready diff --git a/src/hooks/use-style-attr.ts b/src/hooks/use-style-attr.ts index 1a0a69b50e..b1962a054f 100644 --- a/src/hooks/use-style-attr.ts +++ b/src/hooks/use-style-attr.ts @@ -3,7 +3,7 @@ import { buildStyleProperty } from "stylefire" import { MotionValue } from "../motion-value" import { resolveCurrent } from "../utils/resolve-values" -export default (values: Map, styles?: CSSProperties): CSSProperties => +export const useStyleAttr = (values: Map, styles?: CSSProperties): CSSProperties => useMemo( () => ({ ...styles, diff --git a/src/hooks/use-subsequent-render-effect.ts b/src/hooks/use-subsequent-render-effect.ts index e908c9102b..300dfe872b 100644 --- a/src/hooks/use-subsequent-render-effect.ts +++ b/src/hooks/use-subsequent-render-effect.ts @@ -1,6 +1,6 @@ import { useRef, useEffect } from "react" -const useSubsequentRenderEffect = (callback: () => void, conditions: any[]) => { +export const useSubsequentRenderEffect = (callback: () => void, conditions: any[]) => { const isInitialRender = useRef(true) return useEffect(() => { @@ -11,5 +11,3 @@ const useSubsequentRenderEffect = (callback: () => void, conditions: any[]) => { } }, conditions) } - -export default useSubsequentRenderEffect diff --git a/src/hooks/use-transform.ts b/src/hooks/use-transform.ts index 3737487678..8862c47ec0 100644 --- a/src/hooks/use-transform.ts +++ b/src/hooks/use-transform.ts @@ -2,7 +2,7 @@ import { useMemo, useRef, MutableRefObject } from "react" import { MotionValue } from "../motion-value" import { interpolate } from "@popmotion/popcorn" -export default (value: MotionValue, from: number[], to: string[] | number[]) => { +export const useTransform = (value: MotionValue, from: number[], to: string[] | number[]) => { const transformedValue: MutableRefObject = useRef(null) return useMemo( diff --git a/src/index.ts b/src/index.ts index 24e11d8c5f..e8e8e43bfc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ -import motion from "./motion" -import useMotionValue from "./hooks/use-motion-value" -import useTransform from "./hooks/use-transform" -import usePose from "./hooks/use-pose" +import { motion } from "./motion" +import { useMotionValue } from "./hooks/use-motion-value" +import { useTransform } from "./hooks/use-transform" +import { usePose } from "./hooks/use-pose" export { motion, useMotionValue, useTransform, usePose } diff --git a/src/motion-value/index.ts b/src/motion-value/index.ts index 31737f606b..5fff8b152e 100644 --- a/src/motion-value/index.ts +++ b/src/motion-value/index.ts @@ -179,4 +179,4 @@ export class MotionValue { } } -export default (init: ValuePrimitive, opts?: Config) => new MotionValue(init, opts) +export const motionValue = (init: ValuePrimitive, opts?: Config) => new MotionValue(init, opts) diff --git a/src/motion/component.ts b/src/motion/component.ts index e080ab617b..14a1191fa5 100644 --- a/src/motion/component.ts +++ b/src/motion/component.ts @@ -1,14 +1,14 @@ import { memo, forwardRef, createElement, Ref, ComponentType } from "react" import { MotionProps, ComponentFactory } from "./types" -import useConfig from "../hooks/use-config" -import useExternalRef from "../hooks/use-external-ref" -import usePosedValues from "../hooks/use-posed-values" -import usePoseResolver from "../hooks/use-pose-resolver" -import useStyleAttr from "../hooks/use-style-attr" +import { useConfig } from "../hooks/use-config" +import { useExternalRef } from "../hooks/use-external-ref" +import { usePosedValues } from "../hooks/use-posed-values" +import { usePoseResolver } from "../hooks/use-pose-resolver" +import { useStyleAttr } from "../hooks/use-style-attr" -const createMotionComponent =

(Component: string | ComponentType

): ComponentFactory

=> ( - poseConfig = {} -): ComponentType

=> { +export const createMotionComponent =

( + Component: string | ComponentType

+): ComponentFactory

=> (poseConfig = {}): ComponentType

=> { const MotionComponent = (props: MotionProps, externalRef?: Ref) => { const ref = useExternalRef(externalRef) const config = useConfig(poseConfig, props) @@ -27,5 +27,3 @@ const createMotionComponent =

(Component: string | Compon return memo(forwardRef(MotionComponent)) } - -export default createMotionComponent diff --git a/src/motion/index.ts b/src/motion/index.ts index db7fd5d9c9..313e8a0b04 100644 --- a/src/motion/index.ts +++ b/src/motion/index.ts @@ -1,5 +1,5 @@ import { HTMLProps, SVGProps, ComponentType } from "react" -import createMotionComponent from "./component" +import { createMotionComponent } from "./component" import { htmlElements, svgElements } from "./supported-elements" import { ComponentFactory, MotionProps } from "./types" @@ -8,9 +8,7 @@ export type Motion = { [key: string]: ComponentFactory<(HTMLProps | SVGProps) & MotionProps> } -const motion: Motion = createMotionComponent as Motion +export const motion: Motion = createMotionComponent as Motion htmlElements.forEach(element => (motion[element] = createMotionComponent(element))) svgElements.forEach(element => (motion[element] = createMotionComponent(element))) - -export default motion diff --git a/src/utils/create-value.ts b/src/utils/create-value.ts index 19588009be..15f44c17dc 100644 --- a/src/utils/create-value.ts +++ b/src/utils/create-value.ts @@ -1,6 +1,6 @@ import { RefObject } from "react" import { MotionValueMap, Pose } from "../motion/types" -import motionValue from "../motion-value" +import { motionValue } from "../motion-value" import styler from "stylefire" import { invariant } from "hey-listen" diff --git a/src/utils/default-transitions.ts b/src/utils/default-transitions.ts index ca45384394..b778209613 100644 --- a/src/utils/default-transitions.ts +++ b/src/utils/default-transitions.ts @@ -36,7 +36,7 @@ const defaultTransitions = { default: overDampedSpring, } -export default (valueKey: string, to: string | number): Transition => { +export const getDefaultTransition = (valueKey: string, to: string | number): Transition => { const transitionFactory = defaultTransitions[valueKey] || defaultTransitions.default return { ...transitionFactory(to), to } } diff --git a/src/utils/transitions.ts b/src/utils/transitions.ts index 38b0a3e3f4..ab954d6645 100644 --- a/src/utils/transitions.ts +++ b/src/utils/transitions.ts @@ -1,6 +1,6 @@ import { action, tween, spring, keyframes, decay, physics, easing, Action } from "popmotion" import { Transition, TransitionProp, Tween, Keyframes, EasingFunction, TransitionMap } from "../motion/types" -import getDefaultTransition from "./default-transitions" +import { getDefaultTransition } from "./default-transitions" import { invariant } from "hey-listen" import { ActionFactory } from "../motion-value" @@ -62,7 +62,7 @@ const transitionOptionParser = { keyframes: ({ from, to, ...opts }: Keyframes) => opts, } -const getTransition = (valueKey: string, to: string | number, transitionProp?: TransitionProp): Transition => { +const getTransitionProps = (valueKey: string, to: string | number, transitionProp?: TransitionProp): Transition => { if (transitionProp !== undefined) { let transition: Transition = {} @@ -81,11 +81,15 @@ const getTransition = (valueKey: string, to: string | number, transitionProp?: T const preprocessOptions = (type: string, opts: Transition): Transition => transitionOptionParser[type] ? transitionOptionParser[type](opts) : opts -export default (valueKey: string, to: string | number, transition?: TransitionProp): [ActionFactory, Transition] => { - const { type = "tween", ...transitionDefinition } = getTransition(valueKey, to, transition) +export const getTransition = ( + valueKey: string, + to: string | number, + transition?: TransitionProp +): [ActionFactory, Transition] => { + const { type = "tween", ...transitionDefinition } = getTransitionProps(valueKey, to, transition) - const action: ActionFactory = transitions[type] + const actionFactory: ActionFactory = transitions[type] const opts: Transition = preprocessOptions(type, transitionDefinition) - return [action, opts] + return [actionFactory, opts] } From 20289aca2c71748347e627fad6d2fe8ed781605d Mon Sep 17 00:00:00 2001 From: Niels van Hoorn Date: Fri, 23 Nov 2018 10:59:24 +0100 Subject: [PATCH 26/44] Add staggerChildren to BaseTransition --- src/motion/types.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/motion/types.ts b/src/motion/types.ts index 0d804c7112..f8f3481345 100644 --- a/src/motion/types.ts +++ b/src/motion/types.ts @@ -41,6 +41,7 @@ export type BaseTransition = { from?: number | string to?: number | string velocity?: number + staggerChildren?: number } export type Tween = BaseTransition & { From b0157f145253340013c7cf81264a6cd7148ddca8 Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Fri, 23 Nov 2018 10:07:30 +0000 Subject: [PATCH 27/44] latest --- src/motion/__tests__/component.test.tsx | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/motion/__tests__/component.test.tsx b/src/motion/__tests__/component.test.tsx index 9b035238da..026399da7a 100644 --- a/src/motion/__tests__/component.test.tsx +++ b/src/motion/__tests__/component.test.tsx @@ -2,6 +2,7 @@ import { fireEvent, render } from "react-testing-library" import motion from "../" import * as React from "react" import useMotionValue from "../../hooks/use-motion-value" +import useTransform from "../../hooks/use-transform" import usePose from "../../hooks/use-pose" import styled from "styled-components" @@ -226,5 +227,17 @@ test("setPose.cycle starts at the initially-defined pose", async () => { await expect(promise).resolves.toEqual(2) }) -// usePose setPose.cycle -// useTransform +test("useTransform", async () => { + const Box = motion.div() + + const Component = () => { + const x = useMotionValue(75) + const y = useTransform(x, [0, 100], [200, 100]) + + return + } + + const { container } = render() + + expect(container.firstChild).toHaveStyle("transform: translateX(75px) translateY(175px) translateZ(0)") +}) From 524720f38a916560db5a99a9256f8e232a351e46 Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Fri, 23 Nov 2018 10:08:10 +0000 Subject: [PATCH 28/44] updating test imports --- src/motion/__tests__/component.test.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/motion/__tests__/component.test.tsx b/src/motion/__tests__/component.test.tsx index 026399da7a..aec5d5c37f 100644 --- a/src/motion/__tests__/component.test.tsx +++ b/src/motion/__tests__/component.test.tsx @@ -1,9 +1,9 @@ import { fireEvent, render } from "react-testing-library" -import motion from "../" +import { motion } from "../" import * as React from "react" -import useMotionValue from "../../hooks/use-motion-value" -import useTransform from "../../hooks/use-transform" -import usePose from "../../hooks/use-pose" +import { useMotionValue } from "../../hooks/use-motion-value" +import { useTransform } from "../../hooks/use-transform" +import { usePose } from "../../hooks/use-pose" import styled from "styled-components" /** From 9124086dfab4b3aa68246723010cacaeaf8bd0a1 Mon Sep 17 00:00:00 2001 From: Niels van Hoorn Date: Fri, 23 Nov 2018 11:54:54 +0100 Subject: [PATCH 29/44] Improved types of createMotionComponent --- src/motion/component.ts | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/motion/component.ts b/src/motion/component.ts index 14a1191fa5..e854ab4ec8 100644 --- a/src/motion/component.ts +++ b/src/motion/component.ts @@ -1,4 +1,4 @@ -import { memo, forwardRef, createElement, Ref, ComponentType } from "react" +import { memo, forwardRef, createElement, Ref, ComponentType, NamedExoticComponent } from "react" import { MotionProps, ComponentFactory } from "./types" import { useConfig } from "../hooks/use-config" import { useExternalRef } from "../hooks/use-external-ref" @@ -6,24 +6,26 @@ import { usePosedValues } from "../hooks/use-posed-values" import { usePoseResolver } from "../hooks/use-pose-resolver" import { useStyleAttr } from "../hooks/use-style-attr" -export const createMotionComponent =

( - Component: string | ComponentType

-): ComponentFactory

=> (poseConfig = {}): ComponentType

=> { - const MotionComponent = (props: MotionProps, externalRef?: Ref) => { - const ref = useExternalRef(externalRef) - const config = useConfig(poseConfig, props) +export const createMotionComponent =

(Component: string | ComponentType

): ComponentFactory

=> { + return (poseConfig = {}): NamedExoticComponent

=> { + { + const MotionComponent = (props: P & MotionProps, externalRef?: Ref) => { + const ref = useExternalRef(externalRef) + const config = useConfig(poseConfig, props) - // Create motion values - const [values, componentProps] = usePosedValues(config, props, ref) + // Create motion values + const [values, componentProps] = usePosedValues(config, props, ref) - usePoseResolver(values, config, props, ref) + usePoseResolver(values, config, props, ref) - return createElement(Component, { - ...componentProps, - ref, - style: useStyleAttr(values, props.style), - }) - } + return createElement(Component, { + ...componentProps, + ref, + style: useStyleAttr(values, props.style), + }) + } - return memo(forwardRef(MotionComponent)) + return memo(forwardRef(MotionComponent)) + } + } } From 78162c8e253ef9c70e24c4d1673448d85a68bc1a Mon Sep 17 00:00:00 2001 From: Niels van Hoorn Date: Fri, 23 Nov 2018 12:46:36 +0100 Subject: [PATCH 30/44] rename target to targetValue --- dev/examples/dynamic-pose.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dev/examples/dynamic-pose.tsx b/dev/examples/dynamic-pose.tsx index b37e1f41f2..574e1596fe 100644 --- a/dev/examples/dynamic-pose.tsx +++ b/dev/examples/dynamic-pose.tsx @@ -9,7 +9,9 @@ const MotionBox = motion(Box)({ y: "0vh", transition: { duration: 100 }, }, - pong: ({ target }) => ({ x: target, y: "0vh" }), + pong: ({ targetValue }) => { + return { x: targetValue, y: "0vh" } + }, }) export const App = () => { @@ -19,5 +21,5 @@ export const App = () => { setPose(pose.get() === "ping" ? "pong" : "ping") }, 1000) - return + return } From 3064a632c2fe73a1e3640f498d31485896c50898 Mon Sep 17 00:00:00 2001 From: Niels van Hoorn Date: Fri, 23 Nov 2018 12:47:18 +0100 Subject: [PATCH 31/44] Move MotionProps to ComponentFactory type --- src/motion/index.ts | 2 +- src/motion/types.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/motion/index.ts b/src/motion/index.ts index 313e8a0b04..eba831903b 100644 --- a/src/motion/index.ts +++ b/src/motion/index.ts @@ -4,7 +4,7 @@ import { htmlElements, svgElements } from "./supported-elements" import { ComponentFactory, MotionProps } from "./types" export type Motion = { - (component: ComponentType): ComponentFactory<(HTMLProps | SVGProps) & MotionProps> + (component: ComponentType): ComponentFactory | SVGProps> [key: string]: ComponentFactory<(HTMLProps | SVGProps) & MotionProps> } diff --git a/src/motion/types.ts b/src/motion/types.ts index f8f3481345..3f08a52a28 100644 --- a/src/motion/types.ts +++ b/src/motion/types.ts @@ -1,7 +1,7 @@ import { MotionValue } from "../motion-value" import { CSSProperties, ComponentType, Ref } from "react" -export type ComponentFactory = (config?: PoseConfigFactory | PoseConfig) => ComponentType +export type ComponentFactory = (config?: PoseConfigFactory | PoseConfig) => ComponentType export type PoseConfigFactory = (props: MotionProps) => PoseConfig From 78a625239c37c997b8b5ec0cabc8bbb7ecd58b6c Mon Sep 17 00:00:00 2001 From: Niels van Hoorn Date: Fri, 23 Nov 2018 12:48:11 +0100 Subject: [PATCH 32/44] Added forgotten spread --- src/hooks/use-pose-resolver.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/use-pose-resolver.ts b/src/hooks/use-pose-resolver.ts index 66525982ee..6d1ccb16a4 100644 --- a/src/hooks/use-pose-resolver.ts +++ b/src/hooks/use-pose-resolver.ts @@ -16,7 +16,7 @@ const isAnimatable = (value: string | number) => typeof value === "number" || co const createPoseResolver = ( values: MotionValueMap, config: PoseConfig, - { onPoseComplete, props }: MotionProps, + { onPoseComplete, ...props }: MotionProps, ref: RefObject ) => (poseList: string[]) => { const poseTransitions: Promise[] = [] From dc49b6947e6bbd46172fb7660fa155a7a1c0f72f Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Fri, 23 Nov 2018 11:02:22 +0000 Subject: [PATCH 33/44] latest tests --- src/hooks/use-pose-resolver.ts | 2 +- src/motion/__tests__/component.test.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hooks/use-pose-resolver.ts b/src/hooks/use-pose-resolver.ts index 6d1ccb16a4..3ea41d6ff3 100644 --- a/src/hooks/use-pose-resolver.ts +++ b/src/hooks/use-pose-resolver.ts @@ -105,5 +105,5 @@ export const usePoseResolver = ( ;(pose as MotionValue).removeSubscriber(poseSubscriber.current) } } - }) + }, []) } diff --git a/src/motion/__tests__/component.test.tsx b/src/motion/__tests__/component.test.tsx index aec5d5c37f..6af1a350b8 100644 --- a/src/motion/__tests__/component.test.tsx +++ b/src/motion/__tests__/component.test.tsx @@ -239,5 +239,5 @@ test("useTransform", async () => { const { container } = render() - expect(container.firstChild).toHaveStyle("transform: translateX(75px) translateY(175px) translateZ(0)") + expect(container.firstChild).toHaveStyle("transform: translateX(75px) translateY(125px) translateZ(0)") }) From 1e42476c1c5ad6d3eb6a19cfd439f811a0cec79b Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Fri, 23 Nov 2018 13:25:21 +0000 Subject: [PATCH 34/44] latest --- src/hooks/use-pose-resolver.ts | 93 +++++++++++++++++++--------------- src/hooks/use-posed-values.ts | 1 - 2 files changed, 52 insertions(+), 42 deletions(-) diff --git a/src/hooks/use-pose-resolver.ts b/src/hooks/use-pose-resolver.ts index 3ea41d6ff3..6c3a7caccf 100644 --- a/src/hooks/use-pose-resolver.ts +++ b/src/hooks/use-pose-resolver.ts @@ -13,66 +13,77 @@ type PoseSubscriber = (v: string | string[]) => void const isAnimatable = (value: string | number) => typeof value === "number" || complex.test(value) +const isPoseResolver = (pose: Pose | PoseResolver): pose is PoseResolver => typeof pose === "function" + const createPoseResolver = ( values: MotionValueMap, config: PoseConfig, { onPoseComplete, ...props }: MotionProps, ref: RefObject -) => (poseList: string[]) => { - const poseTransitions: Promise[] = [] +) => { + const poseResolver = (poseList: string[]) => { + const poseTransitions: Promise[] = [] + const animating = new Set() - poseList.reverse().forEach(poseKey => { - invariant(config[poseKey] !== undefined, `Pose with name ${poseKey} not found.`) + poseList.reverse().forEach(poseKey => { + invariant(config[poseKey] !== undefined, `Pose with name ${poseKey} not found.`) - const pose: Pose = - typeof config[poseKey] === "function" - ? (config[poseKey] as PoseResolver)(props, resolveCurrent(values), resolveVelocity(values)) - : (config[poseKey] as Pose) + const poseDefinition = config[poseKey] + const pose: Pose = isPoseResolver(poseDefinition) + ? poseDefinition(props, resolveCurrent(values), resolveVelocity(values)) + : poseDefinition - const { transition, transitionEnd, ...thisPose } = pose + const { transition, transitionEnd, ...remainingPoseValues } = pose + let thisPose = remainingPoseValues - const valueTransitions: Promise[] = [] + const valueTransitions: Promise[] = [] - Object.keys(thisPose).forEach(valueKey => { - const target = thisPose[valueKey] + Object.keys(thisPose).forEach(valueKey => { + if (animating.has(valueKey)) return + animating.add(valueKey) - // If this value doesn't exist in the value map, create it - if (!values.has(valueKey)) { - createValuesFromPose(values, pose) - bindValuesToRef(values, ref) - } + const target = thisPose[valueKey] - const value: MotionValue = values.get(valueKey) as MotionValue + // If this value doesn't exist in the value map, create it + if (!values.has(valueKey)) { + createValuesFromPose(values, pose) + bindValuesToRef(values, ref) + } - if (isAnimatable(target)) { - // If we can animate this value, for instance 100, '100px' or '#fff' - const [action, opts] = getTransition(valueKey, target, transition) + const value: MotionValue = values.get(valueKey) as MotionValue - if (value) { - valueTransitions.push(value.control(action, opts)) + if (isAnimatable(target)) { + // If we can animate this value, for instance 100, '100px' or '#fff' + const [action, opts] = getTransition(valueKey, target, transition) + + if (value) { + valueTransitions.push(value.control(action, opts)) + } + } else { + // If this is not an animatable value, for instance `display: block`, just set it. + value.set(target) } - } else { - // If this is not an animatable value, for instance `display: block`, just set it. - value.set(target) - } - }) + }) - poseTransitions.push( - Promise.all(valueTransitions).then(() => { - if (!transitionEnd) return + poseTransitions.push( + Promise.all(valueTransitions).then(() => { + if (!transitionEnd) return - Object.keys(transitionEnd).forEach(valueKey => { - if (values.has(valueKey)) { - ;(values.get(valueKey) as MotionValue).set(transitionEnd[valueKey]) - } + Object.keys(transitionEnd).forEach(valueKey => { + if (values.has(valueKey)) { + ;(values.get(valueKey) as MotionValue).set(transitionEnd[valueKey]) + } + }) }) - }) - ) - }) + ) + }) + + return Promise.all(poseTransitions).then(() => { + onPoseComplete && onPoseComplete(resolveCurrent(values), resolveVelocity(values)) + }) + } - return Promise.all(poseTransitions).then(() => { - onPoseComplete && onPoseComplete(resolveCurrent(values), resolveVelocity(values)) - }) + return poseResolver } export const usePoseResolver = ( diff --git a/src/hooks/use-posed-values.ts b/src/hooks/use-posed-values.ts index ec598ad032..f9f81b893b 100644 --- a/src/hooks/use-posed-values.ts +++ b/src/hooks/use-posed-values.ts @@ -43,7 +43,6 @@ export const usePosedValues = ( // 3. Bind stylers when ref is ready useEffect(() => { bindValuesToRef(values, ref) - return () => values.forEach(value => value.destroy()) }, []) From 087136af81faf3dd39ad46282b7808b8887ff375 Mon Sep 17 00:00:00 2001 From: Niels van Hoorn Date: Fri, 23 Nov 2018 14:47:34 +0100 Subject: [PATCH 35/44] Improving the motion types --- src/motion/component.ts | 2 +- src/motion/index.ts | 10 +++++----- src/motion/supported-elements.ts | 16 ++++++++++++---- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/motion/component.ts b/src/motion/component.ts index e854ab4ec8..2419eef61a 100644 --- a/src/motion/component.ts +++ b/src/motion/component.ts @@ -6,7 +6,7 @@ import { usePosedValues } from "../hooks/use-posed-values" import { usePoseResolver } from "../hooks/use-pose-resolver" import { useStyleAttr } from "../hooks/use-style-attr" -export const createMotionComponent =

(Component: string | ComponentType

): ComponentFactory

=> { +export const createMotionComponent =

(Component: string | ComponentType

): ComponentFactory

=> { return (poseConfig = {}): NamedExoticComponent

=> { { const MotionComponent = (props: P & MotionProps, externalRef?: Ref) => { diff --git a/src/motion/index.ts b/src/motion/index.ts index eba831903b..be28309131 100644 --- a/src/motion/index.ts +++ b/src/motion/index.ts @@ -1,12 +1,12 @@ import { HTMLProps, SVGProps, ComponentType } from "react" import { createMotionComponent } from "./component" -import { htmlElements, svgElements } from "./supported-elements" -import { ComponentFactory, MotionProps } from "./types" +import { htmlElements, svgElements, HTMLElements, SVGElements } from "./supported-elements" +import { ComponentFactory } from "./types" export type Motion = { - (component: ComponentType): ComponentFactory | SVGProps> - [key: string]: ComponentFactory<(HTMLProps | SVGProps) & MotionProps> -} +

(component: ComponentType

): ComponentFactory

+} & { [K in HTMLElements]: ComponentFactory> } & + { [K in SVGElements]: ComponentFactory> } export const motion: Motion = createMotionComponent as Motion diff --git a/src/motion/supported-elements.ts b/src/motion/supported-elements.ts index b6deb25d3a..5130bd94a8 100644 --- a/src/motion/supported-elements.ts +++ b/src/motion/supported-elements.ts @@ -1,4 +1,10 @@ -export const htmlElements = [ +/** + * This is the identity function that helps TypeScript understand the type of the provided array + */ +const tuple = (args: T[]) => args +type UnionStringArray = T[number] + +export const htmlElements = tuple([ "a", "article", "aside", @@ -69,9 +75,9 @@ export const htmlElements = [ "ul", "video", "svg", -] +]) -export const svgElements = [ +export const svgElements = tuple([ "circle", "clipPath", "defs", @@ -90,4 +96,6 @@ export const svgElements = [ "stop", "text", "tspan", -] +]) +export type HTMLElements = UnionStringArray +export type SVGElements = UnionStringArray From aee0246c4f262034cc26d81edcea514ba14a6558 Mon Sep 17 00:00:00 2001 From: Niels van Hoorn Date: Fri, 23 Nov 2018 15:58:52 +0100 Subject: [PATCH 36/44] Even more specific types for motion --- src/motion/index.ts | 8 ++- src/motion/supported-elements.ts | 97 +++++++++++++++++++++++++++++--- 2 files changed, 94 insertions(+), 11 deletions(-) diff --git a/src/motion/index.ts b/src/motion/index.ts index be28309131..db279bef32 100644 --- a/src/motion/index.ts +++ b/src/motion/index.ts @@ -1,12 +1,14 @@ -import { HTMLProps, SVGProps, ComponentType } from "react" +import { ReactSVG, SVGAttributes, SVGProps, ComponentType, ReactHTML, DetailedHTMLFactory } from "react" import { createMotionComponent } from "./component" import { htmlElements, svgElements, HTMLElements, SVGElements } from "./supported-elements" import { ComponentFactory } from "./types" +type UnwrapFactory = F extends DetailedHTMLFactory ? P : never + export type Motion = {

(component: ComponentType

): ComponentFactory

-} & { [K in HTMLElements]: ComponentFactory> } & - { [K in SVGElements]: ComponentFactory> } +} & { [K in HTMLElements]: ComponentFactory> } & + { [K in SVGElements]: ComponentFactory> } export const motion: Motion = createMotionComponent as Motion diff --git a/src/motion/supported-elements.ts b/src/motion/supported-elements.ts index 5130bd94a8..7d21a0d089 100644 --- a/src/motion/supported-elements.ts +++ b/src/motion/supported-elements.ts @@ -1,15 +1,22 @@ -/** - * This is the identity function that helps TypeScript understand the type of the provided array - */ -const tuple = (args: T[]) => args +import { ReactHTML, ReactSVG } from "react" +// These are identity functions that help TypeScript understand the type of the provided array +const htmlTuple = (args: T[]) => args +const svgTuple = (args: T[]) => args type UnionStringArray = T[number] -export const htmlElements = tuple([ +export const htmlElements = htmlTuple([ "a", + "abbr", + "address", + "area", "article", "aside", "audio", "b", + "base", + "bdi", + "bdo", + "big", "blockquote", "body", "br", @@ -22,8 +29,14 @@ export const htmlElements = tuple([ "colgroup", "data", "datalist", + "dd", + "del", + "details", + "dfn", "dialog", "div", + "dl", + "dt", "em", "embed", "fieldset", @@ -41,27 +54,54 @@ export const htmlElements = tuple([ "header", "hgroup", "hr", + "html", "i", "iframe", "img", "input", + "ins", + "kbd", + "keygen", "label", "legend", "li", + "link", + "main", + "map", + "mark", + "menu", + "menuitem", + "meta", + "meter", "nav", + "noscript", "object", "ol", + "optgroup", "option", + "output", "p", "param", "picture", "pre", "progress", "q", + "rp", + "rt", + "ruby", + "s", + "samp", + "script", "section", "select", + "small", + "source", "span", "strong", + "style", + "sub", + "summary", + "sup", "table", "tbody", "td", @@ -72,21 +112,57 @@ export const htmlElements = tuple([ "time", "title", "tr", + "track", + "u", "ul", + "var", "video", - "svg", + "wbr", + "webview", ]) +export type HTMLElements = UnionStringArray -export const svgElements = tuple([ +export const svgElements: (keyof ReactSVG)[] = svgTuple([ + "animate", "circle", "clipPath", "defs", + "desc", "ellipse", + "feBlend", + "feColorMatrix", + "feComponentTransfer", + "feComposite", + "feConvolveMatrix", + "feDiffuseLighting", + "feDisplacementMap", + "feDistantLight", + "feDropShadow", + "feFlood", + "feFuncA", + "feFuncB", + "feFuncG", + "feFuncR", + "feGaussianBlur", + "feImage", + "feMerge", + "feMergeNode", + "feMorphology", + "feOffset", + "fePointLight", + "feSpecularLighting", + "feSpotLight", + "feTile", + "feTurbulence", + "filter", + "foreignObject", "g", "image", "line", "linearGradient", + "marker", "mask", + "metadata", "path", "pattern", "polygon", @@ -94,8 +170,13 @@ export const svgElements = tuple([ "radialGradient", "rect", "stop", + "svg", + "switch", + "symbol", "text", + "textPath", "tspan", + "use", + "view", ]) -export type HTMLElements = UnionStringArray export type SVGElements = UnionStringArray From 58fd4ba17ddad79e47119896aabc1922ce367538 Mon Sep 17 00:00:00 2001 From: Niels van Hoorn Date: Fri, 23 Nov 2018 16:05:28 +0100 Subject: [PATCH 37/44] Remove unused imports --- src/motion/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/motion/index.ts b/src/motion/index.ts index db279bef32..a96e60f3f1 100644 --- a/src/motion/index.ts +++ b/src/motion/index.ts @@ -1,4 +1,4 @@ -import { ReactSVG, SVGAttributes, SVGProps, ComponentType, ReactHTML, DetailedHTMLFactory } from "react" +import { SVGAttributes, ComponentType, ReactHTML, DetailedHTMLFactory } from "react" import { createMotionComponent } from "./component" import { htmlElements, svgElements, HTMLElements, SVGElements } from "./supported-elements" import { ComponentFactory } from "./types" From 0d190747ea2dea337849774cf830197052770677 Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Fri, 23 Nov 2018 15:55:04 +0000 Subject: [PATCH 38/44] animate between value types --- dev/examples/convert-value-types.tsx | 19 ++++ src/dom/unit-type-conversion.ts | 124 +++++++++++++++++++++++++++ src/hooks/use-pose-resolver.ts | 8 +- src/hooks/use-posed-values.ts | 3 +- src/motion-value/index.ts | 2 +- src/utils/value-types.ts | 11 +++ 6 files changed, 163 insertions(+), 4 deletions(-) create mode 100644 dev/examples/convert-value-types.tsx create mode 100644 src/dom/unit-type-conversion.ts create mode 100644 src/utils/value-types.ts diff --git a/dev/examples/convert-value-types.tsx b/dev/examples/convert-value-types.tsx new file mode 100644 index 0000000000..98bfd5182b --- /dev/null +++ b/dev/examples/convert-value-types.tsx @@ -0,0 +1,19 @@ +import * as React from "react" +import { motion, usePose } from "@framer" +import { Box } from "../styled" + +const MotionBox = motion(Box)({ + b: { width: "auto", x: "50%" }, + c: { width: "calc(50vw)", x: 0 }, + a: { width: 100, x: 100 }, +}) + +export const App = () => { + const [pose, setPose] = usePose("b", ["b", "a", "c"]) + + return ( +

+ setPose.cycle()} /> +
+ ) +} diff --git a/src/dom/unit-type-conversion.ts b/src/dom/unit-type-conversion.ts new file mode 100644 index 0000000000..457f97a264 --- /dev/null +++ b/src/dom/unit-type-conversion.ts @@ -0,0 +1,124 @@ +import { Pose, MotionValueMap } from "../motion/types" +import { RefObject } from "react" +import { getValueType } from "../utils/value-types" +import styler from "stylefire" +import { MotionValue } from "../motion-value" + +const positionalKeys = new Set(["width", "height", "top", "left", "right", "bottom", "x", "y"]) +const isPositionalKey = (key: string) => positionalKeys.has(key) +const hasPositionalKey = (pose: Pose) => Object.keys(pose).some(isPositionalKey) + +const setAndResetVelocity = (value: MotionValue, to: string | number) => { + // Looks odd but setting it twice doesn't render, it'll just + // set both prev and current to the latest value + value.set(to) + value.set(to) +} + +export type BoundingBox = { [key in BoundingBoxDimension]: number } + +export enum BoundingBoxDimension { + width = "width", + height = "height", + left = "left", + right = "right", + top = "top", + bottom = "bottom", +} + +type GetActualMeasurementInPixels = (bbox: ClientRect | DOMRect, computedStyle: Partial) => number + +const getPosFromMatrix = (matrix: string, pos: number) => parseFloat(matrix.split(", ")[pos]) + +const getTranslateFromMatrix = (pos2: number, pos3: number): GetActualMeasurementInPixels => (_bbox, { transform }) => { + if (transform === "none" || !transform) return 0 + + const matrix3d = transform.match(/^matrix3d\((.+)\)$/) + + if (matrix3d) { + return getPosFromMatrix(matrix3d[1], pos3) + } else { + const matrix = transform.match(/^matrix\((.+)\)$/) as string[] + return getPosFromMatrix(matrix[1], pos2) + } +} + +const positionalValues: { [key: string]: GetActualMeasurementInPixels } = { + // Dimensions + width: ({ width }) => width, + height: ({ height }) => height, + + top: (_bbox, { top }) => parseFloat(top as string), + left: (_bbox, { left }) => parseFloat(left as string), + bottom: ({ height }, { top }) => parseFloat(top as string) + height, + right: ({ width }, { left }) => parseFloat(left as string) + width, + + // Transform + x: getTranslateFromMatrix(4, 13), + y: getTranslateFromMatrix(5, 14), +} + +const convertChangedValueTypes = ( + pose: Pose, + values: MotionValueMap, + ref: RefObject, + changedKeys: string[] +) => { + const element = ref.current as Element + const elementStyler = styler(element) + const originBbox = element.getBoundingClientRect() + const elementComputedStyle = getComputedStyle(element) + const { top, left, bottom, right, transform } = elementComputedStyle + const originComputedStyle = { top, left, bottom, right, transform } + + // Apply the latest values (as set in checkAndConvertChangedValueTypes) + elementStyler.render() + + const targetBbox = element.getBoundingClientRect() + + changedKeys.forEach(key => { + // Restore styles to their **calculated computed style**, not their actual + // originally set style. This allows us to animate between equivalent pixel units. + const value = values.get(key) as MotionValue + setAndResetVelocity(value, positionalValues[key](originBbox, originComputedStyle)) + pose[key] = positionalValues[key](targetBbox, elementComputedStyle) + }) + + // Reapply original values + elementStyler.render() + + return pose +} + +const checkAndConvertChangedValueTypes = (pose: Pose, values: MotionValueMap, ref: RefObject) => { + let { transitionEnd = {} } = pose + transitionEnd = { ...transitionEnd } + const posePositionalKeys = Object.keys(pose).filter(isPositionalKey) + + const changedValueTypeKeys: string[] = posePositionalKeys.reduce( + (acc, key) => { + const value = values.get(key) as MotionValue + const from = value!.get() + const to = pose[key] + const fromType = getValueType(from) + const toType = getValueType(to) + + if (fromType !== toType) { + acc.push(key) + transitionEnd[key] = transitionEnd[key] || pose[key] + setAndResetVelocity(value, to) + } + + return acc + }, + [] as string[] + ) + + return changedValueTypeKeys.length + ? convertChangedValueTypes({ ...pose, transitionEnd }, values, ref, changedValueTypeKeys) + : pose +} + +export const transformPose = (pose: Pose, values: MotionValueMap, ref: RefObject) => { + return hasPositionalKey(pose) ? checkAndConvertChangedValueTypes(pose, values, ref) : pose +} diff --git a/src/hooks/use-pose-resolver.ts b/src/hooks/use-pose-resolver.ts index 6c3a7caccf..6da6f8d27a 100644 --- a/src/hooks/use-pose-resolver.ts +++ b/src/hooks/use-pose-resolver.ts @@ -7,6 +7,7 @@ import { MotionValue } from "../motion-value" import { createValuesFromPose, bindValuesToRef } from "../utils/create-value" import { PoseConfig, MotionProps, PoseResolver, Pose, MotionValueMap } from "../motion/types" import { useSubsequentRenderEffect } from "../hooks/use-subsequent-render-effect" +import { transformPose } from "../dom/unit-type-conversion" import { complex } from "style-value-types" type PoseSubscriber = (v: string | string[]) => void @@ -29,10 +30,15 @@ const createPoseResolver = ( invariant(config[poseKey] !== undefined, `Pose with name ${poseKey} not found.`) const poseDefinition = config[poseKey] - const pose: Pose = isPoseResolver(poseDefinition) + let pose: Pose = isPoseResolver(poseDefinition) ? poseDefinition(props, resolveCurrent(values), resolveVelocity(values)) : poseDefinition + // This feels like a good candidate to inject a transform function via + // a `PluginContext`, or perhaps a factory function, that can take a pose, + // maybe run side-effects (ie DOM measurement), and return a new one + pose = transformPose(pose, values, ref) + const { transition, transitionEnd, ...remainingPoseValues } = pose let thisPose = remainingPoseValues diff --git a/src/hooks/use-posed-values.ts b/src/hooks/use-posed-values.ts index f9f81b893b..b16fca95f1 100644 --- a/src/hooks/use-posed-values.ts +++ b/src/hooks/use-posed-values.ts @@ -6,7 +6,7 @@ import { createValuesFromPose, bindValuesToRef } from "../utils/create-value" export const usePosedValues = ( config: PoseConfig, - { onPoseComplete, ...props }: MotionProps, + { onPoseComplete, pose = "default", ...props }: MotionProps, ref: RefObject ): [MotionValueMap, Partial] => { const values: MotionValueMap = useRef(new Map()).current @@ -28,7 +28,6 @@ export const usePosedValues = ( }) // 2. Create values from poses - const { pose = "default" } = props const initialPoses = resolvePoses(pose) initialPoses.forEach(poseKey => { diff --git a/src/motion-value/index.ts b/src/motion-value/index.ts index 5fff8b152e..30ce10fc35 100644 --- a/src/motion-value/index.ts +++ b/src/motion-value/index.ts @@ -103,7 +103,7 @@ export class MotionValue { } if (this.onRender) { - sync.render(this.render) + this.onRender(this.current) } // Update timestamp diff --git a/src/utils/value-types.ts b/src/utils/value-types.ts new file mode 100644 index 0000000000..c0e84380ea --- /dev/null +++ b/src/utils/value-types.ts @@ -0,0 +1,11 @@ +import { number, degrees, percent, px, vw, vh, ValueType } from "style-value-types" + +export const auto: ValueType = { + test: (v: any) => v === "auto", + parse: v => v, +} + +const valueTypeTests = [number, degrees, percent, px, vw, vh, auto] +const testValueType = (v: any) => (type: ValueType) => type.test(v) + +export const getValueType = (v: any) => valueTypeTests.find(testValueType(v)) From ef25b70f9fc8a1476ab643559d3171b588272a32 Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Fri, 23 Nov 2018 16:16:48 +0000 Subject: [PATCH 39/44] adding new values if not yet encountered before pose transform --- dev/examples/convert-value-types.tsx | 2 +- src/hooks/use-pose-resolver.ts | 12 +++++------- src/utils/create-value.ts | 11 +++++++++++ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/dev/examples/convert-value-types.tsx b/dev/examples/convert-value-types.tsx index 98bfd5182b..623083853d 100644 --- a/dev/examples/convert-value-types.tsx +++ b/dev/examples/convert-value-types.tsx @@ -3,7 +3,7 @@ import { motion, usePose } from "@framer" import { Box } from "../styled" const MotionBox = motion(Box)({ - b: { width: "auto", x: "50%" }, + b: { width: "auto" }, c: { width: "calc(50vw)", x: 0 }, a: { width: 100, x: 100 }, }) diff --git a/src/hooks/use-pose-resolver.ts b/src/hooks/use-pose-resolver.ts index 6da6f8d27a..1688f8cc25 100644 --- a/src/hooks/use-pose-resolver.ts +++ b/src/hooks/use-pose-resolver.ts @@ -4,7 +4,7 @@ import { getTransition } from "../utils/transitions" import { poseToArray } from "../utils/pose-resolvers" import { resolveCurrent, resolveVelocity } from "../utils/resolve-values" import { MotionValue } from "../motion-value" -import { createValuesFromPose, bindValuesToRef } from "../utils/create-value" +import { checkForNewValues } from "../utils/create-value" import { PoseConfig, MotionProps, PoseResolver, Pose, MotionValueMap } from "../motion/types" import { useSubsequentRenderEffect } from "../hooks/use-subsequent-render-effect" import { transformPose } from "../dom/unit-type-conversion" @@ -34,9 +34,13 @@ const createPoseResolver = ( ? poseDefinition(props, resolveCurrent(values), resolveVelocity(values)) : poseDefinition + checkForNewValues(pose, values, ref) + // This feels like a good candidate to inject a transform function via // a `PluginContext`, or perhaps a factory function, that can take a pose, // maybe run side-effects (ie DOM measurement), and return a new one + // We may need a second `checkForNewValues` after this if we open it up in case + // new values are created. pose = transformPose(pose, values, ref) const { transition, transitionEnd, ...remainingPoseValues } = pose @@ -50,12 +54,6 @@ const createPoseResolver = ( const target = thisPose[valueKey] - // If this value doesn't exist in the value map, create it - if (!values.has(valueKey)) { - createValuesFromPose(values, pose) - bindValuesToRef(values, ref) - } - const value: MotionValue = values.get(valueKey) as MotionValue if (isAnimatable(target)) { diff --git a/src/utils/create-value.ts b/src/utils/create-value.ts index 15f44c17dc..25dcdad0f0 100644 --- a/src/utils/create-value.ts +++ b/src/utils/create-value.ts @@ -4,6 +4,8 @@ import { motionValue } from "../motion-value" import styler from "stylefire" import { invariant } from "hey-listen" +const poseSpecialProps = new Set(["transition", "transitionEnd"]) + export const createValuesFromPose = (values: MotionValueMap, { transition, transitionEnd, ...pose }: Pose) => { const valuesToAdd = { ...pose, ...transitionEnd } Object.keys(valuesToAdd).forEach(valueKey => { @@ -29,3 +31,12 @@ export const bindValuesToRef = (values: MotionValueMap, ref: RefObject) } }) } + +export const checkForNewValues = (pose: Pose, values: MotionValueMap, ref: RefObject) => { + const newValueKeys = Object.keys(pose).filter(key => !poseSpecialProps.has(key) && !values.has(key)) + + if (newValueKeys.length) { + createValuesFromPose(values, pose) + bindValuesToRef(values, ref) + } +} From c7144bceff47e3b9d4367545e353307f095ee495 Mon Sep 17 00:00:00 2001 From: Niels van Hoorn Date: Fri, 23 Nov 2018 20:21:36 +0100 Subject: [PATCH 40/44] Added some type magic to make strictly typed string named poses possible Signed-off-by: Niels van Hoorn --- dev/examples/pose-default-override.tsx | 19 ++++++++++++++----- src/motion/types.ts | 12 +++++++++--- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/dev/examples/pose-default-override.tsx b/dev/examples/pose-default-override.tsx index 1d99fb3701..4c48ba3443 100644 --- a/dev/examples/pose-default-override.tsx +++ b/dev/examples/pose-default-override.tsx @@ -1,12 +1,21 @@ import * as React from "react" import { motion } from "@framer" -import { Box } from "../styled" -const MotionBox = motion(Box)({ - default: { rotate: 0, backgroundColor: "#f00" }, - foo: { rotate: 45, backgroundColor: "#0f0" }, +const Test = React.forwardRef((props: { foo: number; bar: string }, ref: React.Ref) => { + return ( +
+ {props.foo},{props.bar} +
+ ) +}) + +const MotionBox = motion(Test)(() => { + return { + default: { rotate: 0, backgroundColor: "#f00" }, + foo: { rotate: 45, backgroundColor: "#0f0" }, + } }) export const App = () => { - return + return } diff --git a/src/motion/types.ts b/src/motion/types.ts index 3f08a52a28..e4a01b21fa 100644 --- a/src/motion/types.ts +++ b/src/motion/types.ts @@ -1,7 +1,13 @@ import { MotionValue } from "../motion-value" import { CSSProperties, ComponentType, Ref } from "react" -export type ComponentFactory = (config?: PoseConfigFactory | PoseConfig) => ComponentType +type PoseNames = Config extends PoseConfigFactory + ? keyof ReturnType + : keyof Config + +export type ComponentFactory = ( + config?: Config +) => ComponentType>> export type PoseConfigFactory = (props: MotionProps) => PoseConfig @@ -9,10 +15,10 @@ export type PoseConfig = { [key: string]: Pose | PoseResolver } -export type MotionProps = { +export type MotionProps = { [key: string]: any ref?: Ref - pose?: string | string[] | MotionValue + pose?: Poses | Poses[] | MotionValue style?: CSSProperties onPoseComplete?: (current: CurrentValues, velocity: VelocityValues) => void } From 4b9dc87f1b2e15117244d75bc396dfeddbd5f072 Mon Sep 17 00:00:00 2001 From: Niels van Hoorn Date: Sun, 25 Nov 2018 21:27:25 +0100 Subject: [PATCH 41/44] Added default pose Signed-off-by: Niels van Hoorn --- src/motion/types.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/motion/types.ts b/src/motion/types.ts index e4a01b21fa..95dde9f2d6 100644 --- a/src/motion/types.ts +++ b/src/motion/types.ts @@ -1,9 +1,11 @@ import { MotionValue } from "../motion-value" import { CSSProperties, ComponentType, Ref } from "react" -type PoseNames = Config extends PoseConfigFactory - ? keyof ReturnType - : keyof Config +export type DefaultPose = T | "default" + +type PoseNames = DefaultPose< + Config extends PoseConfigFactory ? keyof ReturnType : keyof Config +> export type ComponentFactory = ( config?: Config From 5952b1d55534be63832c89add96e19c35bc6ee5f Mon Sep 17 00:00:00 2001 From: Niels van Hoorn Date: Sun, 25 Nov 2018 21:35:45 +0100 Subject: [PATCH 42/44] Improved typing of usePose Signed-off-by: Niels van Hoorn --- dev/examples/custom-transition.tsx | 2 +- dev/examples/dynamic-pose.tsx | 2 +- dev/examples/pose-as-array-prop.tsx | 2 +- dev/examples/pose-as-hook.tsx | 2 +- dev/examples/pose-as-string-prop.tsx | 5 ++++- dev/examples/pose-children.tsx | 2 +- src/hooks/use-pose.ts | 21 +++++++++++++++------ src/motion/component.ts | 4 ++-- src/motion/types.ts | 2 ++ 9 files changed, 28 insertions(+), 14 deletions(-) diff --git a/dev/examples/custom-transition.tsx b/dev/examples/custom-transition.tsx index 2a0c512db1..fab850b24b 100644 --- a/dev/examples/custom-transition.tsx +++ b/dev/examples/custom-transition.tsx @@ -24,7 +24,7 @@ const MotionBox = motion(Box)({ }) export const App = () => { - const [pose, setPose] = usePose("ping") + const [pose, setPose] = usePose("ping") useInterval(() => { setPose(pose.get() === "ping" ? "pong" : "ping") diff --git a/dev/examples/dynamic-pose.tsx b/dev/examples/dynamic-pose.tsx index 574e1596fe..181977a63c 100644 --- a/dev/examples/dynamic-pose.tsx +++ b/dev/examples/dynamic-pose.tsx @@ -15,7 +15,7 @@ const MotionBox = motion(Box)({ }) export const App = () => { - const [pose, setPose] = usePose("ping") + const [pose, setPose] = usePose("ping") useInterval(() => { setPose(pose.get() === "ping" ? "pong" : "ping") diff --git a/dev/examples/pose-as-array-prop.tsx b/dev/examples/pose-as-array-prop.tsx index bcae9dbdb2..ebe00aea30 100644 --- a/dev/examples/pose-as-array-prop.tsx +++ b/dev/examples/pose-as-array-prop.tsx @@ -10,7 +10,7 @@ const MotionBox = motion(Box)({ }) export const App = () => { - const [pose, setPose] = React.useState("a") + const [pose, setPose] = React.useState<"a" | "b" | "c">("a") useInterval( () => { diff --git a/dev/examples/pose-as-hook.tsx b/dev/examples/pose-as-hook.tsx index 96303076c5..5cb94c08a2 100644 --- a/dev/examples/pose-as-hook.tsx +++ b/dev/examples/pose-as-hook.tsx @@ -9,7 +9,7 @@ const MotionBox = motion(Box)({ }) export const App = () => { - const [pose, setPose] = usePose("ping") + const [pose, setPose] = usePose("ping") useInterval(() => { setPose(pose.get() === "ping" ? "pong" : "ping") diff --git a/dev/examples/pose-as-string-prop.tsx b/dev/examples/pose-as-string-prop.tsx index 06d1a4d678..f1305c928f 100644 --- a/dev/examples/pose-as-string-prop.tsx +++ b/dev/examples/pose-as-string-prop.tsx @@ -2,14 +2,17 @@ import * as React from "react" import { useState } from "react" import { motion } from "@framer" import { Box } from "../styled" +import { ComponentPoseNames } from "motion/types" const MotionBox = motion(Box)({ default: { scale: 1 }, pressed: { scale: 1.2 }, }) +type Poses = ComponentPoseNames + export const App = () => { - const [pose, setPose] = useState("default") + const [pose, setPose] = useState("default") return setPose("pressed")} onMouseUp={() => setPose("default")} /> } diff --git a/dev/examples/pose-children.tsx b/dev/examples/pose-children.tsx index 77b0568fb5..027ea8fa78 100644 --- a/dev/examples/pose-children.tsx +++ b/dev/examples/pose-children.tsx @@ -34,7 +34,7 @@ const childStyles = { } export const App = () => { - const [pose, setPose] = useState("hidden") + const [pose, setPose] = useState<"visible" | "hidden">("hidden") useInterval(() => setPose(pose === "hidden" ? "visible" : "hidden"), 2000, [pose]) diff --git a/src/hooks/use-pose.ts b/src/hooks/use-pose.ts index 1455b67e06..995247c297 100644 --- a/src/hooks/use-pose.ts +++ b/src/hooks/use-pose.ts @@ -1,18 +1,27 @@ -import { useMemo } from "react" +import { useMemo, ComponentType } from "react" import { MotionValue, motionValue } from "../motion-value" +import { DefaultPose, ComponentPoseNames } from "motion/types" -type PoseSetter = { - (pose: string | string[]): void +type PoseSetter = { + (pose: Poses | Poses[]): void cycle: () => void } -export const usePose = (initPose: string | string[] = "default", poses?: string[]) => { - return useMemo((): [MotionValue, PoseSetter] => { +type PoseNames = DefaultPose : T> + +export const usePose = ( + initPose: (PoseNames) | PoseNames[] = "default", + posesOrComponent?: (PoseNames)[] +) => { + type Poses = PoseNames + type Setter = PoseSetter + const poses = posesOrComponent ? (Array.isArray(posesOrComponent) ? posesOrComponent : []) : undefined + return useMemo((): [MotionValue, Setter] => { let i = typeof initPose === "string" && poses ? poses.indexOf(initPose) : 0 const pose = motionValue(initPose) - const setPose: PoseSetter = newPose => { + const setPose: Setter = newPose => { if (poses && typeof newPose === "string") { const poseIndex = poses.indexOf(newPose) i = poseIndex > -1 ? poseIndex : i diff --git a/src/motion/component.ts b/src/motion/component.ts index 2419eef61a..c86e135945 100644 --- a/src/motion/component.ts +++ b/src/motion/component.ts @@ -1,5 +1,5 @@ import { memo, forwardRef, createElement, Ref, ComponentType, NamedExoticComponent } from "react" -import { MotionProps, ComponentFactory } from "./types" +import { MotionProps, ComponentFactory, PoseConfig, PoseConfigFactory } from "./types" import { useConfig } from "../hooks/use-config" import { useExternalRef } from "../hooks/use-external-ref" import { usePosedValues } from "../hooks/use-posed-values" @@ -7,7 +7,7 @@ import { usePoseResolver } from "../hooks/use-pose-resolver" import { useStyleAttr } from "../hooks/use-style-attr" export const createMotionComponent =

(Component: string | ComponentType

): ComponentFactory

=> { - return (poseConfig = {}): NamedExoticComponent

=> { + return (poseConfig: PoseConfigFactory | PoseConfig = {}): NamedExoticComponent

=> { { const MotionComponent = (props: P & MotionProps, externalRef?: Ref) => { const ref = useExternalRef(externalRef) diff --git a/src/motion/types.ts b/src/motion/types.ts index 95dde9f2d6..493dbc3941 100644 --- a/src/motion/types.ts +++ b/src/motion/types.ts @@ -11,6 +11,8 @@ export type ComponentFactory = ComponentType>> +export type ComponentPoseNames = C extends ComponentType> ? P : never + export type PoseConfigFactory = (props: MotionProps) => PoseConfig export type PoseConfig = { From 8e27bc495b4befdded5fab73c32517af3fd7e943 Mon Sep 17 00:00:00 2001 From: Niels van Hoorn Date: Sun, 25 Nov 2018 22:15:44 +0100 Subject: [PATCH 43/44] Made MotionValue typed with generic Signed-off-by: Niels van Hoorn --- src/motion-value/index.ts | 48 +++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/src/motion-value/index.ts b/src/motion-value/index.ts index 30ce10fc35..1d64b2e07c 100644 --- a/src/motion-value/index.ts +++ b/src/motion-value/index.ts @@ -2,23 +2,25 @@ import sync, { getFrameData, FrameData } from "framesync" import { chain, delay as delayAction, Action, ColdSubscription } from "popmotion" import { velocityPerSecond } from "@popmotion/popcorn" -export type ValuePrimitive = any +export type Transformer = (v: T) => T -export type Transformer = (v: ValuePrimitive) => ValuePrimitive +export type Subscriber = (v: T) => void -export type Subscriber = (v: ValuePrimitive) => void - -export type Config = { - transformer?: Transformer - onRender?: Subscriber - parent?: MotionValue +export type Config = { + transformer?: Transformer + onRender?: Subscriber + parent?: MotionValue } export type ActionConfig = { [key: string]: any } export type ActionFactory = (actionConfig: ActionConfig) => Action -export class MotionValue { +const isFloat = (value: any): value is string => { + return !isNaN(parseFloat(value)) +} + +export class MotionValue { // Current state private current: ValuePrimitive @@ -36,28 +38,28 @@ export class MotionValue { private parent?: MotionValue // onRender is fired on render step after update - private onRender: Subscriber | null + private onRender: Subscriber | null // Fired - private subscribers: Set + private subscribers: Set> // If set, will pass `set` values through this function first - private transformer?: Transformer + private transformer?: Transformer // A reference to the currently-controlling animation private controller?: ColdSubscription private canTrackVelocity = false - constructor(init: ValuePrimitive, { onRender, transformer, parent }: Config = {}) { + constructor(init: ValuePrimitive, { onRender, transformer, parent }: Config = {}) { this.parent = parent this.transformer = transformer if (onRender) this.setOnRender(onRender) this.set(init) - this.canTrackVelocity = !isNaN(parseFloat(this.current)) + this.canTrackVelocity = isFloat(this.current) } - addChild(config: Config) { + addChild(config: Config) { const child = new MotionValue(this.current, { parent: this, ...config, @@ -74,17 +76,17 @@ export class MotionValue { this.children.delete(child) } - setOnRender(onRender: Subscriber | null) { + setOnRender(onRender: Subscriber | null) { this.onRender = onRender if (this.onRender) sync.render(this.render) } - addSubscriber(sub: Subscriber) { + addSubscriber(sub: Subscriber) { if (!this.subscribers) this.subscribers = new Set() this.subscribers.add(sub) } - removeSubscriber(sub: Subscriber) { + removeSubscriber(sub: Subscriber) { if (this.subscribers) { this.subscribers.delete(sub) } @@ -122,7 +124,7 @@ export class MotionValue { } notifySubscribers = () => this.subscribers.forEach(this.setSubscriber) - setSubscriber = (sub: Subscriber) => sub(this.current) + setSubscriber = (sub: Subscriber) => sub(this.current) setChild = (child: MotionValue) => child.set(this.current) get() { @@ -130,8 +132,10 @@ export class MotionValue { } getVelocity() { + // This could be isFloat(this.prev) && isFloat(this.current), but that would be wastefull return this.canTrackVelocity - ? velocityPerSecond(parseFloat(this.prev) - parseFloat(this.current), this.timeDelta) + ? // These casts could be avoided if parseFloat would be typed better + velocityPerSecond(parseFloat(this.prev as any) - parseFloat(this.current as any), this.timeDelta) : 0 } @@ -139,7 +143,7 @@ export class MotionValue { if (this.onRender) this.onRender(this.current) } - control(controller: ActionFactory, { delay, ...config }: ActionConfig, transformer?: Transformer) { + control(controller: ActionFactory, { delay, ...config }: ActionConfig, transformer?: Transformer) { this.stop() let initialisedController = controller({ @@ -179,4 +183,4 @@ export class MotionValue { } } -export const motionValue = (init: ValuePrimitive, opts?: Config) => new MotionValue(init, opts) +export const motionValue = (init: V, opts?: Config) => new MotionValue(init, opts) From 37a84621da3fe0549473720bdbeb0aec700bcffa Mon Sep 17 00:00:00 2001 From: Niels van Hoorn Date: Sun, 25 Nov 2018 22:15:52 +0100 Subject: [PATCH 44/44] Removed usuless infer Signed-off-by: Niels van Hoorn --- src/motion/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/motion/index.ts b/src/motion/index.ts index a96e60f3f1..60ebd028d6 100644 --- a/src/motion/index.ts +++ b/src/motion/index.ts @@ -3,7 +3,7 @@ import { createMotionComponent } from "./component" import { htmlElements, svgElements, HTMLElements, SVGElements } from "./supported-elements" import { ComponentFactory } from "./types" -type UnwrapFactory = F extends DetailedHTMLFactory ? P : never +type UnwrapFactory = F extends DetailedHTMLFactory ? P : never export type Motion = {

(component: ComponentType

): ComponentFactory