From 62f91089b1b9af65d2da71d473bbc1cfe96cba63 Mon Sep 17 00:00:00 2001 From: Brian Espinosa Date: Sat, 23 Jul 2022 18:30:14 -0700 Subject: [PATCH 01/10] Add Presence Animation --- .nvmrc | 1 + packages/mdx/package.json | 9 +- packages/mdx/src/mdx-client/slideshow.tsx | 7 +- yarn.lock | 116 ++++++++++++++++++++++ 4 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 .nvmrc diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000..2f51fa42 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v16.14 \ No newline at end of file diff --git a/packages/mdx/package.json b/packages/mdx/package.json index c599bf76..5cad7efc 100644 --- a/packages/mdx/package.json +++ b/packages/mdx/package.json @@ -59,11 +59,13 @@ "@types/node": "^17.0.21", "@types/node-fetch": "^2.6.1", "@types/react": "17.0.45", + "@types/react-dom": "17.0.2", "autoprefixer": "^9.8.2", "click-to-react-component": "^1.0.8", "cssnano": "^4.1.10", "diff": "^4.0.2", "esbuild": "^0.13.2", + "framer-motion": "6.5.1", "mdx-bundler": "^8.0.1", "mdx-debugger": "^0.2.0", "next": "^12.1.0", @@ -81,8 +83,13 @@ "vite": "^2.8.6", "vitest": "^0.5.9" }, + "resolutions": { + "@types/react": "17.0.45", + "@types/react-dom": "17.0.2" + }, "peerDependencies": { - "react": "^16.8.3 || ^17 || ^18" + "react": "^16.8.3 || ^17 || ^18", + "framer-motion": "^6.5.1" }, "repository": "code-hike/codehike", "license": "MIT", diff --git a/packages/mdx/src/mdx-client/slideshow.tsx b/packages/mdx/src/mdx-client/slideshow.tsx index 538cb63e..bab4844c 100644 --- a/packages/mdx/src/mdx-client/slideshow.tsx +++ b/packages/mdx/src/mdx-client/slideshow.tsx @@ -3,6 +3,7 @@ import { EditorProps, EditorStep } from "../mini-editor" import { InnerCode, updateEditorStep } from "./code" import { Preview, PresetConfig } from "./preview" import { extractPreviewSteps } from "./steps" +import { AnimatePresence } from "framer-motion" export function Slideshow({ children, @@ -130,7 +131,11 @@ export function Slideshow({ {hasNotes && (
- {stepsChildren[state.stepIndex]} + + <> + {stepsChildren[state.stepIndex]} + +
)} diff --git a/yarn.lock b/yarn.lock index 1a1529eb..ae286361 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3012,6 +3012,18 @@ resolved "https://registry.yarnpkg.com/@effect-ts/system/-/system-0.55.1.tgz#fe157e7639ff6b05a51b62379961662569da98fb" integrity sha512-OEnwd9JhrV2Q5S7cke/ZgR56Hn75DSr1aIkA0PBE1edoX6GKB6nOdu8u/vPhvqjxLHfMgN8o+EVaWUHPLIC1UQ== +"@emotion/is-prop-valid@^0.8.2": + version "0.8.8" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" + integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA== + dependencies: + "@emotion/memoize" "0.7.4" + +"@emotion/memoize@0.7.4": + version "0.7.4" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" + integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== + "@endemolshinegroup/cosmiconfig-typescript-loader@^3.0.2": version "3.0.2" resolved "https://registry.yarnpkg.com/@endemolshinegroup/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-3.0.2.tgz#eea4635828dde372838b0909693ebd9aafeec22d" @@ -3992,6 +4004,59 @@ "@monaco-editor/loader" "^1.3.2" prop-types "^15.7.2" +"@motionone/animation@^10.12.0": + version "10.13.1" + resolved "https://registry.yarnpkg.com/@motionone/animation/-/animation-10.13.1.tgz#ebacb50df4b7eb4957cf398c221ae10852f28520" + integrity sha512-dxQ+1wWxL6iFHDy1uv6hhcPjIdOg36eDT56jN4LI7Z5HZRyLpq8x1t7JFQclo/IEIb+6Bk4atmyinGFdXVECuA== + dependencies: + "@motionone/easing" "^10.13.1" + "@motionone/types" "^10.13.0" + "@motionone/utils" "^10.13.1" + tslib "^2.3.1" + +"@motionone/dom@10.12.0": + version "10.12.0" + resolved "https://registry.yarnpkg.com/@motionone/dom/-/dom-10.12.0.tgz#ae30827fd53219efca4e1150a5ff2165c28351ed" + integrity sha512-UdPTtLMAktHiqV0atOczNYyDd/d8Cf5fFsd1tua03PqTwwCe/6lwhLSQ8a7TbnQ5SN0gm44N1slBfj+ORIhrqw== + dependencies: + "@motionone/animation" "^10.12.0" + "@motionone/generators" "^10.12.0" + "@motionone/types" "^10.12.0" + "@motionone/utils" "^10.12.0" + hey-listen "^1.0.8" + tslib "^2.3.1" + +"@motionone/easing@^10.13.1": + version "10.13.1" + resolved "https://registry.yarnpkg.com/@motionone/easing/-/easing-10.13.1.tgz#7927b7fe96135989e37c2cda957e4101a4b85aa8" + integrity sha512-INEsInHHDHVgx0dp5qlXi1lMXBqYicgLMMSn3zfGzaIvcaEbI1Uz8BoyNV4BiclTupG7RYIh+T6BU83ZcEe74g== + dependencies: + "@motionone/utils" "^10.13.1" + tslib "^2.3.1" + +"@motionone/generators@^10.12.0": + version "10.13.1" + resolved "https://registry.yarnpkg.com/@motionone/generators/-/generators-10.13.1.tgz#d4989d887b864e0aefbbec63eed35ce298a73773" + integrity sha512-+HK5u2YcNJCckTTqfOLgSVcrWv2z1dVwrSZEMVJuAh0EnWEWGDJRvMBoPc0cFf/osbkA2Rq9bH2+vP0Ex/D8uw== + dependencies: + "@motionone/types" "^10.13.0" + "@motionone/utils" "^10.13.1" + tslib "^2.3.1" + +"@motionone/types@^10.12.0", "@motionone/types@^10.13.0": + version "10.13.0" + resolved "https://registry.yarnpkg.com/@motionone/types/-/types-10.13.0.tgz#b22c549931ebd88ed5528158b5d611dc9dbb3756" + integrity sha512-qegk4qg8U1N9ZwAJ187BG3TkZz1k9LP/pvNtCSlqdq/PMUDKlCFG4ZnjJ481P0IOH/vIw1OzIbKIuyg0A3rk9g== + +"@motionone/utils@^10.12.0", "@motionone/utils@^10.13.1": + version "10.13.1" + resolved "https://registry.yarnpkg.com/@motionone/utils/-/utils-10.13.1.tgz#14919dfcda36b54b184fff690bc0125d554f60cd" + integrity sha512-TjDPTIppaf3ofBXQv4ZzAketJgN0sclALXfZ6mfrkjJkOy83mLls9744F+6S+VKCpBmvbZcBY4PQfrfhAfeMtA== + dependencies: + "@motionone/types" "^10.13.0" + hey-listen "^1.0.8" + tslib "^2.3.1" + "@next/env@12.1.0": version "12.1.0" resolved "https://registry.yarnpkg.com/@next/env/-/env-12.1.0.tgz#73713399399b34aa5a01771fb73272b55b22c314" @@ -5150,6 +5215,13 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== +"@types/react-dom@17.0.2": + version "17.0.2" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.2.tgz#35654cf6c49ae162d5bc90843d5437dc38008d43" + integrity sha512-Icd9KEgdnFfJs39KyRyr0jQ7EKhq8U6CcHRMGAS45fp5qgUvxL3ujUCfWFttUK2UErqZNj97t9gsVPNAqcwoCg== + dependencies: + "@types/react" "*" + "@types/react-dom@^17.0.2": version "17.0.17" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.17.tgz#2e3743277a793a96a99f1bf87614598289da68a1" @@ -9561,6 +9633,27 @@ fraction.js@^4.2.0: resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== +framer-motion@6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-6.5.1.tgz#802448a16a6eb764124bf36d8cbdfa6dd6b931a7" + integrity sha512-o1BGqqposwi7cgDrtg0dNONhkmPsUFDaLcKXigzuTFC5x58mE8iyTazxSudFzmT6MEyJKfjjU8ItoMe3W+3fiw== + dependencies: + "@motionone/dom" "10.12.0" + framesync "6.0.1" + hey-listen "^1.0.8" + popmotion "11.0.3" + style-value-types "5.0.0" + tslib "^2.1.0" + optionalDependencies: + "@emotion/is-prop-valid" "^0.8.2" + +framesync@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/framesync/-/framesync-6.0.1.tgz#5e32fc01f1c42b39c654c35b16440e07a25d6f20" + integrity sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA== + dependencies: + tslib "^2.1.0" + fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" @@ -10308,6 +10401,11 @@ hex-color-regex@^1.1.0: resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== +hey-listen@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/hey-listen/-/hey-listen-1.0.8.tgz#8e59561ff724908de1aa924ed6ecc84a56a9aa68" + integrity sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q== + history@^4.9.0: version "4.10.1" resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3" @@ -13944,6 +14042,16 @@ point-in-polygon@^1.1.0: resolved "https://registry.yarnpkg.com/point-in-polygon/-/point-in-polygon-1.1.0.tgz#b0af2616c01bdee341cbf2894df643387ca03357" integrity sha512-3ojrFwjnnw8Q9242TzgXuTD+eKiutbzyslcq1ydfu82Db2y+Ogbmyrkpv0Hgj31qwT3lbS9+QAAO/pIQM35XRw== +popmotion@11.0.3: + version "11.0.3" + resolved "https://registry.yarnpkg.com/popmotion/-/popmotion-11.0.3.tgz#565c5f6590bbcddab7a33a074bb2ba97e24b0cc9" + integrity sha512-Y55FLdj3UxkR7Vl3s7Qr4e9m0onSnP8W7d/xQLsoJM40vs6UKHFdygs6SWryasTZYqugMjm3BepCF4CWXDiHgA== + dependencies: + framesync "6.0.1" + hey-listen "^1.0.8" + style-value-types "5.0.0" + tslib "^2.1.0" + postcss-calc@^7.0.1: version "7.0.5" resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.5.tgz#f8a6e99f12e619c2ebc23cf6c486fdc15860933e" @@ -16691,6 +16799,14 @@ style-to-object@0.3.0, style-to-object@^0.3.0: dependencies: inline-style-parser "0.1.1" +style-value-types@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/style-value-types/-/style-value-types-5.0.0.tgz#76c35f0e579843d523187989da866729411fc8ad" + integrity sha512-08yq36Ikn4kx4YU6RD7jWEv27v4V+PUsOGa4n/as8Et3CuODMJQ00ENeAVXAeydX4Z2j1XHZF1K2sX4mGl18fA== + dependencies: + hey-listen "^1.0.8" + tslib "^2.1.0" + styled-jsx@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.0.0.tgz#816b4b92e07b1786c6b7111821750e0ba4d26e77" From cced852d6b90c2b8306c2a839716ebe7f9fca8c9 Mon Sep 17 00:00:00 2001 From: Brian Espinosa Date: Sat, 23 Jul 2022 18:30:14 -0700 Subject: [PATCH 02/10] Add Presence Animation --- .nvmrc | 1 + packages/mdx/package.json | 8 +- packages/mdx/src/mdx-client/slideshow.tsx | 7 +- yarn.lock | 116 ++++++++++++++++++++++ 4 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 .nvmrc diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000..2f51fa42 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v16.14 \ No newline at end of file diff --git a/packages/mdx/package.json b/packages/mdx/package.json index c599bf76..8a28b42c 100644 --- a/packages/mdx/package.json +++ b/packages/mdx/package.json @@ -64,6 +64,7 @@ "cssnano": "^4.1.10", "diff": "^4.0.2", "esbuild": "^0.13.2", + "framer-motion": "6.5.1", "mdx-bundler": "^8.0.1", "mdx-debugger": "^0.2.0", "next": "^12.1.0", @@ -81,8 +82,13 @@ "vite": "^2.8.6", "vitest": "^0.5.9" }, + "resolutions": { + "@types/react": "17.0.45", + "@types/react-dom": "17.0.2" + }, "peerDependencies": { - "react": "^16.8.3 || ^17 || ^18" + "react": "^16.8.3 || ^17 || ^18", + "framer-motion": "^6.5.1" }, "repository": "code-hike/codehike", "license": "MIT", diff --git a/packages/mdx/src/mdx-client/slideshow.tsx b/packages/mdx/src/mdx-client/slideshow.tsx index 538cb63e..bab4844c 100644 --- a/packages/mdx/src/mdx-client/slideshow.tsx +++ b/packages/mdx/src/mdx-client/slideshow.tsx @@ -3,6 +3,7 @@ import { EditorProps, EditorStep } from "../mini-editor" import { InnerCode, updateEditorStep } from "./code" import { Preview, PresetConfig } from "./preview" import { extractPreviewSteps } from "./steps" +import { AnimatePresence } from "framer-motion" export function Slideshow({ children, @@ -130,7 +131,11 @@ export function Slideshow({ {hasNotes && (
- {stepsChildren[state.stepIndex]} + + <> + {stepsChildren[state.stepIndex]} + +
)} diff --git a/yarn.lock b/yarn.lock index 1a1529eb..ae286361 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3012,6 +3012,18 @@ resolved "https://registry.yarnpkg.com/@effect-ts/system/-/system-0.55.1.tgz#fe157e7639ff6b05a51b62379961662569da98fb" integrity sha512-OEnwd9JhrV2Q5S7cke/ZgR56Hn75DSr1aIkA0PBE1edoX6GKB6nOdu8u/vPhvqjxLHfMgN8o+EVaWUHPLIC1UQ== +"@emotion/is-prop-valid@^0.8.2": + version "0.8.8" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" + integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA== + dependencies: + "@emotion/memoize" "0.7.4" + +"@emotion/memoize@0.7.4": + version "0.7.4" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" + integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== + "@endemolshinegroup/cosmiconfig-typescript-loader@^3.0.2": version "3.0.2" resolved "https://registry.yarnpkg.com/@endemolshinegroup/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-3.0.2.tgz#eea4635828dde372838b0909693ebd9aafeec22d" @@ -3992,6 +4004,59 @@ "@monaco-editor/loader" "^1.3.2" prop-types "^15.7.2" +"@motionone/animation@^10.12.0": + version "10.13.1" + resolved "https://registry.yarnpkg.com/@motionone/animation/-/animation-10.13.1.tgz#ebacb50df4b7eb4957cf398c221ae10852f28520" + integrity sha512-dxQ+1wWxL6iFHDy1uv6hhcPjIdOg36eDT56jN4LI7Z5HZRyLpq8x1t7JFQclo/IEIb+6Bk4atmyinGFdXVECuA== + dependencies: + "@motionone/easing" "^10.13.1" + "@motionone/types" "^10.13.0" + "@motionone/utils" "^10.13.1" + tslib "^2.3.1" + +"@motionone/dom@10.12.0": + version "10.12.0" + resolved "https://registry.yarnpkg.com/@motionone/dom/-/dom-10.12.0.tgz#ae30827fd53219efca4e1150a5ff2165c28351ed" + integrity sha512-UdPTtLMAktHiqV0atOczNYyDd/d8Cf5fFsd1tua03PqTwwCe/6lwhLSQ8a7TbnQ5SN0gm44N1slBfj+ORIhrqw== + dependencies: + "@motionone/animation" "^10.12.0" + "@motionone/generators" "^10.12.0" + "@motionone/types" "^10.12.0" + "@motionone/utils" "^10.12.0" + hey-listen "^1.0.8" + tslib "^2.3.1" + +"@motionone/easing@^10.13.1": + version "10.13.1" + resolved "https://registry.yarnpkg.com/@motionone/easing/-/easing-10.13.1.tgz#7927b7fe96135989e37c2cda957e4101a4b85aa8" + integrity sha512-INEsInHHDHVgx0dp5qlXi1lMXBqYicgLMMSn3zfGzaIvcaEbI1Uz8BoyNV4BiclTupG7RYIh+T6BU83ZcEe74g== + dependencies: + "@motionone/utils" "^10.13.1" + tslib "^2.3.1" + +"@motionone/generators@^10.12.0": + version "10.13.1" + resolved "https://registry.yarnpkg.com/@motionone/generators/-/generators-10.13.1.tgz#d4989d887b864e0aefbbec63eed35ce298a73773" + integrity sha512-+HK5u2YcNJCckTTqfOLgSVcrWv2z1dVwrSZEMVJuAh0EnWEWGDJRvMBoPc0cFf/osbkA2Rq9bH2+vP0Ex/D8uw== + dependencies: + "@motionone/types" "^10.13.0" + "@motionone/utils" "^10.13.1" + tslib "^2.3.1" + +"@motionone/types@^10.12.0", "@motionone/types@^10.13.0": + version "10.13.0" + resolved "https://registry.yarnpkg.com/@motionone/types/-/types-10.13.0.tgz#b22c549931ebd88ed5528158b5d611dc9dbb3756" + integrity sha512-qegk4qg8U1N9ZwAJ187BG3TkZz1k9LP/pvNtCSlqdq/PMUDKlCFG4ZnjJ481P0IOH/vIw1OzIbKIuyg0A3rk9g== + +"@motionone/utils@^10.12.0", "@motionone/utils@^10.13.1": + version "10.13.1" + resolved "https://registry.yarnpkg.com/@motionone/utils/-/utils-10.13.1.tgz#14919dfcda36b54b184fff690bc0125d554f60cd" + integrity sha512-TjDPTIppaf3ofBXQv4ZzAketJgN0sclALXfZ6mfrkjJkOy83mLls9744F+6S+VKCpBmvbZcBY4PQfrfhAfeMtA== + dependencies: + "@motionone/types" "^10.13.0" + hey-listen "^1.0.8" + tslib "^2.3.1" + "@next/env@12.1.0": version "12.1.0" resolved "https://registry.yarnpkg.com/@next/env/-/env-12.1.0.tgz#73713399399b34aa5a01771fb73272b55b22c314" @@ -5150,6 +5215,13 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== +"@types/react-dom@17.0.2": + version "17.0.2" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.2.tgz#35654cf6c49ae162d5bc90843d5437dc38008d43" + integrity sha512-Icd9KEgdnFfJs39KyRyr0jQ7EKhq8U6CcHRMGAS45fp5qgUvxL3ujUCfWFttUK2UErqZNj97t9gsVPNAqcwoCg== + dependencies: + "@types/react" "*" + "@types/react-dom@^17.0.2": version "17.0.17" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.17.tgz#2e3743277a793a96a99f1bf87614598289da68a1" @@ -9561,6 +9633,27 @@ fraction.js@^4.2.0: resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== +framer-motion@6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-6.5.1.tgz#802448a16a6eb764124bf36d8cbdfa6dd6b931a7" + integrity sha512-o1BGqqposwi7cgDrtg0dNONhkmPsUFDaLcKXigzuTFC5x58mE8iyTazxSudFzmT6MEyJKfjjU8ItoMe3W+3fiw== + dependencies: + "@motionone/dom" "10.12.0" + framesync "6.0.1" + hey-listen "^1.0.8" + popmotion "11.0.3" + style-value-types "5.0.0" + tslib "^2.1.0" + optionalDependencies: + "@emotion/is-prop-valid" "^0.8.2" + +framesync@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/framesync/-/framesync-6.0.1.tgz#5e32fc01f1c42b39c654c35b16440e07a25d6f20" + integrity sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA== + dependencies: + tslib "^2.1.0" + fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" @@ -10308,6 +10401,11 @@ hex-color-regex@^1.1.0: resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== +hey-listen@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/hey-listen/-/hey-listen-1.0.8.tgz#8e59561ff724908de1aa924ed6ecc84a56a9aa68" + integrity sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q== + history@^4.9.0: version "4.10.1" resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3" @@ -13944,6 +14042,16 @@ point-in-polygon@^1.1.0: resolved "https://registry.yarnpkg.com/point-in-polygon/-/point-in-polygon-1.1.0.tgz#b0af2616c01bdee341cbf2894df643387ca03357" integrity sha512-3ojrFwjnnw8Q9242TzgXuTD+eKiutbzyslcq1ydfu82Db2y+Ogbmyrkpv0Hgj31qwT3lbS9+QAAO/pIQM35XRw== +popmotion@11.0.3: + version "11.0.3" + resolved "https://registry.yarnpkg.com/popmotion/-/popmotion-11.0.3.tgz#565c5f6590bbcddab7a33a074bb2ba97e24b0cc9" + integrity sha512-Y55FLdj3UxkR7Vl3s7Qr4e9m0onSnP8W7d/xQLsoJM40vs6UKHFdygs6SWryasTZYqugMjm3BepCF4CWXDiHgA== + dependencies: + framesync "6.0.1" + hey-listen "^1.0.8" + style-value-types "5.0.0" + tslib "^2.1.0" + postcss-calc@^7.0.1: version "7.0.5" resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.5.tgz#f8a6e99f12e619c2ebc23cf6c486fdc15860933e" @@ -16691,6 +16799,14 @@ style-to-object@0.3.0, style-to-object@^0.3.0: dependencies: inline-style-parser "0.1.1" +style-value-types@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/style-value-types/-/style-value-types-5.0.0.tgz#76c35f0e579843d523187989da866729411fc8ad" + integrity sha512-08yq36Ikn4kx4YU6RD7jWEv27v4V+PUsOGa4n/as8Et3CuODMJQ00ENeAVXAeydX4Z2j1XHZF1K2sX4mGl18fA== + dependencies: + hey-listen "^1.0.8" + tslib "^2.1.0" + styled-jsx@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.0.0.tgz#816b4b92e07b1786c6b7111821750e0ba4d26e77" From 694f1f162091321a8ea0473404717bcd6254b5b5 Mon Sep 17 00:00:00 2001 From: Brian Espinosa Date: Sat, 23 Jul 2022 18:35:18 -0700 Subject: [PATCH 03/10] fix deps --- packages/mdx/package.json | 4 ---- yarn.lock | 7 ------- 2 files changed, 11 deletions(-) diff --git a/packages/mdx/package.json b/packages/mdx/package.json index 8a28b42c..6bc8e94c 100644 --- a/packages/mdx/package.json +++ b/packages/mdx/package.json @@ -82,10 +82,6 @@ "vite": "^2.8.6", "vitest": "^0.5.9" }, - "resolutions": { - "@types/react": "17.0.45", - "@types/react-dom": "17.0.2" - }, "peerDependencies": { "react": "^16.8.3 || ^17 || ^18", "framer-motion": "^6.5.1" diff --git a/yarn.lock b/yarn.lock index ae286361..8205dc5b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5215,13 +5215,6 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== -"@types/react-dom@17.0.2": - version "17.0.2" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.2.tgz#35654cf6c49ae162d5bc90843d5437dc38008d43" - integrity sha512-Icd9KEgdnFfJs39KyRyr0jQ7EKhq8U6CcHRMGAS45fp5qgUvxL3ujUCfWFttUK2UErqZNj97t9gsVPNAqcwoCg== - dependencies: - "@types/react" "*" - "@types/react-dom@^17.0.2": version "17.0.17" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.17.tgz#2e3743277a793a96a99f1bf87614598289da68a1" From 7c65e07cdc0ac4ef44f407adcc2dafeb1a669582 Mon Sep 17 00:00:00 2001 From: Brian Espinosa Date: Sat, 23 Jul 2022 18:48:41 -0700 Subject: [PATCH 04/10] Make sure this gets built after install --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index e270ae44..166665e0 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,8 @@ "build:playground": "lerna run --stream --scope playground build", "test": "lerna run --stream test", "dev": "lerna run --stream --scope @*/mdx dev", - "release": "auto shipit" + "release": "auto shipit", + "postinstall": "build:lib" }, "devDependencies": { "auto": "^10.18.7", From baaa94c79f65a8f8604b36aacf1ab42ea5aa7e43 Mon Sep 17 00:00:00 2001 From: Brian Espinosa Date: Sat, 23 Jul 2022 18:58:40 -0700 Subject: [PATCH 05/10] fix build script --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 166665e0..fe10f136 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "test": "lerna run --stream test", "dev": "lerna run --stream --scope @*/mdx dev", "release": "auto shipit", - "postinstall": "build:lib" + "postinstall": "yarn build:lib" }, "devDependencies": { "auto": "^10.18.7", From 0463c9c95808eb1a4abee0c883494a90f92b281b Mon Sep 17 00:00:00 2001 From: Brian Espinosa Date: Fri, 29 Jul 2022 14:28:47 -0700 Subject: [PATCH 06/10] feat(#217): CH.Slideshow autoPlay and autoPlayLoop --- packages/mdx/dev/content/slideshow-auto.mdx | 529 ++++++++++++++++++++ packages/mdx/src/mdx-client/slideshow.tsx | 113 +++-- 2 files changed, 614 insertions(+), 28 deletions(-) create mode 100644 packages/mdx/dev/content/slideshow-auto.mdx diff --git a/packages/mdx/dev/content/slideshow-auto.mdx b/packages/mdx/dev/content/slideshow-auto.mdx new file mode 100644 index 00000000..2168af1a --- /dev/null +++ b/packages/mdx/dev/content/slideshow-auto.mdx @@ -0,0 +1,529 @@ +# Slideshow Auto + +This is how to use the `` component. Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, quia! Quidem, quisquam. + + + + + +```jsx src/index.js +import React from "react" +import ReactDOM from "react-dom" + +const app = React.createElement( + "h1", + { style: { color: "teal" } }, + "Hello React" +) + +ReactDOM.render(app, document.getElementById("root")) +``` + + + +React provides a createElement function to declare what we want to render to the DOM + +--- + + + +```jsx src/index.js focus=4 +import React from "react" +import ReactDOM from "react-dom" + +const app =

Hello React

+ +ReactDOM.render(app, document.getElementById("root")) +``` + +
+ +But instead of using createElement directly you can use JSX. + +--- + + + +```jsx src/index.js focus=4:10 +import React from "react" +import ReactDOM from "react-dom" + +function MyComponent() { + return ( +
+ +
+ ) +} + +const app =

Hello React

+ +ReactDOM.render(app, document.getElementById("root")) +``` + +
+ +To create a component you only need to write a function with a name that starts with a capital letter. + +--- + + + +```jsx src/index.js focus=4[10:20],12:17 +import React from "react" +import ReactDOM from "react-dom" + +function MyComponent() { + return ( +
+ +
+ ) +} + +const app = ( +
+ + +
+) + +ReactDOM.render(app, document.getElementById("root")) +``` + +
+ +Now you can use that function in JSX. + +--- + + + +```jsx src/index.js focus=14[18:29],15[18:31] +import React from "react" +import ReactDOM from "react-dom" + +function MyComponent() { + return ( +
+ +
+ ) +} + +const app = ( +
+ + +
+) + +ReactDOM.render(app, document.getElementById("root")) +``` + +
+ +You can assign attributes + +--- + + + +```jsx src/index.js focus=4[22:29],14[18:29],15[18:31] +import React from "react" +import ReactDOM from "react-dom" + +function MyComponent({ name }) { + return ( +
+ +
+ ) +} + +const app = ( +
+ + +
+) + +ReactDOM.render(app, document.getElementById("root")) +``` + +
+ +And React will pass them to the component as parameters + +--- + + + +```jsx src/index.js focus=4[22:29],7 +import React from "react" +import ReactDOM from "react-dom" + +function MyComponent({ name }) { + return ( +
+ +
+ ) +} + +const app = ( +
+ + +
+) + +ReactDOM.render(app, document.getElementById("root")) +``` + +
+ +Inside JSX, you use curly braces to wrap dynamic data + +--- + + + +```jsx src/index.js focus=5,9 +import React from "react" +import ReactDOM from "react-dom" + +function MyComponent({ name }) { + const goalCount = 2 + return ( +
+ + {"⚽".repeat(goalCount)} +
+ ) +} + +const app = ( +
+ + +
+) + +ReactDOM.render(app, document.getElementById("root")) +``` + +
+ +In fact you can wrap any javascript expression. + +--- + + + +```jsx src/index.js focus=7:9,13[15:35] +import React from "react" +import ReactDOM from "react-dom" + +function MyComponent({ name }) { + const goalCount = 2 + + const handleClick = event => { + // do something + } + + return ( +
+ + {"⚽".repeat(goalCount)} +
+ ) +} + +const app = ( +
+ + +
+) + +ReactDOM.render(app, document.getElementById("root")) +``` + +
+ +To add event listeners you pass a function to the corresponding attribute + +--- + + + +```jsx src/index.js focus=5 +import React from "react" +import ReactDOM from "react-dom" + +function MyComponent({ name }) { + const [goalCount, setCount] = React.useState(2) + + const handleClick = event => { + // do something + } + return ( +
+ + {"⚽".repeat(goalCount)} +
+ ) +} + +const app = ( +
+ + +
+) + +ReactDOM.render(app, document.getElementById("root")) +``` + +
+ +To add state to a component there's the useState function from React. + +--- + + + +```jsx src/index.js focus=5,7:9 +import React from "react" +import ReactDOM from "react-dom" + +function MyComponent({ name }) { + const [goalCount, setCount] = React.useState(2) + + const handleClick = event => { + setCount(goalCount + 1) + } + + return ( +
+ + {"⚽".repeat(goalCount)} +
+ ) +} + +const app = ( +
+ + +
+) + +ReactDOM.render(app, document.getElementById("root")) +``` + +
+ +It gives you a function to update the state. + +--- + + + +```jsx src/index.js focus=5,7:9,13,14 + +``` + + + +When you call it, React will know it needs to re-render the component. + +--- + + + +```jsx src/index.js focus=19 +import React from "react" +import ReactDOM from "react-dom" + +function MyComponent({ name }) { + const [goalCount, setCount] = React.useState(2) + + const handleClick = event => { + setCount(goalCount + 1) + } + + return ( +
+ + {"⚽".repeat(goalCount)} +
+ ) +} + +const players = ["Messi", "Ronaldo", "Laspada"] + +const app = ( +
+ + +
+) + +ReactDOM.render(app, document.getElementById("root")) +``` + +
+ +To render a list + +--- + + + +```jsx src/index.js focus=19,23[6:34],24,25[1:6] +import React from "react" +import ReactDOM from "react-dom" + +function MyComponent({ name }) { + const [goalCount, setCount] = React.useState(2) + + const handleClick = event => { + setCount(goalCount + 1) + } + + return ( +
+ + {"⚽".repeat(goalCount)} +
+ ) +} + +const players = ["Messi", "Ronaldo", "Laspada"] + +const app = ( +
+ {players.map(playerName => ( + + ))} +
+) + +ReactDOM.render(app, document.getElementById("root")) +``` + +
+ +you can map each list item to an element using javascript. + +--- + + + +```jsx src/index.js focus=24[38:54] + +``` + + + +React only needs a unique key for each element, to find out when something changes. + +--- + + + +```jsx src/index.js focus=21:27,30,34 +import React from "react" +import ReactDOM from "react-dom" + +function MyComponent({ name }) { + const [goalCount, setCount] = React.useState(2) + + const handleClick = event => { + setCount(goalCount + 1) + } + + return ( +
+ + {"⚽".repeat(goalCount)} +
+ ) +} + +const players = ["Messi", "Ronaldo", "Laspada"] + +function MyBox() { + return ( +
+ // TODO something +
+ ) +} + +const app = ( + + {players.map(playerName => ( + + ))} + +) + +ReactDOM.render(app, document.getElementById("root")) +``` + +
+ +If you want to compose components together + +--- + + + +```jsx src/index.js focus=21[16:27],24,30:34 +import React from "react" +import ReactDOM from "react-dom" + +function MyComponent({ name }) { + const [goalCount, setCount] = React.useState(2) + + const handleClick = event => { + setCount(goalCount + 1) + } + + return ( +
+ + {"⚽".repeat(goalCount)} +
+ ) +} + +const players = ["Messi", "Ronaldo", "Laspada"] + +function MyBox({ children }) { + return ( +
+ {children} +
+ ) +} + +const app = ( + + {players.map(playerName => ( + + ))} + +) + +ReactDOM.render(app, document.getElementById("root")) +``` + +
+ +React passes the nested elements inside a special property called children. + +
diff --git a/packages/mdx/src/mdx-client/slideshow.tsx b/packages/mdx/src/mdx-client/slideshow.tsx index bab4844c..5076b55a 100644 --- a/packages/mdx/src/mdx-client/slideshow.tsx +++ b/packages/mdx/src/mdx-client/slideshow.tsx @@ -14,6 +14,8 @@ export function Slideshow({ className, style, hasPreviewSteps, + autoPlay, + autoPlayLoop = false, ...rest }: { children: React.ReactNode @@ -24,6 +26,8 @@ export function Slideshow({ className?: string style?: React.CSSProperties hasPreviewSteps?: boolean + autoPlay?: number + autoPlayLoop?: boolean }) { const { stepsChildren, previewChildren } = extractPreviewSteps(children, hasPreviewSteps) @@ -33,11 +37,21 @@ export function Slideshow({ (child: any) => child.props?.children ) + const maxSteps = editorSteps.length - 1; + + // As this gets more complex, probably would make more sense to abstract this into a custom hook with methods to modify state versus exposing directly const [state, setState] = React.useState({ stepIndex: 0, step: editorSteps[0], }) - const tab = state.step + + const { + stepIndex: currentSlideIndex, + step: tab, + } = state; + + const atSlideshowStart = currentSlideIndex === 0; + const atSlideshowEnd = currentSlideIndex === maxSteps; function onTabClick(filename: string) { const newStep = updateEditorStep( @@ -48,6 +62,69 @@ export function Slideshow({ setState({ ...state, step: newStep }) } + function slideNext() { + setState(s => { + const stepIndex = Math.min( + maxSteps, + s.stepIndex + 1 + ) + return { + stepIndex, + step: editorSteps[stepIndex], + } + }) + } + + function slidePrevious() { + setState(s => { + const stepIndex = Math.max( + 0, + s.stepIndex - 1 + ) + return { + stepIndex, + step: editorSteps[stepIndex], + } + }) + } + + React.useEffect(() => { + // If autoplay is enabled, and we are not at the end of the slides, move to the next slide + if (autoPlay && !atSlideshowEnd) { + const autoSlide = setTimeout( + () => { + slideNext(); + console.log('next'); + }, + autoPlay + ); + + // Cleanup our timeout if our component unmounts + return () => { + clearTimeout(autoSlide); + }; + // If we are at the end of the slideshow, and we have configured to loop, start over + } else if (autoPlay && atSlideshowEnd && autoPlayLoop) { + // We still have to use the same timeout function with autoPlay delay or else the last slide will never show because it will instantly change + const autoRestart = setTimeout( + () => { + setState({ + stepIndex: 0, + step: editorSteps[0], + }) + }, + autoPlay + ); + + // Cleanup our timeout if our component unmounts + return () => { + clearTimeout(autoRestart); + }; + } else { + return null; + } + }, [currentSlideIndex, autoPlay]); + return (
- @@ -111,19 +178,9 @@ export function Slideshow({ }) } /> - From 4b6ed5c0d9ca97330ba3c6ce5ad94ef5b62a2c75 Mon Sep 17 00:00:00 2001 From: Brian Espinosa Date: Fri, 29 Jul 2022 14:35:52 -0700 Subject: [PATCH 07/10] oops --- packages/mdx/src/mdx-client/slideshow.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/mdx/src/mdx-client/slideshow.tsx b/packages/mdx/src/mdx-client/slideshow.tsx index 5076b55a..4b2ad8e4 100644 --- a/packages/mdx/src/mdx-client/slideshow.tsx +++ b/packages/mdx/src/mdx-client/slideshow.tsx @@ -92,10 +92,7 @@ export function Slideshow({ // If autoplay is enabled, and we are not at the end of the slides, move to the next slide if (autoPlay && !atSlideshowEnd) { const autoSlide = setTimeout( - () => { - slideNext(); - console.log('next'); - }, + () => slideNext(), autoPlay ); From 2ae25a06ae20c0f3191691afc76d2200618683cb Mon Sep 17 00:00:00 2001 From: Brian Espinosa Date: Sat, 30 Jul 2022 13:51:21 -0700 Subject: [PATCH 08/10] Remove framer-motion oops --- packages/mdx/package.json | 1 - yarn.lock | 109 -------------------------------------- 2 files changed, 110 deletions(-) diff --git a/packages/mdx/package.json b/packages/mdx/package.json index 76cb1d1c..6a77a6e7 100644 --- a/packages/mdx/package.json +++ b/packages/mdx/package.json @@ -68,7 +68,6 @@ "cssnano": "^4.1.10", "diff": "^4.0.2", "esbuild": "^0.13.2", - "framer-motion": "6.5.1", "mdx-bundler": "^8.0.1", "mdx-debugger": "^0.2.0", "next": "^12.1.0", diff --git a/yarn.lock b/yarn.lock index 8205dc5b..1a1529eb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3012,18 +3012,6 @@ resolved "https://registry.yarnpkg.com/@effect-ts/system/-/system-0.55.1.tgz#fe157e7639ff6b05a51b62379961662569da98fb" integrity sha512-OEnwd9JhrV2Q5S7cke/ZgR56Hn75DSr1aIkA0PBE1edoX6GKB6nOdu8u/vPhvqjxLHfMgN8o+EVaWUHPLIC1UQ== -"@emotion/is-prop-valid@^0.8.2": - version "0.8.8" - resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" - integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA== - dependencies: - "@emotion/memoize" "0.7.4" - -"@emotion/memoize@0.7.4": - version "0.7.4" - resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" - integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== - "@endemolshinegroup/cosmiconfig-typescript-loader@^3.0.2": version "3.0.2" resolved "https://registry.yarnpkg.com/@endemolshinegroup/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-3.0.2.tgz#eea4635828dde372838b0909693ebd9aafeec22d" @@ -4004,59 +3992,6 @@ "@monaco-editor/loader" "^1.3.2" prop-types "^15.7.2" -"@motionone/animation@^10.12.0": - version "10.13.1" - resolved "https://registry.yarnpkg.com/@motionone/animation/-/animation-10.13.1.tgz#ebacb50df4b7eb4957cf398c221ae10852f28520" - integrity sha512-dxQ+1wWxL6iFHDy1uv6hhcPjIdOg36eDT56jN4LI7Z5HZRyLpq8x1t7JFQclo/IEIb+6Bk4atmyinGFdXVECuA== - dependencies: - "@motionone/easing" "^10.13.1" - "@motionone/types" "^10.13.0" - "@motionone/utils" "^10.13.1" - tslib "^2.3.1" - -"@motionone/dom@10.12.0": - version "10.12.0" - resolved "https://registry.yarnpkg.com/@motionone/dom/-/dom-10.12.0.tgz#ae30827fd53219efca4e1150a5ff2165c28351ed" - integrity sha512-UdPTtLMAktHiqV0atOczNYyDd/d8Cf5fFsd1tua03PqTwwCe/6lwhLSQ8a7TbnQ5SN0gm44N1slBfj+ORIhrqw== - dependencies: - "@motionone/animation" "^10.12.0" - "@motionone/generators" "^10.12.0" - "@motionone/types" "^10.12.0" - "@motionone/utils" "^10.12.0" - hey-listen "^1.0.8" - tslib "^2.3.1" - -"@motionone/easing@^10.13.1": - version "10.13.1" - resolved "https://registry.yarnpkg.com/@motionone/easing/-/easing-10.13.1.tgz#7927b7fe96135989e37c2cda957e4101a4b85aa8" - integrity sha512-INEsInHHDHVgx0dp5qlXi1lMXBqYicgLMMSn3zfGzaIvcaEbI1Uz8BoyNV4BiclTupG7RYIh+T6BU83ZcEe74g== - dependencies: - "@motionone/utils" "^10.13.1" - tslib "^2.3.1" - -"@motionone/generators@^10.12.0": - version "10.13.1" - resolved "https://registry.yarnpkg.com/@motionone/generators/-/generators-10.13.1.tgz#d4989d887b864e0aefbbec63eed35ce298a73773" - integrity sha512-+HK5u2YcNJCckTTqfOLgSVcrWv2z1dVwrSZEMVJuAh0EnWEWGDJRvMBoPc0cFf/osbkA2Rq9bH2+vP0Ex/D8uw== - dependencies: - "@motionone/types" "^10.13.0" - "@motionone/utils" "^10.13.1" - tslib "^2.3.1" - -"@motionone/types@^10.12.0", "@motionone/types@^10.13.0": - version "10.13.0" - resolved "https://registry.yarnpkg.com/@motionone/types/-/types-10.13.0.tgz#b22c549931ebd88ed5528158b5d611dc9dbb3756" - integrity sha512-qegk4qg8U1N9ZwAJ187BG3TkZz1k9LP/pvNtCSlqdq/PMUDKlCFG4ZnjJ481P0IOH/vIw1OzIbKIuyg0A3rk9g== - -"@motionone/utils@^10.12.0", "@motionone/utils@^10.13.1": - version "10.13.1" - resolved "https://registry.yarnpkg.com/@motionone/utils/-/utils-10.13.1.tgz#14919dfcda36b54b184fff690bc0125d554f60cd" - integrity sha512-TjDPTIppaf3ofBXQv4ZzAketJgN0sclALXfZ6mfrkjJkOy83mLls9744F+6S+VKCpBmvbZcBY4PQfrfhAfeMtA== - dependencies: - "@motionone/types" "^10.13.0" - hey-listen "^1.0.8" - tslib "^2.3.1" - "@next/env@12.1.0": version "12.1.0" resolved "https://registry.yarnpkg.com/@next/env/-/env-12.1.0.tgz#73713399399b34aa5a01771fb73272b55b22c314" @@ -9626,27 +9561,6 @@ fraction.js@^4.2.0: resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== -framer-motion@6.5.1: - version "6.5.1" - resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-6.5.1.tgz#802448a16a6eb764124bf36d8cbdfa6dd6b931a7" - integrity sha512-o1BGqqposwi7cgDrtg0dNONhkmPsUFDaLcKXigzuTFC5x58mE8iyTazxSudFzmT6MEyJKfjjU8ItoMe3W+3fiw== - dependencies: - "@motionone/dom" "10.12.0" - framesync "6.0.1" - hey-listen "^1.0.8" - popmotion "11.0.3" - style-value-types "5.0.0" - tslib "^2.1.0" - optionalDependencies: - "@emotion/is-prop-valid" "^0.8.2" - -framesync@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/framesync/-/framesync-6.0.1.tgz#5e32fc01f1c42b39c654c35b16440e07a25d6f20" - integrity sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA== - dependencies: - tslib "^2.1.0" - fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" @@ -10394,11 +10308,6 @@ hex-color-regex@^1.1.0: resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== -hey-listen@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/hey-listen/-/hey-listen-1.0.8.tgz#8e59561ff724908de1aa924ed6ecc84a56a9aa68" - integrity sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q== - history@^4.9.0: version "4.10.1" resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3" @@ -14035,16 +13944,6 @@ point-in-polygon@^1.1.0: resolved "https://registry.yarnpkg.com/point-in-polygon/-/point-in-polygon-1.1.0.tgz#b0af2616c01bdee341cbf2894df643387ca03357" integrity sha512-3ojrFwjnnw8Q9242TzgXuTD+eKiutbzyslcq1ydfu82Db2y+Ogbmyrkpv0Hgj31qwT3lbS9+QAAO/pIQM35XRw== -popmotion@11.0.3: - version "11.0.3" - resolved "https://registry.yarnpkg.com/popmotion/-/popmotion-11.0.3.tgz#565c5f6590bbcddab7a33a074bb2ba97e24b0cc9" - integrity sha512-Y55FLdj3UxkR7Vl3s7Qr4e9m0onSnP8W7d/xQLsoJM40vs6UKHFdygs6SWryasTZYqugMjm3BepCF4CWXDiHgA== - dependencies: - framesync "6.0.1" - hey-listen "^1.0.8" - style-value-types "5.0.0" - tslib "^2.1.0" - postcss-calc@^7.0.1: version "7.0.5" resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.5.tgz#f8a6e99f12e619c2ebc23cf6c486fdc15860933e" @@ -16792,14 +16691,6 @@ style-to-object@0.3.0, style-to-object@^0.3.0: dependencies: inline-style-parser "0.1.1" -style-value-types@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/style-value-types/-/style-value-types-5.0.0.tgz#76c35f0e579843d523187989da866729411fc8ad" - integrity sha512-08yq36Ikn4kx4YU6RD7jWEv27v4V+PUsOGa4n/as8Et3CuODMJQ00ENeAVXAeydX4Z2j1XHZF1K2sX4mGl18fA== - dependencies: - hey-listen "^1.0.8" - tslib "^2.1.0" - styled-jsx@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.0.0.tgz#816b4b92e07b1786c6b7111821750e0ba4d26e77" From 9d9f3bdb3ebc58b0cc05a8aec5b1b3bc5d4d765c Mon Sep 17 00:00:00 2001 From: Brian Espinosa Date: Sat, 30 Jul 2022 13:51:45 -0700 Subject: [PATCH 09/10] Rename autoPlayLoop -> loop --- packages/mdx/dev/content/slideshow-auto.mdx | 2 +- packages/mdx/src/mdx-client/slideshow.tsx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/mdx/dev/content/slideshow-auto.mdx b/packages/mdx/dev/content/slideshow-auto.mdx index 2168af1a..08068c8f 100644 --- a/packages/mdx/dev/content/slideshow-auto.mdx +++ b/packages/mdx/dev/content/slideshow-auto.mdx @@ -2,7 +2,7 @@ This is how to use the `` component. Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, quia! Quidem, quisquam. - + diff --git a/packages/mdx/src/mdx-client/slideshow.tsx b/packages/mdx/src/mdx-client/slideshow.tsx index 61943e37..8bfc4bd4 100644 --- a/packages/mdx/src/mdx-client/slideshow.tsx +++ b/packages/mdx/src/mdx-client/slideshow.tsx @@ -19,7 +19,7 @@ export function Slideshow({ presetConfig, style, autoPlay, - autoPlayLoop = false, + loop = false, ...rest }: { children: React.ReactNode @@ -34,7 +34,7 @@ export function Slideshow({ presetConfig?: PresetConfig style?: React.CSSProperties autoPlay?: number - autoPlayLoop?: boolean + loop?: boolean }) { const controlsRef = React.useRef(null) @@ -128,7 +128,7 @@ export function Slideshow({ clearTimeout(autoSlide); }; // If we are at the end of the slideshow, and we have configured to loop, start over - } else if (autoPlay && atSlideshowEnd && autoPlayLoop) { + } else if (autoPlay && atSlideshowEnd && loop) { // We still have to use the same timeout function with autoPlay delay or else the last slide will never show because it will instantly change const autoRestart = setTimeout( () => { From a7173757cb2690adb0261141be28ef24f8e3694a Mon Sep 17 00:00:00 2001 From: Rodrigo Pombo Date: Mon, 1 Aug 2022 10:48:06 +0000 Subject: [PATCH 10/10] Slideshow refactor --- ...deshow-auto.mdx => slideshow-autoplay.mdx} | 2 +- packages/mdx/package.json | 3 +- packages/mdx/src/mdx-client/slideshow.tsx | 144 ++++++------------ packages/mdx/src/utils/hooks.ts | 25 +++ packages/mdx/src/utils/index.tsx | 4 + 5 files changed, 75 insertions(+), 103 deletions(-) rename packages/mdx/dev/content/{slideshow-auto.mdx => slideshow-autoplay.mdx} (99%) diff --git a/packages/mdx/dev/content/slideshow-auto.mdx b/packages/mdx/dev/content/slideshow-autoplay.mdx similarity index 99% rename from packages/mdx/dev/content/slideshow-auto.mdx rename to packages/mdx/dev/content/slideshow-autoplay.mdx index 08068c8f..88be5b7c 100644 --- a/packages/mdx/dev/content/slideshow-auto.mdx +++ b/packages/mdx/dev/content/slideshow-autoplay.mdx @@ -2,7 +2,7 @@ This is how to use the `` component. Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, quia! Quidem, quisquam. - + diff --git a/packages/mdx/package.json b/packages/mdx/package.json index 6a77a6e7..ac3c2ef3 100644 --- a/packages/mdx/package.json +++ b/packages/mdx/package.json @@ -86,8 +86,7 @@ "vitest": "^0.5.9" }, "peerDependencies": { - "react": "^16.8.3 || ^17 || ^18", - "framer-motion": "^6.5.1" + "react": "^16.8.3 || ^17 || ^18" }, "repository": "code-hike/codehike", "license": "MIT", diff --git a/packages/mdx/src/mdx-client/slideshow.tsx b/packages/mdx/src/mdx-client/slideshow.tsx index 8bfc4bd4..398e6796 100644 --- a/packages/mdx/src/mdx-client/slideshow.tsx +++ b/packages/mdx/src/mdx-client/slideshow.tsx @@ -1,9 +1,14 @@ import React from "react" +import { clamp, useInterval } from "utils" import { EditorProps, EditorStep } from "../mini-editor" import { InnerCode, updateEditorStep } from "./code" import { Preview, PresetConfig } from "./preview" import { extractPreviewSteps } from "./steps" +type ChangeEvent = { + index: number +} + export function Slideshow({ children, className, @@ -30,19 +35,12 @@ export function Slideshow({ hasPreviewSteps?: boolean autoFocus?: boolean start?: number - onChange?: Function + onChange?: (e: ChangeEvent) => void presetConfig?: PresetConfig style?: React.CSSProperties autoPlay?: number loop?: boolean }) { - const controlsRef = React.useRef(null) - - React.useEffect(() => { - // Only set focus on controls input if we have configured to do so - autoFocus && controlsRef.current.focus() - }, []) - const { stepsChildren, previewChildren } = extractPreviewSteps(children, hasPreviewSteps) const withPreview = presetConfig || hasPreviewSteps @@ -51,63 +49,39 @@ export function Slideshow({ (child: any) => child.props?.children ) - const maxSteps = editorSteps.length - 1; + const maxSteps = editorSteps.length - 1 - // Make sure the initial slide is not configured out of bounds - const initialSlide = start > maxSteps ? maxSteps : start - - // As this gets more complex, probably would make more sense to abstract this into a custom hook with methods to modify state versus exposing directly - const [state, setState] = React.useState({ - stepIndex: initialSlide, - step: editorSteps[initialSlide], + const [state, setState] = React.useState(() => { + const startIndex = clamp(start, 0, maxSteps) + return { + stepIndex: startIndex, + step: editorSteps[startIndex], + } }) - // Destructure these values and give them more semantic names for use below - const { - stepIndex: currentSlideIndex, - step: tab, - } = state; + const { stepIndex: currentIndex, step: tab } = state - const atSlideshowStart = currentSlideIndex === 0; - const atSlideshowEnd = currentSlideIndex === maxSteps; + const atSlideshowEnd = currentIndex === maxSteps - // Run any time our Slideshow state changes React.useEffect(() => { - // Return our state object to the Slideshow onChange function - onSlideshowChange({ - index: currentSlideIndex - }); - // We are only calling this effect if the current slide changes. - }, [currentSlideIndex]); + onSlideshowChange({ index: currentIndex }) + }, [currentIndex]) function onTabClick(filename: string) { - const newStep = updateEditorStep( - state.step, - filename, - null - ) + const newStep = updateEditorStep(tab, filename, null) setState({ ...state, step: newStep }) } - function slideNext() { - setState(s => { - const stepIndex = Math.min( - maxSteps, - s.stepIndex + 1 - ) - return { - stepIndex, - step: editorSteps[stepIndex], - } - }) + function setIndex(newIndex: number) { + const stepIndex = clamp(newIndex, 0, maxSteps) + setState({ stepIndex, step: editorSteps[stepIndex] }) } - function slidePrevious() { + function nextSlide() { setState(s => { - const stepIndex = Math.max( - 0, - s.stepIndex - 1 - ) + const stepIndex = loop + ? (s.stepIndex + 1) % (maxSteps + 1) + : clamp(s.stepIndex + 1, 0, maxSteps) return { stepIndex, step: editorSteps[stepIndex], @@ -115,39 +89,7 @@ export function Slideshow({ }) } - React.useEffect(() => { - // If autoplay is enabled, and we are not at the end of the slides, move to the next slide - if (autoPlay && !atSlideshowEnd) { - const autoSlide = setTimeout( - () => slideNext(), - autoPlay - ); - - // Cleanup our timeout if our component unmounts - return () => { - clearTimeout(autoSlide); - }; - // If we are at the end of the slideshow, and we have configured to loop, start over - } else if (autoPlay && atSlideshowEnd && loop) { - // We still have to use the same timeout function with autoPlay delay or else the last slide will never show because it will instantly change - const autoRestart = setTimeout( - () => { - setState({ - stepIndex: 0, - step: editorSteps[0], - }) - }, - autoPlay - ); - - // Cleanup our timeout if our component unmounts - return () => { - clearTimeout(autoRestart); - }; - } else { - return null; - } - }, [currentSlideIndex, autoPlay]); + useInterval(nextSlide, autoPlay) return (
) : null}
- - setState({ - stepIndex: +e.target.value, - step: editorSteps[+e.target.value], - }) - } + value={currentIndex} + onChange={e => setIndex(+e.target.value)} + ref={useAutoFocusRef(autoFocus)} autoFocus={autoFocus} /> -
- {hasNotes && (
- {stepsChildren[currentSlideIndex]} + {stepsChildren[currentIndex]}
)}
) } + +function useAutoFocusRef(autoFocus: boolean) { + const ref = React.useRef(null) + React.useEffect(() => { + autoFocus && ref.current.focus() + }, []) + return ref +} diff --git a/packages/mdx/src/utils/hooks.ts b/packages/mdx/src/utils/hooks.ts index 32e92996..21921a19 100644 --- a/packages/mdx/src/utils/hooks.ts +++ b/packages/mdx/src/utils/hooks.ts @@ -10,3 +10,28 @@ export const useLayoutEffect = // effect: any, // deps?: any // ) => {} + +// from https://overreacted.io/making-setinterval-declarative-with-react-hooks/ +export function useInterval( + callback: () => void, + delay: number | null +) { + const savedCallback = React.useRef(callback) + + React.useEffect(() => { + savedCallback.current = callback + }, [callback]) + + React.useEffect(() => { + if (!delay && delay !== 0) { + return undefined + } + + const id = setInterval( + () => savedCallback.current(), + delay + ) + + return () => clearInterval(id) + }, [delay]) +} diff --git a/packages/mdx/src/utils/index.tsx b/packages/mdx/src/utils/index.tsx index a7ec1132..5f33a8e5 100644 --- a/packages/mdx/src/utils/index.tsx +++ b/packages/mdx/src/utils/index.tsx @@ -4,3 +4,7 @@ export * from "./code" export * from "./focus" export * from "./theme" export * from "./hooks" + +export function clamp(x: number, min: number, max: number) { + return Math.min(Math.max(x, min), max) +}