[
  {
    "path": ".babelrc.js",
    "content": "module.exports = {\n  presets: [['babel-preset-jason', { runtime: false }]],\n  plugins: [\n    ['babel-plugin-transform-react-remove-prop-types', { mode: 'wrap' }],\n  ],\n  env: {\n    esm: {\n      presets: [['babel-preset-jason', { modules: false }]],\n    },\n  },\n};\n"
  },
  {
    "path": ".eslintignore",
    "content": "**/node_modules\nwww/.cache/\nwww/public/\nlib\n"
  },
  {
    "path": ".eslintrc.yml",
    "content": "parser: babel-eslint\nextends:\n  - jason/react\n  - plugin:jsx-a11y/recommended\n  - prettier\nsettings:\n  react:\n    version: detect\nenv:\n  node: true\n  browser: true\nplugins:\n  - jsx-a11y\n\noverrides:\n  - files: www/**/*\n    env:\n      es6: true\n  - files: stories/**/*\n    rules:\n      no-console: off\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug-report.md",
    "content": "---\nname: Bug report\nabout: Something isn't working as expected.\n---\n\n> What is the current behavior?\n\n<!-- ... -->\n\n> What is the expected behavior?\n\n<!-- If your use case is complicated, please be as descriptive as possible. -->\n\n<!-- ... -->\n\n> Could you provide a [CodeSandbox](https://codesandbox.io/) demo reproducing the bug?\n\n<!-- ... -->\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature-request.md",
    "content": "---\nname: Feature request\nabout: I have a suggestion on how to improve the library.\n---\n\n> What would you like improved?\n\n<!-- ... -->\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: CI\n\non:\n  push:\n    branches: [master, alpha]\n  pull_request:\n    branches: [master, alpha]\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n\n    strategy:\n      # Otherwise how would we know if a specific React version caused the failure?\n      fail-fast: false\n      matrix:\n        REACT_DIST: [16, 17, 18]\n    steps:\n      - uses: actions/checkout@v2\n      - name: Use Node.js 14\n        uses: actions/setup-node@v2\n        with:\n          node-version: 14\n          cache: 'npm'\n      - run: yarn\n      - run: yarn add react@${{ matrix.REACT_DIST }} react-dom@${{ matrix.REACT_DIST }}\n      - run: yarn add @testing-library/react@12\n        if: matrix.REACT_DIST == '17' || matrix.REACT_DIST == '16'\n      - run: yarn --cwd www\n      # Test whether the web page can be built successfully or not\n      - run: yarn --cwd www build\n      - run: yarn test\n      - name: Dry release\n        uses: cycjimmy/semantic-release-action@v2\n        with:\n          dry_run: true\n          semantic_version: 17\n          branches: |\n            [\n              'master',\n              {name: 'alpha', prerelease: true}\n            ]\n        env:\n          # These are not available on forks but we need them on actual runs to verify everything is set up.\n          # Otherwise we might fail in the middle of a release\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}\n\n  release:\n    needs: test\n    runs-on: ubuntu-latest\n    if: ${{ github.repository == 'reactjs/react-transition-group' &&\n      contains('refs/heads/master,refs/heads/alpha',\n      github.ref) && github.event_name == 'push' }}\n    steps:\n      - uses: styfle/cancel-workflow-action@0.9.0\n      - uses: actions/checkout@v2\n      - name: Use Node.js 14\n        uses: actions/setup-node@v2\n        with:\n          node-version: 14\n          cache: 'npm'\n      - run: yarn\n      - run: yarn build\n      - name: Release\n        uses: cycjimmy/semantic-release-action@v2\n        with:\n          semantic_version: 17\n          branches: |\n            [\n              'master',\n              {name: 'alpha', prerelease: true}\n            ]\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}\n"
  },
  {
    "path": ".gitignore",
    "content": "/lib\n\n# Logs\nlogs\n*.log\nnpm-debug.log*\n\n# Runtime data\npids\n*.pid\n*.seed\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (http://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules\njspm_packages\n\n# Optional npm cache directory\n.npm\n\n# Optional REPL history\n.node_repl_history\n\n# Visual Studio Code configuration\n.vscode\n"
  },
  {
    "path": ".prettierignore",
    "content": "**/node_modules\nwww/.cache/\nwww/public/\nlib\n*.md"
  },
  {
    "path": ".size-snapshot.json",
    "content": "{\n  \"./lib/dist/react-transition-group.js\": {\n    \"bundled\": 82684,\n    \"minified\": 22426,\n    \"gzipped\": 6876\n  },\n  \"./lib/dist/react-transition-group.min.js\": {\n    \"bundled\": 47269,\n    \"minified\": 14623,\n    \"gzipped\": 4616\n  }\n}\n"
  },
  {
    "path": ".storybook/main.js",
    "content": "const { plugins, rules } = require('webpack-atoms');\n\nmodule.exports = {\n  stories: ['../stories/index.js'],\n  webpackFinal: (config) => {\n    config.module = {\n      rules: [rules.js(), rules.astroturf(), rules.css({ extract: false })],\n    };\n\n    config.plugins.push(plugins.extractCss({ disable: true }));\n\n    return config;\n  },\n};\n"
  },
  {
    "path": ".storybook/preview.js",
    "content": "import React from 'react';\n\nexport const decorators = [\n  (Story) => (\n    <React.StrictMode>\n      <Story />\n    </React.StrictMode>\n  ),\n];\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "## [4.4.5](https://github.com/reactjs/react-transition-group/compare/v4.4.4...v4.4.5) (2022-08-01)\n\n\n### Bug Fixes\n\n* apply entering animation synchronously when unmountOnExit or mountOnEnter is enabled ([#847](https://github.com/reactjs/react-transition-group/issues/847)) ([1043549](https://github.com/reactjs/react-transition-group/commit/10435492f5a5675b0e80ca6a435834ce4a0f270e))\n\n## [4.4.4](https://github.com/reactjs/react-transition-group/compare/v4.4.3...v4.4.4) (2022-07-30)\n\n\n### Bug Fixes\n\n* missing build files ([#845](https://github.com/reactjs/react-transition-group/issues/845)) ([97af789](https://github.com/reactjs/react-transition-group/commit/97af7893b0a5bbf69211bc3287aee814123ddeea))\n\n## [4.4.3](https://github.com/reactjs/react-transition-group/compare/v4.4.2...v4.4.3) (2022-07-30)\n\n\n### Bug Fixes\n\n* enter animations with mountOnEnter or unmountOnExit  ([#749](https://github.com/reactjs/react-transition-group/issues/749)) ([51bdceb](https://github.com/reactjs/react-transition-group/commit/51bdceb96c8b6a79f417c32326ef1b31160edb97))\n\n## [4.4.2](https://github.com/reactjs/react-transition-group/compare/v4.4.1...v4.4.2) (2021-05-29)\n\n\n### Bug Fixes\n\n* `nodeRef` prop type for cross-realm elements ([#732](https://github.com/reactjs/react-transition-group/issues/732)) ([8710c01](https://github.com/reactjs/react-transition-group/commit/8710c01549e09f55eeefec2aadb3af0a23a00f82))\n\n## [4.4.1](https://github.com/reactjs/react-transition-group/compare/v4.4.0...v4.4.1) (2020-05-06)\n\n\n### Bug Fixes\n\n* transition SSR ([#619](https://github.com/reactjs/react-transition-group/issues/619)) ([2722bb6](https://github.com/reactjs/react-transition-group/commit/2722bb6b755943b8292f0f2bc2fdca55df5c28f0))\n\n# [4.4.0](https://github.com/reactjs/react-transition-group/compare/v4.3.0...v4.4.0) (2020-05-05)\n\n\n### Features\n\n* add `nodeRef` alternative instead of internal `findDOMNode` ([#559](https://github.com/reactjs/react-transition-group/issues/559)) ([85016bf](https://github.com/reactjs/react-transition-group/commit/85016bfddd3831e6d7bb27926f9f178d25502913))\n  - react-transition-group internally uses `findDOMNode`, which is deprecated and produces warnings in [Strict Mode](https://reactjs.org/docs/strict-mode.html), so now you can optionally pass `nodeRef` to `Transition` and `CSSTransition`, it's a ref object that should point to the transitioning child:\n\n    ```jsx\n    import React from \"react\"\n    import { CSSTransition } from \"react-transition-group\"\n\n    const MyComponent = () => {\n      const nodeRef = React.useRef(null)\n      return (\n        <CSSTransition nodeRef={nodeRef} in timeout={200} classNames=\"fade\">\n          <div ref={nodeRef}>Fade</div>\n        </CSSTransition>\n      )\n    }\n    ```\n### Bug Fixes\n\n* set the values of constants attached to `Transition` to match the exported ones ([#554](https://github.com/reactjs/react-transition-group/pull/554))\n\n# [4.3.0](https://github.com/reactjs/react-transition-group/compare/v4.2.2...v4.3.0) (2019-09-05)\n\n\n### Features\n\n* upgrade dom-helpers ([#549](https://github.com/reactjs/react-transition-group/issues/549)) ([b017e18](https://github.com/reactjs/react-transition-group/commit/b017e18))\n\n## [4.2.2](https://github.com/reactjs/react-transition-group/compare/v4.2.1...v4.2.2) (2019-08-02)\n\n\n### Bug Fixes\n\n* Fix imports to play nicely with rollup ([#530](https://github.com/reactjs/react-transition-group/issues/530)) ([3d9003e](https://github.com/reactjs/react-transition-group/commit/3d9003e))\n\n## [4.2.1](https://github.com/reactjs/react-transition-group/compare/v4.2.0...v4.2.1) (2019-07-02)\n\n\n### Bug Fixes\n\n* updated SwitchTransition component to be default export and exported from index.js ([#516](https://github.com/reactjs/react-transition-group/issues/516)) ([cfd0070](https://github.com/reactjs/react-transition-group/commit/cfd0070))\n\n# [4.2.0](https://github.com/reactjs/react-transition-group/compare/v4.1.1...v4.2.0) (2019-06-28)\n\n\n### Features\n\n* add SwitchTransition component ([#470](https://github.com/reactjs/react-transition-group/issues/470)) ([c5e379d](https://github.com/reactjs/react-transition-group/commit/c5e379d))\n\n## [4.1.1](https://github.com/reactjs/react-transition-group/compare/v4.1.0...v4.1.1) (2019-06-10)\n\n\n### Bug Fixes\n\n* adds missing dependency [@babel](https://github.com/babel)/runtime ([#507](https://github.com/reactjs/react-transition-group/issues/507)) ([228bf5f](https://github.com/reactjs/react-transition-group/commit/228bf5f))\n\n# [4.1.0](https://github.com/reactjs/react-transition-group/compare/v4.0.1...v4.1.0) (2019-05-30)\n\n\n### Features\n\n* add global transition disable switch ([#506](https://github.com/reactjs/react-transition-group/issues/506)) ([4c5ba98](https://github.com/reactjs/react-transition-group/commit/4c5ba98))\n\n## [4.0.1](https://github.com/reactjs/react-transition-group/compare/v4.0.0...v4.0.1) (2019-05-09)\n\n\n### Bug Fixes\n\n* issue with dynamically applied classes not being properly removed for reentering items ([#499](https://github.com/reactjs/react-transition-group/issues/499)) ([129cb11](https://github.com/reactjs/react-transition-group/commit/129cb11))\n\n# [4.0.0](https://github.com/reactjs/react-transition-group/compare/v3.0.0...v4.0.0) (2019-04-16)\n\n\n### Features\n\n* support esm via package.json routes ([#488](https://github.com/reactjs/react-transition-group/issues/488)) ([6337bf5](https://github.com/reactjs/react-transition-group/commit/6337bf5)), closes [#77](https://github.com/reactjs/react-transition-group/issues/77)\n\n\n### BREAKING CHANGES\n\n* in environments where esm is supported importing from commonjs requires explicitly adding the `.default` after `require()` when resolving to the esm build\n\n# [3.0.0](https://github.com/reactjs/react-transition-group/compare/v2.9.0...v3.0.0) (2019-04-15)\n\n\n### Features\n\n* use stable context API ([#471](https://github.com/reactjs/react-transition-group/issues/471)) ([aee4901](https://github.com/reactjs/react-transition-group/commit/aee4901)), closes [#429](https://github.com/reactjs/react-transition-group/issues/429)\n\n\n### BREAKING CHANGES\n\n* use new style react context\n\n```diff\n// package.json\n-\"react\": \"^15.0.0\",\n+\"react\": \"^16.6.0\",\n-\"react-dom\": \"^15.0.0\", \n+\"react-dom\": \"^16.6.0\", \n```\n\n# [2.9.0](https://github.com/reactjs/react-transition-group/compare/v2.8.0...v2.9.0) (2019-04-06)\n\n\n### Features\n\n* **CSSTransition:** add \"done\" class for appear ([fe3c156](https://github.com/reactjs/react-transition-group/commit/fe3c156)), closes [#383](https://github.com/reactjs/react-transition-group/issues/383) [#327](https://github.com/reactjs/react-transition-group/issues/327) [#327](https://github.com/reactjs/react-transition-group/issues/327)\n\n\n### Reverts\n\n* bump semantic release dependencies ([1bdcaec](https://github.com/reactjs/react-transition-group/commit/1bdcaec))\n\n# [2.8.0](https://github.com/reactjs/react-transition-group/compare/v2.7.1...v2.8.0) (2019-04-02)\n\n\n### Features\n\n* add support for empty classNames ([#481](https://github.com/reactjs/react-transition-group/issues/481)) ([d755dc6](https://github.com/reactjs/react-transition-group/commit/d755dc6))\n\n## [2.7.1](https://github.com/reactjs/react-transition-group/compare/v2.7.0...v2.7.1) (2019-03-25)\n\n\n### Bug Fixes\n\n* revert tree-shaking support because it was a breaking change ([271364c](https://github.com/reactjs/react-transition-group/commit/271364c))\n\n# [2.7.0](https://github.com/reactjs/react-transition-group/compare/v2.6.1...v2.7.0) (2019-03-22)\n\n\n### Features\n\n* support ESM (tree-shaking) ([#455](https://github.com/reactjs/react-transition-group/issues/455)) ([ef3e357](https://github.com/reactjs/react-transition-group/commit/ef3e357))\n\n## [2.6.1](https://github.com/reactjs/react-transition-group/compare/v2.6.0...v2.6.1) (2019-03-14)\n\n\n### Bug Fixes\n\n* **Transition:** make `exit` key optional when passing an object to the `timeout` prop ([#464](https://github.com/reactjs/react-transition-group/pull/464)) ([3a4cf9c](https://github.com/reactjs/react-transition-group/commit/3a4cf9c91ab5f25caaa9501b129bce66ec9bb56b))\n* **package.json:** mark react-transition-group as side-effect free for webpack tree shaking ([#472](https://github.com/reactjs/react-transition-group/issues/472)) ([b81dc89](https://github.com/reactjs/react-transition-group/commit/b81dc89))\n\n# [2.6.0](https://github.com/reactjs/react-transition-group/compare/v2.5.3...v2.6.0) (2019-02-26)\n\n\n### Features\n\n* add appear timeout ([#462](https://github.com/reactjs/react-transition-group/issues/462)) ([52cdc34](https://github.com/reactjs/react-transition-group/commit/52cdc34))\n\n## [2.5.3](https://github.com/reactjs/react-transition-group/compare/v2.5.2...v2.5.3) (2019-01-14)\n\n\n### Bug Fixes\n\n* strip custom prop-types in production ([#448](https://github.com/reactjs/react-transition-group/issues/448)) ([46fa20f](https://github.com/reactjs/react-transition-group/commit/46fa20f))\n\n## [2.5.2](https://github.com/reactjs/react-transition-group/compare/v2.5.1...v2.5.2) (2018-12-20)\n\n\n### Bug Fixes\n\n* pass appear to CSSTransition callbacks ([#441](https://github.com/reactjs/react-transition-group/issues/441)) ([df7adb4](https://github.com/reactjs/react-transition-group/commit/df7adb4)), closes [#143](https://github.com/reactjs/react-transition-group/issues/143)\n\n## [2.5.1](https://github.com/reactjs/react-transition-group/compare/v2.5.0...v2.5.1) (2018-12-10)\n\n\n### Bug Fixes\n\n* prevent calling setState in TransitionGroup if it has been unmounted ([#435](https://github.com/reactjs/react-transition-group/issues/435)) ([6d46b69](https://github.com/reactjs/react-transition-group/commit/6d46b69))\n\n# [2.5.0](https://github.com/reactjs/react-transition-group/compare/v2.4.0...v2.5.0) (2018-09-26)\n\n\n### Features\n\n* update build and package dependencies ([#413](https://github.com/reactjs/react-transition-group/issues/413)) ([af3d45a](https://github.com/reactjs/react-transition-group/commit/af3d45a))\n\n# [2.4.0](https://github.com/reactjs/react-transition-group/compare/v2.3.1...v2.4.0) (2018-06-27)\n\n\n### Features\n\n* remove deprecated lifecycle hooks and polyfill for older react versions ([c1ab1cf](https://github.com/reactjs/react-transition-group/commit/c1ab1cf))\n\n\n### Performance Improvements\n\n* don't reflow when there's no class to add ([d7b898d](https://github.com/reactjs/react-transition-group/commit/d7b898d))\n\n<a name=\"2.3.1\"></a>\n## [2.3.1](https://github.com/reactjs/react-transition-group/compare/v2.3.0...v2.3.1) (2018-04-14)\n\n\n### Bug Fixes\n\n* **deps:** Move loose-envify and semantic-release to devDependencies ([#319](https://github.com/reactjs/react-transition-group/issues/319)) ([b4ec774](https://github.com/reactjs/react-transition-group/commit/b4ec774))\n\n## [v2.3.0]\n\n> 2018-03-28\n\n* Added `*-done` classes to CSS Transition ([#269])\n* Reorganize docs with more interesting examples! ([#304])\n* A bunch of bug fixes\n\n[#269]: https://github.com/reactjs/react-transition-group/pull/269\n[#304]: https://github.com/reactjs/react-transition-group/pull/304\n[v2.3.0]: https://github.com/reactjs/react-transition-group/compare/v2.2.1...2.3.0\n\n## [v2.2.1]\n\n> 2017-09-29\n\n* **Patch:** Allow React v16 ([#198])\n\n[#198]: https://github.com/reactjs/react-transition-group/pull/198\n[v2.2.1]: https://github.com/reactjs/react-transition-group/compare/v2.2.0...2.2.1\n\n## [v2.2.0]\n\n> 2017-07-21\n\n* **Feature:** Support multiple classes in `classNames` ([#124])\n* **Docs:** fix broken link ([#127])\n* **Bugfix:** Fix Transition props pass-through ([#123])\n\n[#124]: https://github.com/reactjs/react-transition-group/pull/124\n[#123]: https://github.com/reactjs/react-transition-group/pull/123\n[#127]: https://github.com/reactjs/react-transition-group/pull/127\n[v2.2.0]: https://github.com/reactjs/react-transition-group/compare/v2.1.0...2.2.0\n\n## [v2.1.0]\n\n> 2017-07-06\n\n* **Feature:** Add back `childFactory` on `<TransitionGroup>` ([#113])\n* **Bugfix:** Ensure child specified `onExited` fires in a `<TransitionGroup>` ([#113])\n\n[#113]: https://github.com/reactjs/react-transition-group/pull/113\n[v2.1.0]: https://github.com/reactjs/react-transition-group/compare/v2.0.1...2.1.0\n\n## v2.0.2\n\n> 2017-07-06\n\n* **Fix documentation npm:** No code changes\n\n## v2.0.1\n\n> 2017-07-06\n\n* **Fix documentation on npm:** No code changes\n\n## [v2.0.0]\n\n> 2017-07-06\n\n* **Feature:** New API! ([#24]), migration guide at [https://github.com/reactjs/react-transition-group/blob/master/Migration.md](https://github.com/reactjs/react-transition-group/blob/master/Migration.md)\n\n[#24]: https://github.com/reactjs/react-transition-group/pull/24\n[v2.0.0]: https://github.com/reactjs/react-transition-group/compare/v1.2.0...v2.0.0\n\n## [v1.2.0]\n\n> 2017-06-12\n\n* **Feature:** Dist build now includes both production and development builds ([#64])\n* **Feature:** PropTypes are now wrapped allowing for lighter weight production builds ([#69])\n\n[#64]: https://github.com/reactjs/react-transition-group/issues/64\n[#69]: https://github.com/reactjs/react-transition-group/issues/69\n[v1.1.x]: https://github.com/reactjs/react-transition-group/compare/v1.1.3...master\n\n## [v1.1.3]\n\n> 2017-05-02\n\n* bonus release, no additions\n\n[v1.1.3]: https://github.com/reactjs/react-transition-group/compare/v1.1.2...v1.1.3\n\n## [v1.1.2]\n\n> 2017-05-02\n\n* **Bugfix:** Fix refs on children ([#39])\n\n[v1.1.2]: https://github.com/reactjs/react-transition-group/compare/v1.1.1...v1.1.2\n[#39]: https://github.com/reactjs/react-transition-group/pull/39\n\n## [v1.1.1]\n\n> 2017-03-16\n\n* **Chore:** Add a prebuilt version of the library for jsbin and the like.\n\n[v1.1.1]: https://github.com/reactjs/react-transition-group/compare/v1.1.0...v1.1.1\n\n## [v1.1.0]\n\n> 2017-03-16\n\n* **Feature:** Support refs on children ([#9])\n* **Feature:** TransitionChild to passes props through ([#4])\n* **Bugfix:** Fix TransitionGroup error on quick toggle of components ([#15])\n* **Bugfix:** Fix to work enter animation with CSSTransitionGroup ([#13])\n\n[v1.1.0]: https://github.com/reactjs/react-transition-group/compare/v1.0.0...v1.1.0\n[#15]: https://github.com/reactjs/react-transition-group/pull/15\n[#13]: https://github.com/reactjs/react-transition-group/pull/13\n[#9]: https://github.com/reactjs/react-transition-group/pull/9\n[#4]: https://github.com/reactjs/react-transition-group/pull/4\n"
  },
  {
    "path": "LICENSE",
    "content": "BSD 3-Clause License\n\nCopyright (c) 2018, React Community\nForked from React (https://github.com/facebook/react) Copyright 2013-present, Facebook, Inc.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\n* Neither the name of the copyright holder nor the names of its\n  contributors may be used to endorse or promote products derived from\n  this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "Migration.md",
    "content": "# Migration Guide from v1 to v2\n\n_A few notes to help with migrating from v1 to v2._\n\nThe `<CSSTransitionGroup>` component has been removed. A `<CSSTransition>` component has been added for use with the new `<TransitionGroup>` component to accomplish the same tasks.\n\n### tl;dr:\n\n- `transitionName` -> `classNames`\n- `transitionEnterTimeout` and `transitionLeaveTimeout` -> `timeout={{ exit, enter }}`\n- `transitionAppear` -> `appear`\n- `transitionEnter` -> `enter`\n- `transitionLeave` -> `exit`\n\n## Walkthrough\n\nLet's take the [original docs example](https://github.com/reactjs/react-transition-group/tree/v1-stable/#high-level-api-csstransitiongroup) and migrate it.\n\nStarting with this CSS:\n\n```css\n.example-enter {\n  opacity: 0.01;\n}\n\n.example-enter.example-enter-active {\n  opacity: 1;\n  transition: opacity 500ms ease-in;\n}\n\n.example-leave {\n  opacity: 1;\n}\n\n.example-leave.example-leave-active {\n  opacity: 0.01;\n  transition: opacity 300ms ease-in;\n}\n```\n\nAnd this component:\n\n```js\nclass TodoList extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {items: ['hello', 'world', 'click', 'me']};\n    this.handleAdd = this.handleAdd.bind(this);\n  }\n\n  handleAdd() {\n    const newItems = this.state.items.concat([\n      prompt('Enter some text')\n    ]);\n    this.setState({items: newItems});\n  }\n\n  handleRemove(i) {\n    let newItems = this.state.items.slice();\n    newItems.splice(i, 1);\n    this.setState({items: newItems});\n  }\n\n  render() {\n    const items = this.state.items.map((item, i) => (\n      <div key={i} onClick={() => this.handleRemove(i)}>\n        {item}\n      </div>\n    ));\n\n    return (\n      <div>\n        <button onClick={this.handleAdd}>Add Item</button>\n        <CSSTransitionGroup\n          transitionName=\"example\"\n          transitionEnterTimeout={500}\n          transitionLeaveTimeout={300}>\n          {items}\n        </CSSTransitionGroup>\n      </div>\n    );\n  }\n}\n```\n\nThe most straightforward way to migrate is to use `<TransitionGroup>` instead of `<CSSTransitionGroup>`:\n\n```diff\n render() {\n   const items = this.state.items.map((item, i) => (\n     <div key={i} onClick={() => this.handleRemove(i)}>\n       {item}\n     </div>\n   ));\n\n   return (\n     <div>\n       <button onClick={this.handleAdd}>Add Item</button>\n-      <CSSTransitionGroup\n-        transitionName=\"example\"\n-        transitionEnterTimeout={500}\n-        transitionLeaveTimeout={300}>\n+      <TransitionGroup>\n         {items}\n-      </CSSTransitionGroup>\n+      </TransitionGroup>\n     </div>\n   )\n }\n```\n\nThat doesn't get us much, since we haven't included anything to do the animation. For that, we'll need to wrap each item in a `<CSSTransition>`. First, though, let's adjust our CSS:\n\n```diff\n .example-enter {\n   opacity: 0.01;\n }\n\n .example-enter.example-enter-active {\n   opacity: 1;\n   transition: opacity 500ms ease-in;\n }\n\n-.example-leave {\n+.example-exit {\n   opacity: 1;\n }\n\n-.example-leave.example-leave-active {\n+.example-exit.example-exit-active {\n   opacity: 0.01;\n   transition: opacity 300ms ease-in;\n }\n```\n\nAll we did was replace `leave` with `exit`. v2 uses \"exit\" instead of \"leave\" to be more symmetric, avoiding awkwardness with English tenses (like with \"entered\" and \"leaved\").\n\nNow we add the `<CSSTransition>` component:\n\n```diff\n render() {\n   const items = this.state.items.map((item, i) => (\n+    <CSSTransition\n+      key={i}\n+      classNames=\"example\"\n+      timeout={{ enter: 500, exit: 300 }}\n+    >\n       <div onClick={() => this.handleRemove(i)}>\n         {item}\n       </div>\n+    </CSSTransition>\n   ));\n\n   return (\n     <div>\n       <button onClick={this.handleAdd}>Add Item</button>\n       <TransitionGroup>\n         {items}\n       </TransitionGroup>\n     </div>\n   )\n }\n```\n\nNote that we replaced `transitionName` with `classNames`. `<CSSTransition>` otherwise has essentially the same signature as `<CSSTransitionGroup>`. We also replaced `transitionEnterTimeout` and `transitionLeaveTimeout` with a single `timeout` prop with an object.\n\n> **Hint:** If your enter and exit timeouts are the same you can use the shorthand `timeout={500}`.\n\nIf we want to make this a bit more encapsulated, we can wrap our `<CSSTransition>` into a separate component for reuse later:\n\n```js\nconst FadeTransition = (props) => (\n  <CSSTransition\n    {...props}\n    classNames=\"example\"\n    timeout={{ enter: 500, exit: 300 }}\n  />\n);\n```\n\nWe can then use it like:\n\n```diff\n render() {\n   const items = this.state.items.map((item, i) => (\n-    <CSSTransition\n-      key={i}\n-      classNames=\"example\"\n-      timeout={{ enter: 500, exit: 300 }}\n-    >\n+    <FadeTransition key={i}>\n       <div onClick={() => this.handleRemove(i)}>\n         {item}\n       </div>\n-    </CSSTransition>\n+    </FadeTransition>\n   ));\n\n   return (\n     <div>\n       <button onClick={this.handleAdd}>Add Item</button>\n       <TransitionGroup>\n         {items}\n       </TransitionGroup>\n     </div>\n   )\n }\n```\n\n> **Hey!** You may not need `<CSSTransition>` at all! The lower level `<Transition>` component is very flexible and may be easier to work with for simpler or more custom cases. Check out how we migrated [React-Bootstrap](https://react-bootstrap.github.io/)'s simple transitions to v2 for the [`<Collapse>`](https://github.com/react-bootstrap/react-bootstrap/pull/2676/files#diff-4f938f648d04d4859be417d6590ca7c4) and [`<Fade>`](https://github.com/react-bootstrap/react-bootstrap/pull/2676/files#diff-8f766132cbd9f8de55ee05d63d75abd8) components.\n\n\n## Wrapping `<Transition>` Components\n\nThe old `<TransitionGroup>` component managed transitions through custom static lifecycle methods on its children. In v2 we removed that API in favor of requiring that `<TransitionGroup>` be used with a `<Transition>` component, and using traditional prop passing to communicate between the two.\n\nThis means that `<TransitionGroup>`s inject their children with `<Transition>`-specific props that _must_ be passed through to the `<Transition>` component for the transition to work.\n\n```js\nconst MyTransition = ({ children: child, ...props }) => (\n  // NOTICE THE SPREAD! THIS IS REQUIRED!\n  <Transition {...props}>\n    {transitionState => React.cloneElement(child, {\n      style: getStyleForTransitionState(transitionState)\n    })}\n  </Transition>\n);\n\nconst MyList = () => (\n  <TransitionGroup>\n    {items.map(item => (\n      <MyTransition>{item}</MyTransition>\n    )}\n  </TransitionGroup>\n);\n```\n\nNote how `<MyTransition>` passes all props other than its own to `<Transition>`.\n\n\n## Lifecycle Callbacks\n\nAs noted, child lifecycle methods have been removed. If you do need to do some work when the `<Transition>` changes from one state to another, use the lifecycle callback props.\n\n```js\n<Transition\n  {...props}\n  onEnter={handleEnter}\n  onEntering={handleEntering}\n  onEntered={handleEntered}\n  onExit={handleExit}\n  onExiting={handleExiting}\n  onExited={handleExited}\n/>\n```\n\nEach callback is called with the DOM node of the transition component. Note also that there are now _three_ states per enter/exit transition instead of the original two. See the [full documentation](https://reactcommunity.org/react-transition-group/#Transition) for more details.\n"
  },
  {
    "path": "README.md",
    "content": "# react-transition-group [![npm][npm-badge]][npm]\n\n> **ATTENTION!** To address many issues that have come up over the years, the API in v2 and above is not backwards compatible with the original [`React addon (v1-stable)`](https://github.com/reactjs/react-transition-group/tree/v1-stable).\n>\n> **For a drop-in replacement for `react-addons-transition-group` and `react-addons-css-transition-group`, use the v1 release. Documentation and code for that release are available on the [`v1-stable`](https://github.com/reactjs/react-transition-group/tree/v1-stable) branch.**\n>\n> We are no longer updating the v1 codebase, please upgrade to the latest version when possible\n\nA set of components for managing component states (including mounting and unmounting) over time, specifically designed with animation in mind.\n\n## Documentation\n\n- [**Main documentation**](https://reactcommunity.org/react-transition-group/)\n- [Migration guide from v1](/Migration.md)\n\n## TypeScript\nTypeScript definitions are published via [**DefinitelyTyped**](https://github.com/DefinitelyTyped/DefinitelyTyped) and can be installed via the following command:\n\n```\nnpm install @types/react-transition-group\n```\n\n## Examples\n\nClone the repo first:\n\n```\ngit@github.com:reactjs/react-transition-group.git\n```\n\nThen run `npm install` (or `yarn`), and finally `npm run storybook` to start a storybook instance that you can navigate to in your browser to see the examples.\n\n[npm-badge]: https://img.shields.io/npm/v/react-transition-group.svg\n[npm]: https://www.npmjs.org/package/react-transition-group\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"react-transition-group\",\n  \"version\": \"4.4.5\",\n  \"description\": \"A react component toolset for managing animations\",\n  \"main\": \"lib/cjs/index.js\",\n  \"module\": \"lib/esm/index.js\",\n  \"scripts\": {\n    \"test\": \"npm run lint && npm run testonly\",\n    \"testonly\": \"jest --verbose\",\n    \"tdd\": \"jest --watch\",\n    \"build\": \"rimraf lib && yarn build:cjs && yarn build:esm && yarn build:pick && yarn build:dist && cp README.md LICENSE ./lib\",\n    \"build:docs\": \"yarn --cwd www run build\",\n    \"build:cjs\": \"babel src --out-dir lib/cjs\",\n    \"build:esm\": \"cross-env BABEL_ENV=esm babel src --out-dir lib/esm\",\n    \"build:pick\": \"cherry-pick --cwd=lib --input-dir=../src --cjs-dir=cjs --esm-dir=esm\",\n    \"build:dist\": \"cross-env BABEL_ENV=esm rollup -c\",\n    \"bootstrap\": \"yarn && yarn --cwd www\",\n    \"fix\": \"run-s fix:eslint fix:prettier\",\n    \"fix:eslint\": \"yarn lint:eslint --fix\",\n    \"fix:prettier\": \"yarn lint:prettier --write\",\n    \"lint\": \"run-p lint:*\",\n    \"lint:eslint\": \"eslint .\",\n    \"lint:prettier\": \"prettier . --check\",\n    \"release\": \"release\",\n    \"release:next\": \"release --preid beta --tag next\",\n    \"deploy-docs\": \"yarn --cwd www run deploy\",\n    \"start\": \"yarn --cwd www run develop\",\n    \"storybook\": \"start-storybook -p 6006\",\n    \"build-storybook\": \"build-storybook\",\n    \"semantic-release\": \"semantic-release\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/reactjs/react-transition-group.git\"\n  },\n  \"keywords\": [\n    \"react\",\n    \"transition\",\n    \"addons\",\n    \"transition-group\",\n    \"animation\",\n    \"css\",\n    \"transitions\"\n  ],\n  \"author\": \"\",\n  \"license\": \"BSD-3-Clause\",\n  \"bugs\": {\n    \"url\": \"https://github.com/reactjs/react-transition-group/issues\"\n  },\n  \"homepage\": \"https://github.com/reactjs/react-transition-group#readme\",\n  \"jest\": {\n    \"testRegex\": \"-test\\\\.js\",\n    \"setupFiles\": [\n      \"./test/setup.js\"\n    ],\n    \"setupFilesAfterEnv\": [\n      \"./test/setupAfterEnv.js\"\n    ],\n    \"roots\": [\n      \"<rootDir>/test\"\n    ]\n  },\n  \"peerDependencies\": {\n    \"react\": \">=16.6.0\",\n    \"react-dom\": \">=16.6.0\"\n  },\n  \"dependencies\": {\n    \"@babel/runtime\": \"^7.5.5\",\n    \"dom-helpers\": \"^5.0.1\",\n    \"loose-envify\": \"^1.4.0\",\n    \"prop-types\": \"^15.6.2\"\n  },\n  \"devDependencies\": {\n    \"@babel/cli\": \"^7.8.4\",\n    \"@babel/core\": \"^7.9.0\",\n    \"@restart/hooks\": \"^0.3.22\",\n    \"@semantic-release/changelog\": \"^5.0.1\",\n    \"@semantic-release/git\": \"^9.0.0\",\n    \"@semantic-release/github\": \"^7.0.5\",\n    \"@semantic-release/npm\": \"^7.0.5\",\n    \"@storybook/addon-actions\": \"^6.3.4\",\n    \"@storybook/react\": \"^6.3.4\",\n    \"@testing-library/react\": \"alpha\",\n    \"@typescript-eslint/eslint-plugin\": \"^4.26.1\",\n    \"astroturf\": \"^0.10.4\",\n    \"babel-eslint\": \"^10.1.0\",\n    \"babel-loader\": \"^8.1.0\",\n    \"babel-plugin-transform-react-remove-prop-types\": \"^0.4.24\",\n    \"babel-preset-jason\": \"^6.2.0\",\n    \"cherry-pick\": \"^0.5.0\",\n    \"cross-env\": \"^7.0.2\",\n    \"eslint\": \"^7.28.0\",\n    \"eslint-config-jason\": \"^8.1.1\",\n    \"eslint-config-prettier\": \"^8.3.0\",\n    \"eslint-plugin-import\": \"^2.23.4\",\n    \"eslint-plugin-jsx-a11y\": \"^6.4.1\",\n    \"eslint-plugin-react\": \"^7.24.0\",\n    \"eslint-plugin-react-hooks\": \"^4.2.0\",\n    \"jest\": \"^25.3.0\",\n    \"npm-run-all\": \"^4.1.5\",\n    \"prettier\": \"^2.3.1\",\n    \"react\": \"^18.0.0\",\n    \"react-dom\": \"^18.0.0\",\n    \"release-script\": \"^1.0.2\",\n    \"rimraf\": \"^3.0.2\",\n    \"rollup\": \"^2.6.1\",\n    \"rollup-plugin-babel\": \"^4.4.0\",\n    \"rollup-plugin-commonjs\": \"^10.1.0\",\n    \"rollup-plugin-node-resolve\": \"^5.2.0\",\n    \"rollup-plugin-replace\": \"^2.2.0\",\n    \"rollup-plugin-size-snapshot\": \"^0.11.0\",\n    \"rollup-plugin-terser\": \"^5.3.0\",\n    \"semantic-release\": \"^17.0.6\",\n    \"semantic-release-alt-publish-dir\": \"^3.0.0\",\n    \"typescript\": \"^4.3.2\",\n    \"webpack-atoms\": \"14.0.0\"\n  },\n  \"release\": {\n    \"pkgRoot\": \"lib\",\n    \"verifyConditions\": [\n      \"@semantic-release/changelog\",\n      \"semantic-release-alt-publish-dir\",\n      \"@semantic-release/git\",\n      \"@semantic-release/github\"\n    ],\n    \"prepare\": [\n      \"@semantic-release/changelog\",\n      \"semantic-release-alt-publish-dir\",\n      \"@semantic-release/npm\",\n      \"@semantic-release/git\"\n    ]\n  },\n  \"browserify\": {\n    \"transform\": [\n      \"loose-envify\"\n    ]\n  },\n  \"sideEffects\": false\n}\n"
  },
  {
    "path": "prettier.config.js",
    "content": "module.exports = {\n  singleQuote: true,\n};\n"
  },
  {
    "path": "rollup.config.js",
    "content": "import nodeResolve from 'rollup-plugin-node-resolve';\nimport babel from 'rollup-plugin-babel';\nimport commonjs from 'rollup-plugin-commonjs';\nimport replace from 'rollup-plugin-replace';\nimport { sizeSnapshot } from 'rollup-plugin-size-snapshot';\nimport { terser } from 'rollup-plugin-terser';\n\nconst input = './src/index.js';\nconst name = 'ReactTransitionGroup';\nconst globals = {\n  react: 'React',\n  'react-dom': 'ReactDOM',\n};\n\nconst babelOptions = {\n  exclude: /node_modules/,\n  runtimeHelpers: true,\n};\n\nconst commonjsOptions = {\n  include: /node_modules/,\n  namedExports: {\n    'prop-types': ['object', 'oneOfType', 'element', 'bool', 'func'],\n  },\n};\n\nexport default [\n  {\n    input,\n    output: {\n      file: './lib/dist/react-transition-group.js',\n      format: 'umd',\n      name,\n      globals,\n    },\n    external: Object.keys(globals),\n    plugins: [\n      nodeResolve(),\n      babel(babelOptions),\n      commonjs(commonjsOptions),\n      replace({ 'process.env.NODE_ENV': JSON.stringify('development') }),\n      sizeSnapshot(),\n    ],\n  },\n\n  {\n    input,\n    output: {\n      file: './lib/dist/react-transition-group.min.js',\n      format: 'umd',\n      name,\n      globals,\n    },\n    external: Object.keys(globals),\n    plugins: [\n      nodeResolve(),\n      babel(babelOptions),\n      commonjs(commonjsOptions),\n      replace({ 'process.env.NODE_ENV': JSON.stringify('production') }),\n      sizeSnapshot(),\n      terser(),\n    ],\n  },\n];\n"
  },
  {
    "path": "src/CSSTransition.js",
    "content": "import PropTypes from 'prop-types';\nimport addOneClass from 'dom-helpers/addClass';\n\nimport removeOneClass from 'dom-helpers/removeClass';\nimport React from 'react';\n\nimport Transition from './Transition';\nimport { classNamesShape } from './utils/PropTypes';\nimport { forceReflow } from './utils/reflow';\n\nconst addClass = (node, classes) =>\n  node && classes && classes.split(' ').forEach((c) => addOneClass(node, c));\nconst removeClass = (node, classes) =>\n  node && classes && classes.split(' ').forEach((c) => removeOneClass(node, c));\n\n/**\n * A transition component inspired by the excellent\n * [ng-animate](https://docs.angularjs.org/api/ngAnimate) library, you should\n * use it if you're using CSS transitions or animations. It's built upon the\n * [`Transition`](https://reactcommunity.org/react-transition-group/transition)\n * component, so it inherits all of its props.\n *\n * `CSSTransition` applies a pair of class names during the `appear`, `enter`,\n * and `exit` states of the transition. The first class is applied and then a\n * second `*-active` class in order to activate the CSS transition. After the\n * transition, matching `*-done` class names are applied to persist the\n * transition state.\n *\n * ```jsx\n * function App() {\n *   const [inProp, setInProp] = useState(false);\n *   const nodeRef = useRef(null);\n *   return (\n *     <div>\n *       <CSSTransition nodeRef={nodeRef} in={inProp} timeout={200} classNames=\"my-node\">\n *         <div ref={nodeRef}>\n *           {\"I'll receive my-node-* classes\"}\n *         </div>\n *       </CSSTransition>\n *       <button type=\"button\" onClick={() => setInProp(true)}>\n *         Click to Enter\n *       </button>\n *     </div>\n *   );\n * }\n * ```\n *\n * When the `in` prop is set to `true`, the child component will first receive\n * the class `example-enter`, then the `example-enter-active` will be added in\n * the next tick. `CSSTransition` [forces a\n * reflow](https://github.com/reactjs/react-transition-group/blob/5007303e729a74be66a21c3e2205e4916821524b/src/CSSTransition.js#L208-L215)\n * between before adding the `example-enter-active`. This is an important trick\n * because it allows us to transition between `example-enter` and\n * `example-enter-active` even though they were added immediately one after\n * another. Most notably, this is what makes it possible for us to animate\n * _appearance_.\n *\n * ```css\n * .my-node-enter {\n *   opacity: 0;\n * }\n * .my-node-enter-active {\n *   opacity: 1;\n *   transition: opacity 200ms;\n * }\n * .my-node-exit {\n *   opacity: 1;\n * }\n * .my-node-exit-active {\n *   opacity: 0;\n *   transition: opacity 200ms;\n * }\n * ```\n *\n * `*-active` classes represent which styles you want to animate **to**, so it's\n * important to add `transition` declaration only to them, otherwise transitions\n * might not behave as intended! This might not be obvious when the transitions\n * are symmetrical, i.e. when `*-enter-active` is the same as `*-exit`, like in\n * the example above (minus `transition`), but it becomes apparent in more\n * complex transitions.\n *\n * **Note**: If you're using the\n * [`appear`](http://reactcommunity.org/react-transition-group/transition#Transition-prop-appear)\n * prop, make sure to define styles for `.appear-*` classes as well.\n */\nclass CSSTransition extends React.Component {\n  static defaultProps = {\n    classNames: '',\n  };\n\n  appliedClasses = {\n    appear: {},\n    enter: {},\n    exit: {},\n  };\n\n  onEnter = (maybeNode, maybeAppearing) => {\n    const [node, appearing] = this.resolveArguments(maybeNode, maybeAppearing);\n    this.removeClasses(node, 'exit');\n    this.addClass(node, appearing ? 'appear' : 'enter', 'base');\n\n    if (this.props.onEnter) {\n      this.props.onEnter(maybeNode, maybeAppearing);\n    }\n  };\n\n  onEntering = (maybeNode, maybeAppearing) => {\n    const [node, appearing] = this.resolveArguments(maybeNode, maybeAppearing);\n    const type = appearing ? 'appear' : 'enter';\n    this.addClass(node, type, 'active');\n\n    if (this.props.onEntering) {\n      this.props.onEntering(maybeNode, maybeAppearing);\n    }\n  };\n\n  onEntered = (maybeNode, maybeAppearing) => {\n    const [node, appearing] = this.resolveArguments(maybeNode, maybeAppearing);\n    const type = appearing ? 'appear' : 'enter';\n    this.removeClasses(node, type);\n    this.addClass(node, type, 'done');\n\n    if (this.props.onEntered) {\n      this.props.onEntered(maybeNode, maybeAppearing);\n    }\n  };\n\n  onExit = (maybeNode) => {\n    const [node] = this.resolveArguments(maybeNode);\n    this.removeClasses(node, 'appear');\n    this.removeClasses(node, 'enter');\n    this.addClass(node, 'exit', 'base');\n\n    if (this.props.onExit) {\n      this.props.onExit(maybeNode);\n    }\n  };\n\n  onExiting = (maybeNode) => {\n    const [node] = this.resolveArguments(maybeNode);\n    this.addClass(node, 'exit', 'active');\n\n    if (this.props.onExiting) {\n      this.props.onExiting(maybeNode);\n    }\n  };\n\n  onExited = (maybeNode) => {\n    const [node] = this.resolveArguments(maybeNode);\n    this.removeClasses(node, 'exit');\n    this.addClass(node, 'exit', 'done');\n\n    if (this.props.onExited) {\n      this.props.onExited(maybeNode);\n    }\n  };\n\n  // when prop `nodeRef` is provided `node` is excluded\n  resolveArguments = (maybeNode, maybeAppearing) =>\n    this.props.nodeRef\n      ? [this.props.nodeRef.current, maybeNode] // here `maybeNode` is actually `appearing`\n      : [maybeNode, maybeAppearing]; // `findDOMNode` was used\n\n  getClassNames = (type) => {\n    const { classNames } = this.props;\n    const isStringClassNames = typeof classNames === 'string';\n    const prefix = isStringClassNames && classNames ? `${classNames}-` : '';\n\n    let baseClassName = isStringClassNames\n      ? `${prefix}${type}`\n      : classNames[type];\n\n    let activeClassName = isStringClassNames\n      ? `${baseClassName}-active`\n      : classNames[`${type}Active`];\n\n    let doneClassName = isStringClassNames\n      ? `${baseClassName}-done`\n      : classNames[`${type}Done`];\n\n    return {\n      baseClassName,\n      activeClassName,\n      doneClassName,\n    };\n  };\n\n  addClass(node, type, phase) {\n    let className = this.getClassNames(type)[`${phase}ClassName`];\n    const { doneClassName } = this.getClassNames('enter');\n\n    if (type === 'appear' && phase === 'done' && doneClassName) {\n      className += ` ${doneClassName}`;\n    }\n\n    // This is to force a repaint,\n    // which is necessary in order to transition styles when adding a class name.\n    if (phase === 'active') {\n      if (node) forceReflow(node);\n    }\n\n    if (className) {\n      this.appliedClasses[type][phase] = className;\n      addClass(node, className);\n    }\n  }\n\n  removeClasses(node, type) {\n    const {\n      base: baseClassName,\n      active: activeClassName,\n      done: doneClassName,\n    } = this.appliedClasses[type];\n\n    this.appliedClasses[type] = {};\n\n    if (baseClassName) {\n      removeClass(node, baseClassName);\n    }\n    if (activeClassName) {\n      removeClass(node, activeClassName);\n    }\n    if (doneClassName) {\n      removeClass(node, doneClassName);\n    }\n  }\n\n  render() {\n    const { classNames: _, ...props } = this.props;\n\n    return (\n      <Transition\n        {...props}\n        onEnter={this.onEnter}\n        onEntered={this.onEntered}\n        onEntering={this.onEntering}\n        onExit={this.onExit}\n        onExiting={this.onExiting}\n        onExited={this.onExited}\n      />\n    );\n  }\n}\n\nCSSTransition.propTypes = {\n  ...Transition.propTypes,\n\n  /**\n   * The animation classNames applied to the component as it appears, enters,\n   * exits or has finished the transition. A single name can be provided, which\n   * will be suffixed for each stage, e.g. `classNames=\"fade\"` applies:\n   *\n   * - `fade-appear`, `fade-appear-active`, `fade-appear-done`\n   * - `fade-enter`, `fade-enter-active`, `fade-enter-done`\n   * - `fade-exit`, `fade-exit-active`, `fade-exit-done`\n   *\n   * A few details to note about how these classes are applied:\n   *\n   * 1. They are _joined_ with the ones that are already defined on the child\n   *    component, so if you want to add some base styles, you can use\n   *    `className` without worrying that it will be overridden.\n   *\n   * 2. If the transition component mounts with `in={false}`, no classes are\n   *    applied yet. You might be expecting `*-exit-done`, but if you think\n   *    about it, a component cannot finish exiting if it hasn't entered yet.\n   *\n   * 2. `fade-appear-done` and `fade-enter-done` will _both_ be applied. This\n   *    allows you to define different behavior for when appearing is done and\n   *    when regular entering is done, using selectors like\n   *    `.fade-enter-done:not(.fade-appear-done)`. For example, you could apply\n   *    an epic entrance animation when element first appears in the DOM using\n   *    [Animate.css](https://daneden.github.io/animate.css/). Otherwise you can\n   *    simply use `fade-enter-done` for defining both cases.\n   *\n   * Each individual classNames can also be specified independently like:\n   *\n   * ```js\n   * classNames={{\n   *  appear: 'my-appear',\n   *  appearActive: 'my-active-appear',\n   *  appearDone: 'my-done-appear',\n   *  enter: 'my-enter',\n   *  enterActive: 'my-active-enter',\n   *  enterDone: 'my-done-enter',\n   *  exit: 'my-exit',\n   *  exitActive: 'my-active-exit',\n   *  exitDone: 'my-done-exit',\n   * }}\n   * ```\n   *\n   * If you want to set these classes using CSS Modules:\n   *\n   * ```js\n   * import styles from './styles.css';\n   * ```\n   *\n   * you might want to use camelCase in your CSS file, that way could simply\n   * spread them instead of listing them one by one:\n   *\n   * ```js\n   * classNames={{ ...styles }}\n   * ```\n   *\n   * @type {string | {\n   *  appear?: string,\n   *  appearActive?: string,\n   *  appearDone?: string,\n   *  enter?: string,\n   *  enterActive?: string,\n   *  enterDone?: string,\n   *  exit?: string,\n   *  exitActive?: string,\n   *  exitDone?: string,\n   * }}\n   */\n  classNames: classNamesShape,\n\n  /**\n   * A `<Transition>` callback fired immediately after the 'enter' or 'appear' class is\n   * applied.\n   *\n   * **Note**: when `nodeRef` prop is passed, `node` is not passed, so `isAppearing` is being passed as the first argument.\n   *\n   * @type Function(node: HtmlElement, isAppearing: bool)\n   */\n  onEnter: PropTypes.func,\n\n  /**\n   * A `<Transition>` callback fired immediately after the 'enter-active' or\n   * 'appear-active' class is applied.\n   *\n   * **Note**: when `nodeRef` prop is passed, `node` is not passed, so `isAppearing` is being passed as the first argument.\n   *\n   * @type Function(node: HtmlElement, isAppearing: bool)\n   */\n  onEntering: PropTypes.func,\n\n  /**\n   * A `<Transition>` callback fired immediately after the 'enter' or\n   * 'appear' classes are **removed** and the `done` class is added to the DOM node.\n   *\n   * **Note**: when `nodeRef` prop is passed, `node` is not passed, so `isAppearing` is being passed as the first argument.\n   *\n   * @type Function(node: HtmlElement, isAppearing: bool)\n   */\n  onEntered: PropTypes.func,\n\n  /**\n   * A `<Transition>` callback fired immediately after the 'exit' class is\n   * applied.\n   *\n   * **Note**: when `nodeRef` prop is passed, `node` is not passed\n   *\n   * @type Function(node: HtmlElement)\n   */\n  onExit: PropTypes.func,\n\n  /**\n   * A `<Transition>` callback fired immediately after the 'exit-active' is applied.\n   *\n   * **Note**: when `nodeRef` prop is passed, `node` is not passed\n   *\n   * @type Function(node: HtmlElement)\n   */\n  onExiting: PropTypes.func,\n\n  /**\n   * A `<Transition>` callback fired immediately after the 'exit' classes\n   * are **removed** and the `exit-done` class is added to the DOM node.\n   *\n   * **Note**: when `nodeRef` prop is passed, `node` is not passed\n   *\n   * @type Function(node: HtmlElement)\n   */\n  onExited: PropTypes.func,\n};\n\nexport default CSSTransition;\n"
  },
  {
    "path": "src/ReplaceTransition.js",
    "content": "import PropTypes from 'prop-types';\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport TransitionGroup from './TransitionGroup';\n\n/**\n * The `<ReplaceTransition>` component is a specialized `Transition` component\n * that animates between two children.\n *\n * ```jsx\n * <ReplaceTransition in>\n *   <Fade><div>I appear first</div></Fade>\n *   <Fade><div>I replace the above</div></Fade>\n * </ReplaceTransition>\n * ```\n */\nclass ReplaceTransition extends React.Component {\n  handleEnter = (...args) => this.handleLifecycle('onEnter', 0, args);\n  handleEntering = (...args) => this.handleLifecycle('onEntering', 0, args);\n  handleEntered = (...args) => this.handleLifecycle('onEntered', 0, args);\n\n  handleExit = (...args) => this.handleLifecycle('onExit', 1, args);\n  handleExiting = (...args) => this.handleLifecycle('onExiting', 1, args);\n  handleExited = (...args) => this.handleLifecycle('onExited', 1, args);\n\n  handleLifecycle(handler, idx, originalArgs) {\n    const { children } = this.props;\n    const child = React.Children.toArray(children)[idx];\n\n    if (child.props[handler]) child.props[handler](...originalArgs);\n    if (this.props[handler]) {\n      const maybeNode = child.props.nodeRef\n        ? undefined\n        : ReactDOM.findDOMNode(this);\n\n      this.props[handler](maybeNode);\n    }\n  }\n\n  render() {\n    const { children, in: inProp, ...props } = this.props;\n    const [first, second] = React.Children.toArray(children);\n\n    delete props.onEnter;\n    delete props.onEntering;\n    delete props.onEntered;\n    delete props.onExit;\n    delete props.onExiting;\n    delete props.onExited;\n\n    return (\n      <TransitionGroup {...props}>\n        {inProp\n          ? React.cloneElement(first, {\n              key: 'first',\n              onEnter: this.handleEnter,\n              onEntering: this.handleEntering,\n              onEntered: this.handleEntered,\n            })\n          : React.cloneElement(second, {\n              key: 'second',\n              onEnter: this.handleExit,\n              onEntering: this.handleExiting,\n              onEntered: this.handleExited,\n            })}\n      </TransitionGroup>\n    );\n  }\n}\n\nReplaceTransition.propTypes = {\n  in: PropTypes.bool.isRequired,\n  children(props, propName) {\n    if (React.Children.count(props[propName]) !== 2)\n      return new Error(\n        `\"${propName}\" must be exactly two transition components.`\n      );\n\n    return null;\n  },\n};\n\nexport default ReplaceTransition;\n"
  },
  {
    "path": "src/SwitchTransition.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { ENTERED, ENTERING, EXITING } from './Transition';\nimport TransitionGroupContext from './TransitionGroupContext';\n\nfunction areChildrenDifferent(oldChildren, newChildren) {\n  if (oldChildren === newChildren) return false;\n  if (\n    React.isValidElement(oldChildren) &&\n    React.isValidElement(newChildren) &&\n    oldChildren.key != null &&\n    oldChildren.key === newChildren.key\n  ) {\n    return false;\n  }\n  return true;\n}\n\n/**\n * Enum of modes for SwitchTransition component\n * @enum { string }\n */\nexport const modes = {\n  out: 'out-in',\n  in: 'in-out',\n};\n\nconst callHook =\n  (element, name, cb) =>\n  (...args) => {\n    element.props[name] && element.props[name](...args);\n    cb();\n  };\n\nconst leaveRenders = {\n  [modes.out]: ({ current, changeState }) =>\n    React.cloneElement(current, {\n      in: false,\n      onExited: callHook(current, 'onExited', () => {\n        changeState(ENTERING, null);\n      }),\n    }),\n  [modes.in]: ({ current, changeState, children }) => [\n    current,\n    React.cloneElement(children, {\n      in: true,\n      onEntered: callHook(children, 'onEntered', () => {\n        changeState(ENTERING);\n      }),\n    }),\n  ],\n};\n\nconst enterRenders = {\n  [modes.out]: ({ children, changeState }) =>\n    React.cloneElement(children, {\n      in: true,\n      onEntered: callHook(children, 'onEntered', () => {\n        changeState(ENTERED, React.cloneElement(children, { in: true }));\n      }),\n    }),\n  [modes.in]: ({ current, children, changeState }) => [\n    React.cloneElement(current, {\n      in: false,\n      onExited: callHook(current, 'onExited', () => {\n        changeState(ENTERED, React.cloneElement(children, { in: true }));\n      }),\n    }),\n    React.cloneElement(children, {\n      in: true,\n    }),\n  ],\n};\n\n/**\n * A transition component inspired by the [vue transition modes](https://vuejs.org/v2/guide/transitions.html#Transition-Modes).\n * You can use it when you want to control the render between state transitions.\n * Based on the selected mode and the child's key which is the `Transition` or `CSSTransition` component, the `SwitchTransition` makes a consistent transition between them.\n *\n * If the `out-in` mode is selected, the `SwitchTransition` waits until the old child leaves and then inserts a new child.\n * If the `in-out` mode is selected, the `SwitchTransition` inserts a new child first, waits for the new child to enter and then removes the old child.\n *\n * **Note**: If you want the animation to happen simultaneously\n * (that is, to have the old child removed and a new child inserted **at the same time**),\n * you should use\n * [`TransitionGroup`](https://reactcommunity.org/react-transition-group/transition-group)\n * instead.\n *\n * ```jsx\n * function App() {\n *  const [state, setState] = useState(false);\n *  const helloRef = useRef(null);\n *  const goodbyeRef = useRef(null);\n *  const nodeRef = state ? goodbyeRef : helloRef;\n *  return (\n *    <SwitchTransition>\n *      <CSSTransition\n *        key={state ? \"Goodbye, world!\" : \"Hello, world!\"}\n *        nodeRef={nodeRef}\n *        addEndListener={(node, done) => node.addEventListener(\"transitionend\", done, false)}\n *        classNames='fade'\n *      >\n *        <button ref={nodeRef} onClick={() => setState(state => !state)}>\n *          {state ? \"Goodbye, world!\" : \"Hello, world!\"}\n *        </button>\n *      </CSSTransition>\n *    </SwitchTransition>\n *  );\n * }\n * ```\n *\n * ```css\n * .fade-enter{\n *    opacity: 0;\n * }\n * .fade-exit{\n *    opacity: 1;\n * }\n * .fade-enter-active{\n *    opacity: 1;\n * }\n * .fade-exit-active{\n *    opacity: 0;\n * }\n * .fade-enter-active,\n * .fade-exit-active{\n *    transition: opacity 500ms;\n * }\n * ```\n */\nclass SwitchTransition extends React.Component {\n  state = {\n    status: ENTERED,\n    current: null,\n  };\n\n  appeared = false;\n\n  componentDidMount() {\n    this.appeared = true;\n  }\n\n  static getDerivedStateFromProps(props, state) {\n    if (props.children == null) {\n      return {\n        current: null,\n      };\n    }\n\n    if (state.status === ENTERING && props.mode === modes.in) {\n      return {\n        status: ENTERING,\n      };\n    }\n\n    if (state.current && areChildrenDifferent(state.current, props.children)) {\n      return {\n        status: EXITING,\n      };\n    }\n\n    return {\n      current: React.cloneElement(props.children, {\n        in: true,\n      }),\n    };\n  }\n\n  changeState = (status, current = this.state.current) => {\n    this.setState({\n      status,\n      current,\n    });\n  };\n\n  render() {\n    const {\n      props: { children, mode },\n      state: { status, current },\n    } = this;\n\n    const data = { children, current, changeState: this.changeState, status };\n    let component;\n    switch (status) {\n      case ENTERING:\n        component = enterRenders[mode](data);\n        break;\n      case EXITING:\n        component = leaveRenders[mode](data);\n        break;\n      case ENTERED:\n        component = current;\n    }\n\n    return (\n      <TransitionGroupContext.Provider value={{ isMounting: !this.appeared }}>\n        {component}\n      </TransitionGroupContext.Provider>\n    );\n  }\n}\n\nSwitchTransition.propTypes = {\n  /**\n   * Transition modes.\n   * `out-in`: Current element transitions out first, then when complete, the new element transitions in.\n   * `in-out`: New element transitions in first, then when complete, the current element transitions out.\n   *\n   * @type {'out-in'|'in-out'}\n   */\n  mode: PropTypes.oneOf([modes.in, modes.out]),\n  /**\n   * Any `Transition` or `CSSTransition` component.\n   */\n  children: PropTypes.oneOfType([PropTypes.element.isRequired]),\n};\n\nSwitchTransition.defaultProps = {\n  mode: modes.out,\n};\n\nexport default SwitchTransition;\n"
  },
  {
    "path": "src/Transition.js",
    "content": "import PropTypes from 'prop-types';\nimport React from 'react';\nimport ReactDOM from 'react-dom';\n\nimport config from './config';\nimport { timeoutsShape } from './utils/PropTypes';\nimport TransitionGroupContext from './TransitionGroupContext';\nimport { forceReflow } from './utils/reflow';\n\nexport const UNMOUNTED = 'unmounted';\nexport const EXITED = 'exited';\nexport const ENTERING = 'entering';\nexport const ENTERED = 'entered';\nexport const EXITING = 'exiting';\n\n/**\n * The Transition component lets you describe a transition from one component\n * state to another _over time_ with a simple declarative API. Most commonly\n * it's used to animate the mounting and unmounting of a component, but can also\n * be used to describe in-place transition states as well.\n *\n * ---\n *\n * **Note**: `Transition` is a platform-agnostic base component. If you're using\n * transitions in CSS, you'll probably want to use\n * [`CSSTransition`](https://reactcommunity.org/react-transition-group/css-transition)\n * instead. It inherits all the features of `Transition`, but contains\n * additional features necessary to play nice with CSS transitions (hence the\n * name of the component).\n *\n * ---\n *\n * By default the `Transition` component does not alter the behavior of the\n * component it renders, it only tracks \"enter\" and \"exit\" states for the\n * components. It's up to you to give meaning and effect to those states. For\n * example we can add styles to a component when it enters or exits:\n *\n * ```jsx\n * import { Transition } from 'react-transition-group';\n * import { useRef } from 'react';\n *\n * const duration = 300;\n *\n * const defaultStyle = {\n *   transition: `opacity ${duration}ms ease-in-out`,\n *   opacity: 0,\n * }\n *\n * const transitionStyles = {\n *   entering: { opacity: 1 },\n *   entered:  { opacity: 1 },\n *   exiting:  { opacity: 0 },\n *   exited:  { opacity: 0 },\n * };\n *\n * function Fade({ in: inProp }) {\n *   const nodeRef = useRef(null);\n *   return (\n *     <Transition nodeRef={nodeRef} in={inProp} timeout={duration}>\n *       {state => (\n *         <div ref={nodeRef} style={{\n *           ...defaultStyle,\n *           ...transitionStyles[state]\n *         }}>\n *           I'm a fade Transition!\n *         </div>\n *       )}\n *     </Transition>\n *   );\n * }\n * ```\n *\n * There are 4 main states a Transition can be in:\n *  - `'entering'`\n *  - `'entered'`\n *  - `'exiting'`\n *  - `'exited'`\n *\n * Transition state is toggled via the `in` prop. When `true` the component\n * begins the \"Enter\" stage. During this stage, the component will shift from\n * its current transition state, to `'entering'` for the duration of the\n * transition and then to the `'entered'` stage once it's complete. Let's take\n * the following example (we'll use the\n * [useState](https://reactjs.org/docs/hooks-reference.html#usestate) hook):\n *\n * ```jsx\n * import { Transition } from 'react-transition-group';\n * import { useState, useRef } from 'react';\n *\n * function App() {\n *   const [inProp, setInProp] = useState(false);\n *   const nodeRef = useRef(null);\n *   return (\n *     <div>\n *       <Transition nodeRef={nodeRef} in={inProp} timeout={500}>\n *         {state => (\n *           // ...\n *         )}\n *       </Transition>\n *       <button onClick={() => setInProp(true)}>\n *         Click to Enter\n *       </button>\n *     </div>\n *   );\n * }\n * ```\n *\n * When the button is clicked the component will shift to the `'entering'` state\n * and stay there for 500ms (the value of `timeout`) before it finally switches\n * to `'entered'`.\n *\n * When `in` is `false` the same thing happens except the state moves from\n * `'exiting'` to `'exited'`.\n */\nclass Transition extends React.Component {\n  static contextType = TransitionGroupContext;\n\n  constructor(props, context) {\n    super(props, context);\n\n    let parentGroup = context;\n    // In the context of a TransitionGroup all enters are really appears\n    let appear =\n      parentGroup && !parentGroup.isMounting ? props.enter : props.appear;\n\n    let initialStatus;\n\n    this.appearStatus = null;\n\n    if (props.in) {\n      if (appear) {\n        initialStatus = EXITED;\n        this.appearStatus = ENTERING;\n      } else {\n        initialStatus = ENTERED;\n      }\n    } else {\n      if (props.unmountOnExit || props.mountOnEnter) {\n        initialStatus = UNMOUNTED;\n      } else {\n        initialStatus = EXITED;\n      }\n    }\n\n    this.state = { status: initialStatus };\n\n    this.nextCallback = null;\n  }\n\n  static getDerivedStateFromProps({ in: nextIn }, prevState) {\n    if (nextIn && prevState.status === UNMOUNTED) {\n      return { status: EXITED };\n    }\n    return null;\n  }\n\n  // getSnapshotBeforeUpdate(prevProps) {\n  //   let nextStatus = null\n\n  //   if (prevProps !== this.props) {\n  //     const { status } = this.state\n\n  //     if (this.props.in) {\n  //       if (status !== ENTERING && status !== ENTERED) {\n  //         nextStatus = ENTERING\n  //       }\n  //     } else {\n  //       if (status === ENTERING || status === ENTERED) {\n  //         nextStatus = EXITING\n  //       }\n  //     }\n  //   }\n\n  //   return { nextStatus }\n  // }\n\n  componentDidMount() {\n    this.updateStatus(true, this.appearStatus);\n  }\n\n  componentDidUpdate(prevProps) {\n    let nextStatus = null;\n    if (prevProps !== this.props) {\n      const { status } = this.state;\n\n      if (this.props.in) {\n        if (status !== ENTERING && status !== ENTERED) {\n          nextStatus = ENTERING;\n        }\n      } else {\n        if (status === ENTERING || status === ENTERED) {\n          nextStatus = EXITING;\n        }\n      }\n    }\n    this.updateStatus(false, nextStatus);\n  }\n\n  componentWillUnmount() {\n    this.cancelNextCallback();\n  }\n\n  getTimeouts() {\n    const { timeout } = this.props;\n    let exit, enter, appear;\n\n    exit = enter = appear = timeout;\n\n    if (timeout != null && typeof timeout !== 'number') {\n      exit = timeout.exit;\n      enter = timeout.enter;\n      // TODO: remove fallback for next major\n      appear = timeout.appear !== undefined ? timeout.appear : enter;\n    }\n    return { exit, enter, appear };\n  }\n\n  updateStatus(mounting = false, nextStatus) {\n    if (nextStatus !== null) {\n      // nextStatus will always be ENTERING or EXITING.\n      this.cancelNextCallback();\n\n      if (nextStatus === ENTERING) {\n        if (this.props.unmountOnExit || this.props.mountOnEnter) {\n          const node = this.props.nodeRef\n            ? this.props.nodeRef.current\n            : ReactDOM.findDOMNode(this);\n          // https://github.com/reactjs/react-transition-group/pull/749\n          // With unmountOnExit or mountOnEnter, the enter animation should happen at the transition between `exited` and `entering`.\n          // To make the animation happen,  we have to separate each rendering and avoid being processed as batched.\n          if (node) forceReflow(node);\n        }\n        this.performEnter(mounting);\n      } else {\n        this.performExit();\n      }\n    } else if (this.props.unmountOnExit && this.state.status === EXITED) {\n      this.setState({ status: UNMOUNTED });\n    }\n  }\n\n  performEnter(mounting) {\n    const { enter } = this.props;\n    const appearing = this.context ? this.context.isMounting : mounting;\n    const [maybeNode, maybeAppearing] = this.props.nodeRef\n      ? [appearing]\n      : [ReactDOM.findDOMNode(this), appearing];\n\n    const timeouts = this.getTimeouts();\n    const enterTimeout = appearing ? timeouts.appear : timeouts.enter;\n    // no enter animation skip right to ENTERED\n    // if we are mounting and running this it means appear _must_ be set\n    if ((!mounting && !enter) || config.disabled) {\n      this.safeSetState({ status: ENTERED }, () => {\n        this.props.onEntered(maybeNode);\n      });\n      return;\n    }\n\n    this.props.onEnter(maybeNode, maybeAppearing);\n\n    this.safeSetState({ status: ENTERING }, () => {\n      this.props.onEntering(maybeNode, maybeAppearing);\n\n      this.onTransitionEnd(enterTimeout, () => {\n        this.safeSetState({ status: ENTERED }, () => {\n          this.props.onEntered(maybeNode, maybeAppearing);\n        });\n      });\n    });\n  }\n\n  performExit() {\n    const { exit } = this.props;\n    const timeouts = this.getTimeouts();\n    const maybeNode = this.props.nodeRef\n      ? undefined\n      : ReactDOM.findDOMNode(this);\n\n    // no exit animation skip right to EXITED\n    if (!exit || config.disabled) {\n      this.safeSetState({ status: EXITED }, () => {\n        this.props.onExited(maybeNode);\n      });\n      return;\n    }\n\n    this.props.onExit(maybeNode);\n\n    this.safeSetState({ status: EXITING }, () => {\n      this.props.onExiting(maybeNode);\n\n      this.onTransitionEnd(timeouts.exit, () => {\n        this.safeSetState({ status: EXITED }, () => {\n          this.props.onExited(maybeNode);\n        });\n      });\n    });\n  }\n\n  cancelNextCallback() {\n    if (this.nextCallback !== null) {\n      this.nextCallback.cancel();\n      this.nextCallback = null;\n    }\n  }\n\n  safeSetState(nextState, callback) {\n    // This shouldn't be necessary, but there are weird race conditions with\n    // setState callbacks and unmounting in testing, so always make sure that\n    // we can cancel any pending setState callbacks after we unmount.\n    callback = this.setNextCallback(callback);\n    this.setState(nextState, callback);\n  }\n\n  setNextCallback(callback) {\n    let active = true;\n\n    this.nextCallback = (event) => {\n      if (active) {\n        active = false;\n        this.nextCallback = null;\n\n        callback(event);\n      }\n    };\n\n    this.nextCallback.cancel = () => {\n      active = false;\n    };\n\n    return this.nextCallback;\n  }\n\n  onTransitionEnd(timeout, handler) {\n    this.setNextCallback(handler);\n    const node = this.props.nodeRef\n      ? this.props.nodeRef.current\n      : ReactDOM.findDOMNode(this);\n\n    const doesNotHaveTimeoutOrListener =\n      timeout == null && !this.props.addEndListener;\n    if (!node || doesNotHaveTimeoutOrListener) {\n      setTimeout(this.nextCallback, 0);\n      return;\n    }\n\n    if (this.props.addEndListener) {\n      const [maybeNode, maybeNextCallback] = this.props.nodeRef\n        ? [this.nextCallback]\n        : [node, this.nextCallback];\n      this.props.addEndListener(maybeNode, maybeNextCallback);\n    }\n\n    if (timeout != null) {\n      setTimeout(this.nextCallback, timeout);\n    }\n  }\n\n  render() {\n    const status = this.state.status;\n\n    if (status === UNMOUNTED) {\n      return null;\n    }\n\n    const {\n      children,\n      // filter props for `Transition`\n      in: _in,\n      mountOnEnter: _mountOnEnter,\n      unmountOnExit: _unmountOnExit,\n      appear: _appear,\n      enter: _enter,\n      exit: _exit,\n      timeout: _timeout,\n      addEndListener: _addEndListener,\n      onEnter: _onEnter,\n      onEntering: _onEntering,\n      onEntered: _onEntered,\n      onExit: _onExit,\n      onExiting: _onExiting,\n      onExited: _onExited,\n      nodeRef: _nodeRef,\n      ...childProps\n    } = this.props;\n\n    return (\n      // allows for nested Transitions\n      <TransitionGroupContext.Provider value={null}>\n        {typeof children === 'function'\n          ? children(status, childProps)\n          : React.cloneElement(React.Children.only(children), childProps)}\n      </TransitionGroupContext.Provider>\n    );\n  }\n}\n\nTransition.propTypes = {\n  /**\n   * A React reference to the DOM element that needs to transition:\n   * https://stackoverflow.com/a/51127130/4671932\n   *\n   *   - This prop is optional, but recommended in order to avoid defaulting to\n   *      [`ReactDOM.findDOMNode`](https://reactjs.org/docs/react-dom.html#finddomnode),\n   *      which is deprecated in `StrictMode`\n   *   - When `nodeRef` prop is used, `node` is not passed to callback functions\n   *      (e.g. `onEnter`) because user already has direct access to the node.\n   *   - When changing `key` prop of `Transition` in a `TransitionGroup` a new\n   *     `nodeRef` need to be provided to `Transition` with changed `key` prop\n   *     (see\n   *     [test/CSSTransition-test.js](https://github.com/reactjs/react-transition-group/blob/13435f897b3ab71f6e19d724f145596f5910581c/test/CSSTransition-test.js#L362-L437)).\n   */\n  nodeRef: PropTypes.shape({\n    current:\n      typeof Element === 'undefined'\n        ? PropTypes.any\n        : (propValue, key, componentName, location, propFullName, secret) => {\n            const value = propValue[key];\n\n            return PropTypes.instanceOf(\n              value && 'ownerDocument' in value\n                ? value.ownerDocument.defaultView.Element\n                : Element\n            )(propValue, key, componentName, location, propFullName, secret);\n          },\n  }),\n\n  /**\n   * A `function` child can be used instead of a React element. This function is\n   * called with the current transition status (`'entering'`, `'entered'`,\n   * `'exiting'`, `'exited'`), which can be used to apply context\n   * specific props to a component.\n   *\n   * ```jsx\n   * <Transition nodeRef={nodeRef} in={this.state.in} timeout={150}>\n   *   {state => (\n   *     <MyComponent ref={nodeRef} className={`fade fade-${state}`} />\n   *   )}\n   * </Transition>\n   * ```\n   */\n  children: PropTypes.oneOfType([\n    PropTypes.func.isRequired,\n    PropTypes.element.isRequired,\n  ]).isRequired,\n\n  /**\n   * Show the component; triggers the enter or exit states\n   */\n  in: PropTypes.bool,\n\n  /**\n   * By default the child component is mounted immediately along with\n   * the parent `Transition` component. If you want to \"lazy mount\" the component on the\n   * first `in={true}` you can set `mountOnEnter`. After the first enter transition the component will stay\n   * mounted, even on \"exited\", unless you also specify `unmountOnExit`.\n   */\n  mountOnEnter: PropTypes.bool,\n\n  /**\n   * By default the child component stays mounted after it reaches the `'exited'` state.\n   * Set `unmountOnExit` if you'd prefer to unmount the component after it finishes exiting.\n   */\n  unmountOnExit: PropTypes.bool,\n\n  /**\n   * By default the child component does not perform the enter transition when\n   * it first mounts, regardless of the value of `in`. If you want this\n   * behavior, set both `appear` and `in` to `true`.\n   *\n   * > **Note**: there are no special appear states like `appearing`/`appeared`, this prop\n   * > only adds an additional enter transition. However, in the\n   * > `<CSSTransition>` component that first enter transition does result in\n   * > additional `.appear-*` classes, that way you can choose to style it\n   * > differently.\n   */\n  appear: PropTypes.bool,\n\n  /**\n   * Enable or disable enter transitions.\n   */\n  enter: PropTypes.bool,\n\n  /**\n   * Enable or disable exit transitions.\n   */\n  exit: PropTypes.bool,\n\n  /**\n   * The duration of the transition, in milliseconds.\n   * Required unless `addEndListener` is provided.\n   *\n   * You may specify a single timeout for all transitions:\n   *\n   * ```jsx\n   * timeout={500}\n   * ```\n   *\n   * or individually:\n   *\n   * ```jsx\n   * timeout={{\n   *  appear: 500,\n   *  enter: 300,\n   *  exit: 500,\n   * }}\n   * ```\n   *\n   * - `appear` defaults to the value of `enter`\n   * - `enter` defaults to `0`\n   * - `exit` defaults to `0`\n   *\n   * @type {number | { enter?: number, exit?: number, appear?: number }}\n   */\n  timeout: (props, ...args) => {\n    let pt = timeoutsShape;\n    if (!props.addEndListener) pt = pt.isRequired;\n    return pt(props, ...args);\n  },\n\n  /**\n   * Add a custom transition end trigger. Called with the transitioning\n   * DOM node and a `done` callback. Allows for more fine grained transition end\n   * logic. Timeouts are still used as a fallback if provided.\n   *\n   * **Note**: when `nodeRef` prop is passed, `node` is not passed, so `done` is being passed as the first argument.\n   *\n   * ```jsx\n   * addEndListener={(node, done) => {\n   *   // use the css transitionend event to mark the finish of a transition\n   *   node.addEventListener('transitionend', done, false);\n   * }}\n   * ```\n   */\n  addEndListener: PropTypes.func,\n\n  /**\n   * Callback fired before the \"entering\" status is applied. An extra parameter\n   * `isAppearing` is supplied to indicate if the enter stage is occurring on the initial mount\n   *\n   * **Note**: when `nodeRef` prop is passed, `node` is not passed, so `isAppearing` is being passed as the first argument.\n   *\n   * @type Function(node: HtmlElement, isAppearing: bool) -> void\n   */\n  onEnter: PropTypes.func,\n\n  /**\n   * Callback fired after the \"entering\" status is applied. An extra parameter\n   * `isAppearing` is supplied to indicate if the enter stage is occurring on the initial mount\n   *\n   * **Note**: when `nodeRef` prop is passed, `node` is not passed, so `isAppearing` is being passed as the first argument.\n   *\n   * @type Function(node: HtmlElement, isAppearing: bool)\n   */\n  onEntering: PropTypes.func,\n\n  /**\n   * Callback fired after the \"entered\" status is applied. An extra parameter\n   * `isAppearing` is supplied to indicate if the enter stage is occurring on the initial mount\n   *\n   * **Note**: when `nodeRef` prop is passed, `node` is not passed, so `isAppearing` is being passed as the first argument.\n   *\n   * @type Function(node: HtmlElement, isAppearing: bool) -> void\n   */\n  onEntered: PropTypes.func,\n\n  /**\n   * Callback fired before the \"exiting\" status is applied.\n   *\n   * **Note**: when `nodeRef` prop is passed, `node` is not passed.\n   *\n   * @type Function(node: HtmlElement) -> void\n   */\n  onExit: PropTypes.func,\n\n  /**\n   * Callback fired after the \"exiting\" status is applied.\n   *\n   * **Note**: when `nodeRef` prop is passed, `node` is not passed.\n   *\n   * @type Function(node: HtmlElement) -> void\n   */\n  onExiting: PropTypes.func,\n\n  /**\n   * Callback fired after the \"exited\" status is applied.\n   *\n   * **Note**: when `nodeRef` prop is passed, `node` is not passed\n   *\n   * @type Function(node: HtmlElement) -> void\n   */\n  onExited: PropTypes.func,\n};\n\n// Name the function so it is clearer in the documentation\nfunction noop() {}\n\nTransition.defaultProps = {\n  in: false,\n  mountOnEnter: false,\n  unmountOnExit: false,\n  appear: false,\n  enter: true,\n  exit: true,\n\n  onEnter: noop,\n  onEntering: noop,\n  onEntered: noop,\n\n  onExit: noop,\n  onExiting: noop,\n  onExited: noop,\n};\n\nTransition.UNMOUNTED = UNMOUNTED;\nTransition.EXITED = EXITED;\nTransition.ENTERING = ENTERING;\nTransition.ENTERED = ENTERED;\nTransition.EXITING = EXITING;\n\nexport default Transition;\n"
  },
  {
    "path": "src/TransitionGroup.js",
    "content": "import PropTypes from 'prop-types';\nimport React from 'react';\nimport TransitionGroupContext from './TransitionGroupContext';\n\nimport {\n  getChildMapping,\n  getInitialChildMapping,\n  getNextChildMapping,\n} from './utils/ChildMapping';\n\nconst values = Object.values || ((obj) => Object.keys(obj).map((k) => obj[k]));\n\nconst defaultProps = {\n  component: 'div',\n  childFactory: (child) => child,\n};\n\n/**\n * The `<TransitionGroup>` component manages a set of transition components\n * (`<Transition>` and `<CSSTransition>`) in a list. Like with the transition\n * components, `<TransitionGroup>` is a state machine for managing the mounting\n * and unmounting of components over time.\n *\n * Consider the example below. As items are removed or added to the TodoList the\n * `in` prop is toggled automatically by the `<TransitionGroup>`.\n *\n * Note that `<TransitionGroup>`  does not define any animation behavior!\n * Exactly _how_ a list item animates is up to the individual transition\n * component. This means you can mix and match animations across different list\n * items.\n */\nclass TransitionGroup extends React.Component {\n  constructor(props, context) {\n    super(props, context);\n\n    const handleExited = this.handleExited.bind(this);\n\n    // Initial children should all be entering, dependent on appear\n    this.state = {\n      contextValue: { isMounting: true },\n      handleExited,\n      firstRender: true,\n    };\n  }\n\n  componentDidMount() {\n    this.mounted = true;\n    this.setState({\n      contextValue: { isMounting: false },\n    });\n  }\n\n  componentWillUnmount() {\n    this.mounted = false;\n  }\n\n  static getDerivedStateFromProps(\n    nextProps,\n    { children: prevChildMapping, handleExited, firstRender }\n  ) {\n    return {\n      children: firstRender\n        ? getInitialChildMapping(nextProps, handleExited)\n        : getNextChildMapping(nextProps, prevChildMapping, handleExited),\n      firstRender: false,\n    };\n  }\n\n  // node is `undefined` when user provided `nodeRef` prop\n  handleExited(child, node) {\n    let currentChildMapping = getChildMapping(this.props.children);\n\n    if (child.key in currentChildMapping) return;\n\n    if (child.props.onExited) {\n      child.props.onExited(node);\n    }\n\n    if (this.mounted) {\n      this.setState((state) => {\n        let children = { ...state.children };\n\n        delete children[child.key];\n        return { children };\n      });\n    }\n  }\n\n  render() {\n    const { component: Component, childFactory, ...props } = this.props;\n    const { contextValue } = this.state;\n    const children = values(this.state.children).map(childFactory);\n\n    delete props.appear;\n    delete props.enter;\n    delete props.exit;\n\n    if (Component === null) {\n      return (\n        <TransitionGroupContext.Provider value={contextValue}>\n          {children}\n        </TransitionGroupContext.Provider>\n      );\n    }\n    return (\n      <TransitionGroupContext.Provider value={contextValue}>\n        <Component {...props}>{children}</Component>\n      </TransitionGroupContext.Provider>\n    );\n  }\n}\n\nTransitionGroup.propTypes = {\n  /**\n   * `<TransitionGroup>` renders a `<div>` by default. You can change this\n   * behavior by providing a `component` prop.\n   * If you use React v16+ and would like to avoid a wrapping `<div>` element\n   * you can pass in `component={null}`. This is useful if the wrapping div\n   * borks your css styles.\n   */\n  component: PropTypes.any,\n  /**\n   * A set of `<Transition>` components, that are toggled `in` and out as they\n   * leave. the `<TransitionGroup>` will inject specific transition props, so\n   * remember to spread them through if you are wrapping the `<Transition>` as\n   * with our `<Fade>` example.\n   *\n   * While this component is meant for multiple `Transition` or `CSSTransition`\n   * children, sometimes you may want to have a single transition child with\n   * content that you want to be transitioned out and in when you change it\n   * (e.g. routes, images etc.) In that case you can change the `key` prop of\n   * the transition child as you change its content, this will cause\n   * `TransitionGroup` to transition the child out and back in.\n   */\n  children: PropTypes.node,\n\n  /**\n   * A convenience prop that enables or disables appear animations\n   * for all children. Note that specifying this will override any defaults set\n   * on individual children Transitions.\n   */\n  appear: PropTypes.bool,\n  /**\n   * A convenience prop that enables or disables enter animations\n   * for all children. Note that specifying this will override any defaults set\n   * on individual children Transitions.\n   */\n  enter: PropTypes.bool,\n  /**\n   * A convenience prop that enables or disables exit animations\n   * for all children. Note that specifying this will override any defaults set\n   * on individual children Transitions.\n   */\n  exit: PropTypes.bool,\n\n  /**\n   * You may need to apply reactive updates to a child as it is exiting.\n   * This is generally done by using `cloneElement` however in the case of an exiting\n   * child the element has already been removed and not accessible to the consumer.\n   *\n   * If you do need to update a child as it leaves you can provide a `childFactory`\n   * to wrap every child, even the ones that are leaving.\n   *\n   * @type Function(child: ReactElement) -> ReactElement\n   */\n  childFactory: PropTypes.func,\n};\n\nTransitionGroup.defaultProps = defaultProps;\n\nexport default TransitionGroup;\n"
  },
  {
    "path": "src/TransitionGroupContext.js",
    "content": "import React from 'react';\n\nexport default React.createContext(null);\n"
  },
  {
    "path": "src/config.js",
    "content": "export default {\n  disabled: false,\n};\n"
  },
  {
    "path": "src/index.js",
    "content": "export { default as CSSTransition } from './CSSTransition';\nexport { default as ReplaceTransition } from './ReplaceTransition';\nexport { default as SwitchTransition } from './SwitchTransition';\nexport { default as TransitionGroup } from './TransitionGroup';\nexport { default as Transition } from './Transition';\nexport { default as config } from './config';\n"
  },
  {
    "path": "src/utils/ChildMapping.js",
    "content": "import { Children, cloneElement, isValidElement } from 'react';\n\n/**\n * Given `this.props.children`, return an object mapping key to child.\n *\n * @param {*} children `this.props.children`\n * @return {object} Mapping of key to child\n */\nexport function getChildMapping(children, mapFn) {\n  let mapper = (child) =>\n    mapFn && isValidElement(child) ? mapFn(child) : child;\n\n  let result = Object.create(null);\n  if (children)\n    Children.map(children, (c) => c).forEach((child) => {\n      // run the map function here instead so that the key is the computed one\n      result[child.key] = mapper(child);\n    });\n  return result;\n}\n\n/**\n * When you're adding or removing children some may be added or removed in the\n * same render pass. We want to show *both* since we want to simultaneously\n * animate elements in and out. This function takes a previous set of keys\n * and a new set of keys and merges them with its best guess of the correct\n * ordering. In the future we may expose some of the utilities in\n * ReactMultiChild to make this easy, but for now React itself does not\n * directly have this concept of the union of prevChildren and nextChildren\n * so we implement it here.\n *\n * @param {object} prev prev children as returned from\n * `ReactTransitionChildMapping.getChildMapping()`.\n * @param {object} next next children as returned from\n * `ReactTransitionChildMapping.getChildMapping()`.\n * @return {object} a key set that contains all keys in `prev` and all keys\n * in `next` in a reasonable order.\n */\nexport function mergeChildMappings(prev, next) {\n  prev = prev || {};\n  next = next || {};\n\n  function getValueForKey(key) {\n    return key in next ? next[key] : prev[key];\n  }\n\n  // For each key of `next`, the list of keys to insert before that key in\n  // the combined list\n  let nextKeysPending = Object.create(null);\n\n  let pendingKeys = [];\n  for (let prevKey in prev) {\n    if (prevKey in next) {\n      if (pendingKeys.length) {\n        nextKeysPending[prevKey] = pendingKeys;\n        pendingKeys = [];\n      }\n    } else {\n      pendingKeys.push(prevKey);\n    }\n  }\n\n  let i;\n  let childMapping = {};\n  for (let nextKey in next) {\n    if (nextKeysPending[nextKey]) {\n      for (i = 0; i < nextKeysPending[nextKey].length; i++) {\n        let pendingNextKey = nextKeysPending[nextKey][i];\n        childMapping[nextKeysPending[nextKey][i]] =\n          getValueForKey(pendingNextKey);\n      }\n    }\n    childMapping[nextKey] = getValueForKey(nextKey);\n  }\n\n  // Finally, add the keys which didn't appear before any key in `next`\n  for (i = 0; i < pendingKeys.length; i++) {\n    childMapping[pendingKeys[i]] = getValueForKey(pendingKeys[i]);\n  }\n\n  return childMapping;\n}\n\nfunction getProp(child, prop, props) {\n  return props[prop] != null ? props[prop] : child.props[prop];\n}\n\nexport function getInitialChildMapping(props, onExited) {\n  return getChildMapping(props.children, (child) => {\n    return cloneElement(child, {\n      onExited: onExited.bind(null, child),\n      in: true,\n      appear: getProp(child, 'appear', props),\n      enter: getProp(child, 'enter', props),\n      exit: getProp(child, 'exit', props),\n    });\n  });\n}\n\nexport function getNextChildMapping(nextProps, prevChildMapping, onExited) {\n  let nextChildMapping = getChildMapping(nextProps.children);\n  let children = mergeChildMappings(prevChildMapping, nextChildMapping);\n\n  Object.keys(children).forEach((key) => {\n    let child = children[key];\n\n    if (!isValidElement(child)) return;\n\n    const hasPrev = key in prevChildMapping;\n    const hasNext = key in nextChildMapping;\n\n    const prevChild = prevChildMapping[key];\n    const isLeaving = isValidElement(prevChild) && !prevChild.props.in;\n\n    // item is new (entering)\n    if (hasNext && (!hasPrev || isLeaving)) {\n      // console.log('entering', key)\n      children[key] = cloneElement(child, {\n        onExited: onExited.bind(null, child),\n        in: true,\n        exit: getProp(child, 'exit', nextProps),\n        enter: getProp(child, 'enter', nextProps),\n      });\n    } else if (!hasNext && hasPrev && !isLeaving) {\n      // item is old (exiting)\n      // console.log('leaving', key)\n      children[key] = cloneElement(child, { in: false });\n    } else if (hasNext && hasPrev && isValidElement(prevChild)) {\n      // item hasn't changed transition states\n      // copy over the last transition props;\n      // console.log('unchanged', key)\n      children[key] = cloneElement(child, {\n        onExited: onExited.bind(null, child),\n        in: prevChild.props.in,\n        exit: getProp(child, 'exit', nextProps),\n        enter: getProp(child, 'enter', nextProps),\n      });\n    }\n  });\n\n  return children;\n}\n"
  },
  {
    "path": "src/utils/PropTypes.js",
    "content": "import PropTypes from 'prop-types';\n\nexport const timeoutsShape =\n  process.env.NODE_ENV !== 'production'\n    ? PropTypes.oneOfType([\n        PropTypes.number,\n        PropTypes.shape({\n          enter: PropTypes.number,\n          exit: PropTypes.number,\n          appear: PropTypes.number,\n        }).isRequired,\n      ])\n    : null;\n\nexport const classNamesShape =\n  process.env.NODE_ENV !== 'production'\n    ? PropTypes.oneOfType([\n        PropTypes.string,\n        PropTypes.shape({\n          enter: PropTypes.string,\n          exit: PropTypes.string,\n          active: PropTypes.string,\n        }),\n        PropTypes.shape({\n          enter: PropTypes.string,\n          enterDone: PropTypes.string,\n          enterActive: PropTypes.string,\n          exit: PropTypes.string,\n          exitDone: PropTypes.string,\n          exitActive: PropTypes.string,\n        }),\n      ])\n    : null;\n"
  },
  {
    "path": "src/utils/SimpleSet.js",
    "content": "export default class SimpleSet {\n  constructor() {\n    this.v = [];\n  }\n  clear() {\n    this.v.length = 0;\n  }\n  has(k) {\n    return this.v.indexOf(k) !== -1;\n  }\n  add(k) {\n    if (this.has(k)) return;\n    this.v.push(k);\n  }\n  delete(k) {\n    const idx = this.v.indexOf(k);\n    if (idx === -1) return false;\n    this.v.splice(idx, 1);\n    return true;\n  }\n}\n"
  },
  {
    "path": "src/utils/reflow.js",
    "content": "export const forceReflow = (node) => node.scrollTop;\n"
  },
  {
    "path": "stories/.eslintrc.yml",
    "content": "rules:\n  react/prop-types: off\n  no-unused-vars:\n    - error\n    - varsIgnorePattern: ^_$\n  import/no-extraneous-dependencies:\n    - error\n    - devDependencies: true\n"
  },
  {
    "path": "stories/CSSTransition.js",
    "content": "import React, { useState } from 'react';\nimport { storiesOf } from '@storybook/react';\n\nimport StoryFixture from './StoryFixture';\nimport Fade from './transitions/CSSFade';\n\nfunction ToggleFixture({ defaultIn, description, children }) {\n  const [show, setShow] = useState(defaultIn || false);\n\n  return (\n    <StoryFixture description={description}>\n      <div style={{ marginBottom: 10 }}>\n        <button\n          onClick={() => {\n            setShow(!show);\n          }}\n        >\n          Toggle\n        </button>\n      </div>\n      {React.cloneElement(children, { in: show })}\n    </StoryFixture>\n  );\n}\n\nstoriesOf('CSSTransition', module)\n  .add('Fade', () => (\n    <ToggleFixture>\n      <Fade>asaghasg asgasg</Fade>\n    </ToggleFixture>\n  ))\n  .add('Fade with appear', () => (\n    <ToggleFixture defaultIn>\n      <Fade appear>asaghasg asgasg</Fade>\n    </ToggleFixture>\n  ))\n  .add('Fade with mountOnEnter', () => {\n    return (\n      <ToggleFixture>\n        <Fade mountOnEnter>Fade with mountOnEnter</Fade>\n      </ToggleFixture>\n    );\n  })\n  .add('Fade with unmountOnExit', () => {\n    return (\n      <ToggleFixture>\n        <Fade unmountOnExit>Fade with unmountOnExit</Fade>\n      </ToggleFixture>\n    );\n  });\n"
  },
  {
    "path": "stories/CSSTransitionGroupFixture.js",
    "content": "import React from 'react';\n\nimport TransitionGroup from '../src/TransitionGroup';\nimport StoryFixture from './StoryFixture';\n\nclass CSSTransitionGroupFixture extends React.Component {\n  static defaultProps = {\n    items: [],\n  };\n\n  count = this.props.items.length;\n  state = {\n    items: this.props.items,\n  };\n\n  handleAddItem = () => {\n    this.setState(({ items }) => ({\n      items: [...items, `Item number: ${++this.count}`],\n    }));\n  };\n\n  handleRemoveItems = () => {\n    this.setState(({ items }) => {\n      items = items.slice();\n      items.splice(1, 3);\n      return { items };\n    });\n  };\n\n  handleRemoveItem = (item) => {\n    this.setState(({ items }) => ({\n      items: items.filter((i) => i !== item),\n    }));\n  };\n\n  render() {\n    const { items: _, description, children, ...rest } = this.props;\n    // e.g. `Fade`, see where `CSSTransitionGroupFixture` is used\n    const { type: TransitionType, props: transitionTypeProps } =\n      React.Children.only(children);\n\n    return (\n      <StoryFixture description={description}>\n        <div style={{ marginBottom: 10 }}>\n          <button onClick={this.handleAddItem}>Add Item</button>{' '}\n          <button onClick={this.handleRemoveItems}>Remove a few</button>\n        </div>\n        <TransitionGroup component=\"div\" {...rest}>\n          {this.state.items.map((item) => (\n            <TransitionType {...transitionTypeProps} key={item}>\n              {item}\n              <button onClick={() => this.handleRemoveItem(item)}>\n                &times;\n              </button>\n            </TransitionType>\n          ))}\n        </TransitionGroup>\n      </StoryFixture>\n    );\n  }\n}\n\nexport default CSSTransitionGroupFixture;\n"
  },
  {
    "path": "stories/NestedTransition.js",
    "content": "import React, { useState } from 'react';\n\nimport StoryFixture from './StoryFixture';\nimport Fade from './transitions/CSSFadeForTransitionGroup';\nimport Scale from './transitions/Scale';\n\nfunction FadeAndScale(props) {\n  return (\n    <Fade {...props}>\n      <div>I will fade</div>\n      {/*\n          We also want to scale in at the same time so we pass the `in` state here as well, so it enters\n          at the same time as the Fade.\n\n          Note also the `appear` since the Fade will happen when the item mounts, the Scale transition\n          will mount at the same time as the div we want to scale, so we need to tell it to animate as\n          it _appears_.\n        */}\n      <Scale in={props.in} appear>\n        I should scale\n      </Scale>\n    </Fade>\n  );\n}\n\nfunction Example() {\n  const [showNested, setShowNested] = useState(false);\n\n  return (\n    <StoryFixture description=\"nested Transitions\">\n      <h3>Nested Animations</h3>\n      <button\n        onClick={() => {\n          setShowNested(!showNested);\n        }}\n      >\n        Click to see 2 nested animations\n      </button>\n      <FadeAndScale in={showNested} mountOnEnter unmountOnExit />\n    </StoryFixture>\n  );\n}\n\nexport default Example;\n"
  },
  {
    "path": "stories/ReplaceTransition.js",
    "content": "import { css } from 'astroturf';\nimport React, { useState } from 'react';\nimport { storiesOf } from '@storybook/react';\n\nimport ReplaceTransition from '../src/ReplaceTransition';\nimport CSSTransition from '../src/CSSTransition';\n\nconst FADE_TIMEOUT = 1000;\n\nconst styles = css`\n  .enter {\n    opacity: 0.01;\n  }\n\n  .enter.enter-active {\n    position: absolute;\n    left: 0;\n    right: 0;\n    opacity: 1;\n    transition: opacity ${FADE_TIMEOUT * 2}ms ease-in;\n    transition-delay: ${FADE_TIMEOUT}ms;\n  }\n\n  .exit {\n    opacity: 1;\n  }\n  .exit.exit-active {\n    opacity: 0.01;\n\n    transition: opacity ${FADE_TIMEOUT}ms ease-in;\n  }\n\n  .box {\n    padding: 20px;\n    background-color: #ccc;\n  }\n  .container {\n    position: relative;\n  }\n`;\n\nconst defaultProps = {\n  in: false,\n  timeout: FADE_TIMEOUT * 2,\n};\n\nfunction Fade(props) {\n  return (\n    <CSSTransition {...props} className={styles.box} classNames={styles} />\n  );\n}\n\nFade.defaultProps = defaultProps;\n\nfunction Example({ children }) {\n  const [show, setShow] = useState(false);\n\n  return (\n    <div>\n      <button\n        onClick={() => {\n          setShow(!show);\n        }}\n      >\n        toggle (in: \"{String(show)}\")\n      </button>\n      {React.cloneElement(children, { in: show })}\n    </div>\n  );\n}\n\nstoriesOf('Replace Transition', module).add('Animates on all', () => {\n  const firstNodeRef = React.createRef();\n  const secondNodeRef = React.createRef();\n  return (\n    <Example>\n      <ReplaceTransition\n        in={false} // `Example` is overriding this prop\n        className={styles.container}\n        onEnter={() => console.log('onEnter')}\n        onEntering={() => console.log('onEntering')}\n        onEntered={() => console.log('onEntered')}\n        onExit={() => console.log('onExit')}\n        onExiting={() => console.log('onExiting')}\n        onExited={() => console.log('onExited')}\n      >\n        <Fade nodeRef={firstNodeRef}>\n          <div ref={firstNodeRef}>in True</div>\n        </Fade>\n        <Fade nodeRef={secondNodeRef}>\n          <div ref={secondNodeRef}>in False</div>\n        </Fade>\n      </ReplaceTransition>\n    </Example>\n  );\n});\n"
  },
  {
    "path": "stories/StoryFixture.js",
    "content": "import PropTypes from 'prop-types';\nimport React from 'react';\n\nconst propTypes = {\n  description: PropTypes.string,\n};\n\nfunction StoryFixture({ description, children }) {\n  return (\n    <div>\n      <p>{description}</p>\n\n      {children}\n    </div>\n  );\n}\n\nStoryFixture.propTypes = propTypes;\n\nexport default StoryFixture;\n"
  },
  {
    "path": "stories/Transition.js",
    "content": "import React, { useState } from 'react';\nimport { storiesOf } from '@storybook/react';\n\nimport StoryFixture from './StoryFixture';\nimport {\n  Fade,\n  Collapse,\n  FadeForwardRef,\n  FadeInnerRef,\n} from './transitions/Bootstrap';\n\nfunction ToggleFixture({ defaultIn, description, children }) {\n  const [show, setShow] = useState(defaultIn);\n\n  return (\n    <StoryFixture description={description}>\n      <div style={{ marginBottom: 10 }}>\n        <button\n          onClick={() => {\n            setShow(!show);\n          }}\n        >\n          Toggle\n        </button>\n      </div>\n      {React.cloneElement(children, { in: show })}\n    </StoryFixture>\n  );\n}\n\nstoriesOf('Transition', module)\n  .add('Bootstrap Fade', () => (\n    <ToggleFixture>\n      <Fade>asaghasg asgasg</Fade>\n    </ToggleFixture>\n  ))\n  .add('Bootstrap Collapse', () => (\n    <ToggleFixture>\n      <Collapse>\n        asaghasg asgasg\n        <div>foo</div>\n        <div>bar</div>\n      </Collapse>\n    </ToggleFixture>\n  ))\n  .add('Fade using React.forwardRef', () => {\n    const nodeRef = React.createRef();\n    return (\n      <ToggleFixture>\n        <FadeForwardRef ref={nodeRef}>\n          Fade using React.forwardRef\n        </FadeForwardRef>\n      </ToggleFixture>\n    );\n  })\n  .add('Fade using innerRef', () => {\n    const nodeRef = React.createRef();\n    return (\n      <ToggleFixture>\n        <FadeInnerRef innerRef={nodeRef}>Fade using innerRef</FadeInnerRef>\n      </ToggleFixture>\n    );\n  })\n  .add('Fade with mountOnEnter', () => {\n    return (\n      <ToggleFixture>\n        <Fade mountOnEnter>Fade with mountOnEnter</Fade>\n      </ToggleFixture>\n    );\n  })\n  .add('Fade with unmountOnExit', () => {\n    return (\n      <ToggleFixture>\n        <Fade unmountOnExit>Fade with unmountOnExit</Fade>\n      </ToggleFixture>\n    );\n  });\n"
  },
  {
    "path": "stories/TransitionGroup.js",
    "content": "import React, { useEffect, useState } from 'react';\nimport { storiesOf } from '@storybook/react';\n\nimport TransitionGroup from '../src/TransitionGroup';\n\nimport CSSTransitionGroupFixture from './CSSTransitionGroupFixture';\nimport NestedTransition from './NestedTransition';\nimport StoryFixture from './StoryFixture';\nimport Fade, { FADE_TIMEOUT } from './transitions/CSSFadeForTransitionGroup';\n\nstoriesOf('Css Transition Group', module)\n  .add('Animates on all', () => (\n    <CSSTransitionGroupFixture\n      description={`\n        Should animate when items are added to the list but not when they are\n        removed or on initial appear\n      `}\n      appear\n      items={['Item number: 1']}\n    >\n      <Fade />\n    </CSSTransitionGroupFixture>\n  ))\n  .add('Animates on enter', () => (\n    <CSSTransitionGroupFixture\n      description={`\n        Should animate when items are added to the list but not when they are\n        removed or on initial appear\n      `}\n      exit={false}\n      timeout={{ enter: FADE_TIMEOUT }}\n      items={['Item number: 1']}\n    >\n      <Fade />\n    </CSSTransitionGroupFixture>\n  ))\n  .add('Animates on exit', () => (\n    <CSSTransitionGroupFixture\n      description={`\n        Should animate when items are removed to the list but not when they are\n        added or on initial appear\n      `}\n      items={['Item number: 1', 'Item number: 2', 'Item number: 3']}\n    >\n      <Fade enter={false} timeout={{ exit: FADE_TIMEOUT }} />\n    </CSSTransitionGroupFixture>\n  ))\n  .add('Animates on appear', () => (\n    <CSSTransitionGroupFixture\n      description={`\n        Should animate when items first mount but not when added or removed\n      `}\n      appear\n      items={['Item number: 1', 'Item number: 2', 'Item number: 3']}\n    >\n      <Fade exit={false} enter={false} />\n    </CSSTransitionGroupFixture>\n  ))\n  .add('Dynamic props', () => (\n    <StoryFixture\n      description={`\n        Updates to children should not break animations\n      `}\n    >\n      <DynamicTransition />\n    </StoryFixture>\n  ))\n  .add('Re-entering while leaving', () => (\n    <StoryFixture\n      description={`\n        Should animate on enter even while exiting\n      `}\n    >\n      <ReEnterTransition />\n    </StoryFixture>\n  ))\n  .add('Nested Transitions', () => <NestedTransition />);\n\nclass DynamicTransition extends React.Component {\n  state = { count: 0 };\n  handleClick = () => {\n    this.setState({ hide: !this.state.hide });\n  };\n\n  componentDidMount() {\n    this.interval = setInterval(() => {\n      this.setState({ count: this.state.count + 1 });\n    }, 700);\n  }\n  componentWillUnmount() {\n    clearInterval(this.interval);\n  }\n\n  render() {\n    const { hide, count } = this.state;\n    return (\n      <div>\n        <button onClick={this.handleClick}>Toggle item</button>\n        <TransitionGroup timeout={FADE_TIMEOUT}>\n          {!hide && <Fade key=\"item\">Changing! {count}</Fade>}\n        </TransitionGroup>\n      </div>\n    );\n  }\n}\n\nfunction ReEnterTransition() {\n  const [hide, setHide] = useState(false);\n\n  useEffect(() => {\n    if (hide) {\n      setTimeout(() => {\n        console.log('re-entering!');\n        setHide(false);\n      }, 0.5 * FADE_TIMEOUT);\n    }\n  }, [hide]);\n\n  return (\n    <div>\n      <button\n        onClick={() => {\n          setHide(true);\n        }}\n      >\n        Remove and re-add\n      </button>\n      <TransitionGroup timeout={FADE_TIMEOUT}>\n        {!hide && <Fade key=\"item\">I'm entering!</Fade>}\n      </TransitionGroup>\n    </div>\n  );\n}\n"
  },
  {
    "path": "stories/index.js",
    "content": "import './Transition';\nimport './CSSTransition';\nimport './TransitionGroup';\nimport './ReplaceTransition';\n"
  },
  {
    "path": "stories/transitions/Bootstrap.js",
    "content": "import { css } from 'astroturf';\nimport React, { useEffect, useRef } from 'react';\nimport style from 'dom-helpers/css';\n\nimport Transition, {\n  EXITED,\n  ENTERED,\n  ENTERING,\n  EXITING,\n} from '../../src/Transition';\n\nconst styles = css`\n  .fade {\n    opacity: 0;\n    transition: opacity 0.5s linear;\n  }\n  .fade.in {\n    opacity: 1;\n  }\n\n  .collapse {\n    display: none;\n  }\n\n  .collapse.in {\n    display: block;\n  }\n\n  .collapsing {\n    position: relative;\n    height: 0;\n    overflow: hidden;\n    transition: 0.35s ease;\n    transition-property: height, visibility;\n  }\n`;\n\nconst fadeStyles = {\n  [ENTERING]: styles.in,\n  [ENTERED]: styles.in,\n};\n\nexport function Fade(props) {\n  const nodeRef = useRef();\n  return (\n    <Transition\n      {...props}\n      nodeRef={nodeRef}\n      className={styles.fade}\n      timeout={500}\n    >\n      {(status) => (\n        <div\n          ref={nodeRef}\n          className={`${styles.fade} ${fadeStyles[status] || ''}`}\n        >\n          {props.children}\n        </div>\n      )}\n    </Transition>\n  );\n}\n\nfunction getHeight(elem) {\n  let value = elem.offsetHeight;\n  let margins = ['marginTop', 'marginBottom'];\n\n  return (\n    value +\n    parseInt(style(elem, margins[0]), 10) +\n    parseInt(style(elem, margins[1]), 10)\n  );\n}\n\nconst collapseStyles = {\n  [EXITED]: styles.collapse,\n  [EXITING]: styles.collapsing,\n  [ENTERING]: styles.collapsing,\n  [ENTERED]: `${styles.collapse} ${styles.in}`,\n};\n\nexport class Collapse extends React.Component {\n  nodeRef = React.createRef();\n\n  /* -- Expanding -- */\n  handleEnter = () => {\n    this.nodeRef.current.style.height = '0';\n  };\n\n  handleEntering = () => {\n    this.nodeRef.current.style.height = `${this.nodeRef.current.scrollHeight}px`;\n  };\n\n  handleEntered = () => {\n    this.nodeRef.current.style.height = null;\n  };\n\n  /* -- Collapsing -- */\n  handleExit = () => {\n    this.nodeRef.current.style.height = getHeight(this.nodeRef.current) + 'px';\n    this.nodeRef.current.offsetHeight; // eslint-disable-line no-unused-expressions\n  };\n\n  handleExiting = () => {\n    this.nodeRef.current.style.height = '0';\n  };\n\n  render() {\n    const { children, ...rest } = this.props;\n    return (\n      <Transition\n        {...rest}\n        nodeRef={this.nodeRef}\n        timeout={350}\n        onEnter={this.handleEnter}\n        onEntering={this.handleEntering}\n        onEntered={this.handleEntered}\n        onExit={this.handleExit}\n        onExiting={this.handleExiting}\n      >\n        {(state, props) => (\n          <div ref={this.nodeRef} className={collapseStyles[state]} {...props}>\n            {children}\n          </div>\n        )}\n      </Transition>\n    );\n  }\n}\n\nexport function FadeInnerRef(props) {\n  const nodeRef = useMergedRef(props.innerRef);\n  return (\n    <Transition\n      {...props}\n      nodeRef={nodeRef}\n      className={styles.fade}\n      timeout={150}\n    >\n      {(status) => (\n        <div\n          ref={nodeRef}\n          className={`${styles.fade} ${fadeStyles[status] || ''}`}\n        >\n          {props.children}\n        </div>\n      )}\n    </Transition>\n  );\n}\n\nexport const FadeForwardRef = React.forwardRef((props, ref) => {\n  return <FadeInnerRef {...props} innerRef={ref} />;\n});\n\n/**\n * Compose multiple refs, there may be different implementations\n * This one is derived from\n * e.g. https://github.com/react-restart/hooks/blob/ed37bf3dfc8fc1d9234a6d8fe0af94d69fad3b74/src/useMergedRefs.ts\n * Also here are good discussion about this\n * https://github.com/facebook/react/issues/13029\n * @param ref\n * @returns {React.MutableRefObject<undefined>}\n */\nfunction useMergedRef(ref) {\n  const nodeRef = React.useRef();\n  useEffect(function () {\n    if (ref) {\n      if (typeof ref === 'function') {\n        ref(nodeRef.current);\n      } else {\n        ref.current = nodeRef.current;\n      }\n    }\n  });\n  return nodeRef;\n}\n"
  },
  {
    "path": "stories/transitions/CSSFade.js",
    "content": "import { css } from 'astroturf';\nimport React, { useRef } from 'react';\n\nimport CSSTransition from '../../src/CSSTransition';\n\nexport const FADE_TIMEOUT = 1000;\n\nconst styles = css`\n  .default {\n    opacity: 0;\n  }\n  .enter-done {\n    opacity: 1;\n  }\n\n  .enter,\n  .appear {\n    opacity: 0.01;\n  }\n\n  .enter.enter-active,\n  .appear.appear-active {\n    opacity: 1;\n    transition: opacity ${FADE_TIMEOUT}ms ease-in;\n  }\n\n  .exit {\n    opacity: 1;\n  }\n  .exit.exit-active {\n    opacity: 0.01;\n    transition: opacity ${0.8 * FADE_TIMEOUT}ms ease-in;\n  }\n`;\n\nconst defaultProps = {\n  in: false,\n  timeout: FADE_TIMEOUT,\n};\nfunction Fade(props) {\n  const nodeRef = useRef();\n  return (\n    <CSSTransition {...props} classNames={styles} nodeRef={nodeRef}>\n      <div ref={nodeRef} className={styles.default}>\n        {props.children}\n      </div>\n    </CSSTransition>\n  );\n}\n\nFade.defaultProps = defaultProps;\n\nexport default Fade;\n"
  },
  {
    "path": "stories/transitions/CSSFadeForTransitionGroup.js",
    "content": "import { css } from 'astroturf';\nimport React, { useRef } from 'react';\n\nimport CSSTransition from '../../src/CSSTransition';\n\nexport const FADE_TIMEOUT = 1000;\n\nconst styles = css`\n  .enter,\n  .appear {\n    opacity: 0.01;\n  }\n\n  .enter.enter-active,\n  .appear.appear-active {\n    opacity: 1;\n    transition: opacity ${FADE_TIMEOUT}ms ease-in;\n  }\n\n  .exit {\n    opacity: 1;\n  }\n  .exit.exit-active {\n    opacity: 0.01;\n    transition: opacity ${0.8 * FADE_TIMEOUT}ms ease-in;\n  }\n`;\n\nconst defaultProps = {\n  in: false,\n  timeout: FADE_TIMEOUT,\n};\n\nfunction Fade(props) {\n  const nodeRef = useRef();\n  return (\n    <CSSTransition {...props} classNames={styles} nodeRef={nodeRef}>\n      <div ref={nodeRef}>{props.children}</div>\n    </CSSTransition>\n  );\n}\n\nFade.defaultProps = defaultProps;\n\nexport default Fade;\n"
  },
  {
    "path": "stories/transitions/Scale.js",
    "content": "import { css } from 'astroturf';\nimport React, { useRef } from 'react';\n\nimport CSSTransition from '../../src/CSSTransition';\n\nexport const SCALE_TIMEOUT = 1000;\n\nconst styles = css`\n  .enter,\n  .appear {\n    transform: scale(0);\n  }\n  .enter.enter-active,\n  .appear.appear-active {\n    transform: scale(1);\n    transition: transform ${SCALE_TIMEOUT}ms;\n  }\n\n  .exit {\n    transform: scale(1);\n  }\n\n  .exit.exit-active {\n    transform: scale(0);\n    transition: transform ${SCALE_TIMEOUT}ms;\n  }\n`;\n\nconst defaultProps = {\n  in: false,\n  timeout: SCALE_TIMEOUT,\n};\n\nfunction Scale(props) {\n  const nodeRef = useRef();\n  return (\n    <CSSTransition {...props} classNames={styles} nodeRef={nodeRef}>\n      <div ref={nodeRef}>{props.children}</div>\n    </CSSTransition>\n  );\n}\n\nScale.defaultProps = defaultProps;\n\nexport default Scale;\n"
  },
  {
    "path": "test/.eslintrc.yml",
    "content": "env:\n  jest: true\n  es6: true\nrules:\n  no-require: off\n  global-require: off\n  no-console: off\n  react/no-multi-comp: off\n  react/no-render-return-value: off\n  react/no-find-dom-node: off\n  react/prop-types: off\n  react/prefer-stateless-function: off\n  react/jsx-boolean-value: off\n  react/no-string-refs: off\n  import/no-extraneous-dependencies:\n    - error\n    - devDependencies: true\n"
  },
  {
    "path": "test/CSSTransition-test.js",
    "content": "import React from 'react';\nimport { render, waitFor } from './utils';\n\nimport CSSTransition from '../src/CSSTransition';\nimport TransitionGroup from '../src/TransitionGroup';\n\ndescribe('CSSTransition', () => {\n  it('should flush new props to the DOM before initiating a transition', (done) => {\n    const nodeRef = React.createRef();\n    const { setProps } = render(\n      <CSSTransition\n        in={false}\n        nodeRef={nodeRef}\n        timeout={0}\n        classNames=\"test\"\n        onEnter={() => {\n          expect(nodeRef.current.classList.contains('test-class')).toEqual(\n            true\n          );\n          expect(nodeRef.current.classList.contains('test-entering')).toEqual(\n            false\n          );\n          done();\n        }}\n      >\n        <div ref={nodeRef} />\n      </CSSTransition>\n    );\n\n    expect(nodeRef.current.classList.contains('test-class')).toEqual(false);\n\n    setProps({\n      in: true,\n      className: 'test-class',\n    });\n  });\n\n  describe('entering', () => {\n    it('should apply classes at each transition state', async () => {\n      let count = 0;\n      let done = false;\n      const nodeRef = React.createRef();\n      const { setProps } = render(\n        <CSSTransition nodeRef={nodeRef} timeout={10} classNames=\"test\">\n          <div ref={nodeRef} />\n        </CSSTransition>\n      );\n\n      setProps({\n        in: true,\n\n        onEnter() {\n          count++;\n          expect(nodeRef.current.className).toEqual('test-enter');\n        },\n\n        onEntering() {\n          count++;\n          expect(nodeRef.current.className).toEqual(\n            'test-enter test-enter-active'\n          );\n        },\n\n        onEntered() {\n          expect(nodeRef.current.className).toEqual('test-enter-done');\n          expect(count).toEqual(2);\n          done = true;\n        },\n      });\n\n      await waitFor(() => {\n        expect(done).toBe(true);\n      });\n    });\n\n    it('should apply custom classNames names', async () => {\n      let count = 0;\n      const nodeRef = React.createRef();\n      const { setProps } = render(\n        <CSSTransition\n          timeout={10}\n          nodeRef={nodeRef}\n          classNames={{\n            enter: 'custom',\n            enterActive: 'custom-super-active',\n            enterDone: 'custom-super-done',\n          }}\n        >\n          <div ref={nodeRef} />\n        </CSSTransition>\n      );\n\n      setProps({\n        in: true,\n\n        onEnter() {\n          count++;\n          expect(nodeRef.current.className).toEqual('custom');\n        },\n\n        onEntering() {\n          count++;\n          expect(nodeRef.current.className).toEqual(\n            'custom custom-super-active'\n          );\n        },\n\n        onEntered() {\n          expect(nodeRef.current.className).toEqual('custom-super-done');\n        },\n      });\n\n      await waitFor(() => {\n        expect(count).toEqual(2);\n      });\n    });\n  });\n\n  describe('appearing', () => {\n    it('should apply appear classes at each transition state', async () => {\n      let count = 0;\n      const nodeRef = React.createRef();\n      render(\n        <CSSTransition\n          timeout={10}\n          nodeRef={nodeRef}\n          classNames=\"appear-test\"\n          in={true}\n          appear={true}\n          onEnter={(isAppearing) => {\n            count++;\n            expect(isAppearing).toEqual(true);\n            expect(nodeRef.current.className).toEqual('appear-test-appear');\n          }}\n          onEntering={(isAppearing) => {\n            count++;\n            expect(isAppearing).toEqual(true);\n            expect(nodeRef.current.className).toEqual(\n              'appear-test-appear appear-test-appear-active'\n            );\n          }}\n          onEntered={(isAppearing) => {\n            expect(isAppearing).toEqual(true);\n            expect(nodeRef.current.className).toEqual(\n              'appear-test-appear-done appear-test-enter-done'\n            );\n          }}\n        >\n          <div ref={nodeRef} />\n        </CSSTransition>\n      );\n\n      await waitFor(() => {\n        expect(count).toEqual(2);\n      });\n    });\n\n    it('should lose the \"*-appear-done\" class after leaving and entering again', async () => {\n      const nodeRef = React.createRef();\n      let entered = false;\n      let exited = false;\n      const { setProps } = render(\n        <CSSTransition\n          timeout={10}\n          nodeRef={nodeRef}\n          classNames=\"appear-test\"\n          in={true}\n          appear={true}\n          onEntered={() => {\n            entered = true;\n          }}\n        >\n          <div ref={nodeRef} />\n        </CSSTransition>\n      );\n\n      await waitFor(() => {\n        expect(entered).toEqual(true);\n      });\n      setProps({\n        in: false,\n        onEntered: () => {},\n        onExited: () => {\n          exited = true;\n        },\n      });\n\n      await waitFor(() => {\n        expect(exited).toEqual(true);\n      });\n      expect(nodeRef.current.className).toBe('appear-test-exit-done');\n      entered = false;\n      setProps({\n        in: true,\n        onEntered: () => {\n          entered = true;\n        },\n      });\n\n      await waitFor(() => {\n        expect(entered).toEqual(true);\n      });\n      expect(nodeRef.current.className).toBe('appear-test-enter-done');\n    });\n\n    it('should not add undefined when appearDone is not defined', async () => {\n      const nodeRef = React.createRef();\n      let done = false;\n      render(\n        <CSSTransition\n          timeout={10}\n          nodeRef={nodeRef}\n          classNames={{ appear: 'appear-test' }}\n          in={true}\n          appear={true}\n          onEnter={(isAppearing) => {\n            expect(isAppearing).toEqual(true);\n            expect(nodeRef.current.className).toEqual('appear-test');\n          }}\n          onEntered={(isAppearing) => {\n            expect(isAppearing).toEqual(true);\n            expect(nodeRef.current.className).toEqual('');\n            done = true;\n          }}\n        >\n          <div ref={nodeRef} />\n        </CSSTransition>\n      );\n\n      await waitFor(() => {\n        expect(done).toEqual(true);\n      });\n    });\n\n    it('should not be appearing in normal enter mode', async () => {\n      let count = 0;\n      const nodeRef = React.createRef();\n      render(\n        <CSSTransition\n          timeout={10}\n          nodeRef={nodeRef}\n          classNames=\"not-appear-test\"\n          appear={true}\n        >\n          <div ref={nodeRef} />\n        </CSSTransition>\n      ).setProps({\n        in: true,\n\n        onEnter(isAppearing) {\n          count++;\n          expect(isAppearing).toEqual(false);\n          expect(nodeRef.current.className).toEqual('not-appear-test-enter');\n        },\n\n        onEntering(isAppearing) {\n          count++;\n          expect(isAppearing).toEqual(false);\n          expect(nodeRef.current.className).toEqual(\n            'not-appear-test-enter not-appear-test-enter-active'\n          );\n        },\n\n        onEntered(isAppearing) {\n          expect(isAppearing).toEqual(false);\n          expect(nodeRef.current.className).toEqual(\n            'not-appear-test-enter-done'\n          );\n        },\n      });\n\n      await waitFor(() => {\n        expect(count).toEqual(2);\n      });\n    });\n\n    it('should not enter the transition states when appear=false', () => {\n      const nodeRef = React.createRef();\n      render(\n        <CSSTransition\n          timeout={10}\n          nodeRef={nodeRef}\n          classNames=\"appear-fail-test\"\n          in={true}\n          appear={false}\n          onEnter={() => {\n            throw Error('Enter called!');\n          }}\n          onEntering={() => {\n            throw Error('Entring called!');\n          }}\n          onEntered={() => {\n            throw Error('Entred called!');\n          }}\n        >\n          <div ref={nodeRef} />\n        </CSSTransition>\n      );\n    });\n  });\n\n  describe('exiting', () => {\n    it('should apply classes at each transition state', async () => {\n      let count = 0;\n      const nodeRef = React.createRef();\n      const { setProps } = render(\n        <CSSTransition in nodeRef={nodeRef} timeout={10} classNames=\"test\">\n          <div ref={nodeRef} />\n        </CSSTransition>\n      );\n\n      setProps({\n        in: false,\n\n        onExit() {\n          count++;\n          expect(nodeRef.current.className).toEqual('test-exit');\n        },\n\n        onExiting() {\n          count++;\n          expect(nodeRef.current.className).toEqual(\n            'test-exit test-exit-active'\n          );\n        },\n\n        onExited() {\n          expect(nodeRef.current.className).toEqual('test-exit-done');\n        },\n      });\n\n      await waitFor(() => {\n        expect(count).toEqual(2);\n      });\n    });\n\n    it('should apply custom classNames names', async () => {\n      let count = 0;\n      const nodeRef = React.createRef();\n      const { setProps } = render(\n        <CSSTransition\n          in\n          nodeRef={nodeRef}\n          timeout={10}\n          classNames={{\n            exit: 'custom',\n            exitActive: 'custom-super-active',\n            exitDone: 'custom-super-done',\n          }}\n        >\n          <div ref={nodeRef} />\n        </CSSTransition>\n      );\n\n      setProps({\n        in: false,\n\n        onExit() {\n          count++;\n          expect(nodeRef.current.className).toEqual('custom');\n        },\n\n        onExiting() {\n          count++;\n          expect(nodeRef.current.className).toEqual(\n            'custom custom-super-active'\n          );\n        },\n\n        onExited() {\n          expect(nodeRef.current.className).toEqual('custom-super-done');\n        },\n      });\n\n      await waitFor(() => {\n        expect(count).toEqual(2);\n      });\n    });\n\n    it('should support empty prefix', async () => {\n      let count = 0;\n\n      const nodeRef = React.createRef();\n      const { setProps } = render(\n        <CSSTransition in nodeRef={nodeRef} timeout={10}>\n          <div ref={nodeRef} />\n        </CSSTransition>\n      );\n\n      setProps({\n        in: false,\n\n        onExit() {\n          count++;\n          expect(nodeRef.current.className).toEqual('exit');\n        },\n\n        onExiting() {\n          count++;\n          expect(nodeRef.current.className).toEqual('exit exit-active');\n        },\n\n        onExited() {\n          expect(nodeRef.current.className).toEqual('exit-done');\n        },\n      });\n\n      await waitFor(() => {\n        expect(count).toEqual(2);\n      });\n    });\n  });\n\n  describe('reentering', () => {\n    it('should remove dynamically applied classes', async () => {\n      let count = 0;\n      class Test extends React.Component {\n        render() {\n          const { direction, text, nodeRef, ...props } = this.props;\n\n          return (\n            <TransitionGroup\n              component={null}\n              childFactory={(child) =>\n                React.cloneElement(child, {\n                  classNames: direction,\n                })\n              }\n            >\n              <CSSTransition\n                key={text}\n                timeout={100}\n                nodeRef={nodeRef}\n                {...props}\n              >\n                <span ref={nodeRef}>{text}</span>\n              </CSSTransition>\n            </TransitionGroup>\n          );\n        }\n      }\n\n      const nodeRef = {\n        foo: React.createRef(),\n        bar: React.createRef(),\n      };\n\n      const { setProps } = render(\n        <Test direction=\"down\" text=\"foo\" nodeRef={nodeRef.foo} />\n      );\n\n      setProps({\n        direction: 'up',\n        text: 'bar',\n        nodeRef: nodeRef.bar,\n\n        onEnter() {\n          count++;\n          expect(nodeRef.bar.current.className).toEqual('up-enter');\n        },\n        onEntering() {\n          count++;\n          expect(nodeRef.bar.current.className).toEqual(\n            'up-enter up-enter-active'\n          );\n        },\n      });\n\n      await waitFor(() => {\n        expect(count).toEqual(2);\n      });\n\n      setProps({\n        direction: 'down',\n        text: 'foo',\n        nodeRef: nodeRef.foo,\n\n        onEntering() {\n          count++;\n          expect(nodeRef.foo.current.className).toEqual(\n            'down-enter down-enter-active'\n          );\n        },\n        onEntered() {\n          count++;\n          expect(nodeRef.foo.current.className).toEqual('down-enter-done');\n        },\n      });\n\n      await waitFor(() => {\n        expect(count).toEqual(4);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/CSSTransitionGroup-test.js",
    "content": "import hasClass from 'dom-helpers/hasClass';\nimport CSSTransition from '../src/CSSTransition';\n\nlet React;\nlet ReactDOM;\nlet TransitionGroup;\nlet act;\nlet render;\n\n// Most of the real functionality is covered in other unit tests, this just\n// makes sure we're wired up correctly.\ndescribe('CSSTransitionGroup', () => {\n  let container;\n  let consoleErrorSpy;\n\n  function YoloTransition({ id, ...props }) {\n    const nodeRef = React.useRef();\n    return (\n      <CSSTransition nodeRef={nodeRef} classNames=\"yolo\" timeout={0} {...props}>\n        <span ref={nodeRef} id={id} />\n      </CSSTransition>\n    );\n  }\n\n  beforeEach(() => {\n    jest.resetModuleRegistry();\n    jest.useFakeTimers();\n\n    React = require('react');\n    ReactDOM = require('react-dom');\n    const testUtils = require('./utils');\n    act = testUtils.act;\n    const baseRender = testUtils.render;\n\n    render = (element, container) =>\n      baseRender(<React.StrictMode>{element}</React.StrictMode>, { container });\n\n    TransitionGroup = require('../src/TransitionGroup');\n\n    container = document.createElement('div');\n    consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});\n  });\n\n  afterEach(() => {\n    consoleErrorSpy.mockRestore();\n    jest.useRealTimers();\n  });\n\n  it('should clean-up silently after the timeout elapses', () => {\n    render(\n      <TransitionGroup enter={false}>\n        <YoloTransition key=\"one\" id=\"one\" />\n      </TransitionGroup>,\n      container\n    );\n\n    const transitionGroupDiv = container.childNodes[0];\n\n    expect(transitionGroupDiv.childNodes.length).toBe(1);\n\n    render(\n      <TransitionGroup enter={false}>\n        <YoloTransition key=\"two\" id=\"two\" />\n      </TransitionGroup>,\n      container\n    );\n\n    expect(transitionGroupDiv.childNodes.length).toBe(2);\n    expect(transitionGroupDiv.childNodes[0].id).toBe('two');\n    expect(transitionGroupDiv.childNodes[1].id).toBe('one');\n\n    act(() => {\n      jest.runAllTimers();\n    });\n\n    // No warnings\n    expect(consoleErrorSpy).not.toHaveBeenCalled();\n\n    // The leaving child has been removed\n    expect(transitionGroupDiv.childNodes.length).toBe(1);\n    expect(transitionGroupDiv.childNodes[0].id).toBe('two');\n  });\n\n  it('should keep both sets of DOM nodes around', () => {\n    render(\n      <TransitionGroup>\n        <YoloTransition key=\"one\" id=\"one\" />\n      </TransitionGroup>,\n      container\n    );\n\n    const transitionGroupDiv = container.childNodes[0];\n\n    expect(transitionGroupDiv.childNodes.length).toBe(1);\n\n    render(\n      <TransitionGroup>\n        <YoloTransition key=\"two\" id=\"two\" />\n      </TransitionGroup>,\n      container\n    );\n\n    expect(transitionGroupDiv.childNodes.length).toBe(2);\n    expect(transitionGroupDiv.childNodes[0].id).toBe('two');\n    expect(transitionGroupDiv.childNodes[1].id).toBe('one');\n  });\n\n  it('should switch transitionLeave from false to true', () => {\n    render(\n      <TransitionGroup enter={false} leave={false}>\n        <YoloTransition key=\"one\" id=\"one\" />\n      </TransitionGroup>,\n      container\n    );\n\n    const transitionGroupDiv = container.childNodes[0];\n\n    expect(transitionGroupDiv.childNodes.length).toBe(1);\n\n    render(\n      <TransitionGroup enter={false} leave={false}>\n        <YoloTransition key=\"two\" id=\"two\" />\n      </TransitionGroup>,\n      container\n    );\n\n    act(() => {\n      jest.runAllTimers();\n    });\n\n    expect(transitionGroupDiv.childNodes.length).toBe(1);\n\n    render(\n      <TransitionGroup enter={false} leave>\n        <YoloTransition key=\"three\" id=\"three\" />\n      </TransitionGroup>,\n      container\n    );\n\n    expect(transitionGroupDiv.childNodes.length).toBe(2);\n    expect(transitionGroupDiv.childNodes[0].id).toBe('three');\n    expect(transitionGroupDiv.childNodes[1].id).toBe('two');\n  });\n\n  it('should work with a null child', () => {\n    render(<TransitionGroup>{[null]}</TransitionGroup>, container);\n  });\n\n  it('should work with a child which renders as null', () => {\n    const NullComponent = () => null;\n    // Testing the whole lifecycle of entering and exiting,\n    // because those lifecycle methods used to fail when the DOM node was null.\n    render(<TransitionGroup />, container);\n    render(\n      <TransitionGroup>\n        <CSSTransition classNames=\"yolo\" timeout={0}>\n          <NullComponent />\n        </CSSTransition>\n      </TransitionGroup>,\n      container\n    );\n    render(<TransitionGroup />, container);\n  });\n\n  it('should transition from one to null', () => {\n    render(\n      <TransitionGroup>\n        <YoloTransition key=\"one\" id=\"one\" />\n      </TransitionGroup>,\n      container\n    );\n\n    const transitionGroupDiv = container.childNodes[0];\n\n    expect(transitionGroupDiv.childNodes.length).toBe(1);\n\n    render(<TransitionGroup>{null}</TransitionGroup>, container);\n\n    // (Here, we expect the original child to stick around but test that no\n    // exception is thrown)\n    expect(transitionGroupDiv.childNodes.length).toBe(1);\n    expect(transitionGroupDiv.childNodes[0].id).toBe('one');\n  });\n\n  it('should transition from false to one', () => {\n    render(<TransitionGroup>{false}</TransitionGroup>, container);\n\n    const transitionGroupDiv = container.childNodes[0];\n\n    expect(transitionGroupDiv.childNodes.length).toBe(0);\n\n    render(\n      <TransitionGroup>\n        <YoloTransition key=\"one\" id=\"one\" />\n      </TransitionGroup>,\n      container\n    );\n\n    expect(transitionGroupDiv.childNodes.length).toBe(1);\n    expect(transitionGroupDiv.childNodes[0].id).toBe('one');\n  });\n\n  it('should clear transition timeouts when unmounted', () => {\n    class Component extends React.Component {\n      render() {\n        return <TransitionGroup>{this.props.children}</TransitionGroup>;\n      }\n    }\n\n    render(<Component />, container);\n    render(\n      <Component>\n        <YoloTransition key=\"yolo\" id=\"yolo\" />\n      </Component>,\n      container\n    );\n\n    ReactDOM.unmountComponentAtNode(container);\n\n    // Testing that no exception is thrown here, as the timeout has been cleared.\n    act(() => {\n      jest.runAllTimers();\n    });\n  });\n\n  it('should handle unmounted elements properly', () => {\n    class Child extends React.Component {\n      render() {\n        if (!this.props.show) return null;\n        return <div />;\n      }\n    }\n\n    class Component extends React.Component {\n      state = { showChild: true };\n\n      componentDidMount() {\n        this.setState({ showChild: false });\n      }\n\n      render() {\n        return (\n          <TransitionGroup appear={true}>\n            <Child show={this.state.showChild} />\n          </TransitionGroup>\n        );\n      }\n    }\n\n    render(<Component />, container);\n\n    // Testing that no exception is thrown here, as the timeout has been cleared.\n    act(() => {\n      jest.runAllTimers();\n    });\n  });\n\n  it('should work with custom component wrapper cloning children', () => {\n    const extraClassNameProp = 'wrapper-item';\n    class Wrapper extends React.Component {\n      render() {\n        return (\n          <div>\n            {React.Children.map(this.props.children, (child) =>\n              React.cloneElement(child, { className: extraClassNameProp })\n            )}\n          </div>\n        );\n      }\n    }\n\n    class Child extends React.Component {\n      render() {\n        return <div {...this.props} />;\n      }\n    }\n\n    class Component extends React.Component {\n      render() {\n        return (\n          <TransitionGroup component={Wrapper}>\n            <Child />\n          </TransitionGroup>\n        );\n      }\n    }\n\n    render(<Component />, container);\n    const transitionGroupDiv = container.childNodes[0];\n    transitionGroupDiv.childNodes.forEach((child) => {\n      expect(hasClass(child, extraClassNameProp)).toBe(true);\n    });\n\n    // Testing that no exception is thrown here, as the timeout has been cleared.\n    act(() => {\n      jest.runAllTimers();\n    });\n  });\n});\n"
  },
  {
    "path": "test/ChildMapping-test.js",
    "content": "let React;\nlet ChildMapping;\n\ndescribe('ChildMapping', () => {\n  beforeEach(() => {\n    React = require('react');\n    ChildMapping = require('../src/utils/ChildMapping');\n  });\n\n  it('should support getChildMapping', () => {\n    let oneone = <div key=\"oneone\" />;\n    let onetwo = <div key=\"onetwo\" />;\n    let one = (\n      <div key=\"one\">\n        {oneone}\n        {onetwo}\n      </div>\n    );\n    let two = <div key=\"two\">foo</div>;\n    let component = (\n      <div>\n        {one}\n        {two}\n      </div>\n    );\n\n    let mapping = ChildMapping.getChildMapping(component.props.children);\n\n    expect(mapping['.$one'].props).toEqual(one.props);\n    expect(mapping['.$two'].props).toEqual(two.props);\n  });\n\n  it('should support mergeChildMappings for adding keys', () => {\n    let prev = {\n      one: true,\n      two: true,\n    };\n    let next = {\n      one: true,\n      two: true,\n      three: true,\n    };\n    expect(ChildMapping.mergeChildMappings(prev, next)).toEqual({\n      one: true,\n      two: true,\n      three: true,\n    });\n  });\n\n  it('should support mergeChildMappings for removing keys', () => {\n    let prev = {\n      one: true,\n      two: true,\n      three: true,\n    };\n    let next = {\n      one: true,\n      two: true,\n    };\n    expect(ChildMapping.mergeChildMappings(prev, next)).toEqual({\n      one: true,\n      two: true,\n      three: true,\n    });\n  });\n\n  it('should support mergeChildMappings for adding and removing', () => {\n    let prev = {\n      one: true,\n      two: true,\n      three: true,\n    };\n    let next = {\n      one: true,\n      two: true,\n      four: true,\n    };\n    expect(ChildMapping.mergeChildMappings(prev, next)).toEqual({\n      one: true,\n      two: true,\n      three: true,\n      four: true,\n    });\n  });\n\n  it('should reconcile overlapping insertions and deletions', () => {\n    let prev = {\n      one: true,\n      two: true,\n      four: true,\n      five: true,\n    };\n    let next = {\n      one: true,\n      two: true,\n      three: true,\n      five: true,\n    };\n    expect(ChildMapping.mergeChildMappings(prev, next)).toEqual({\n      one: true,\n      two: true,\n      three: true,\n      four: true,\n      five: true,\n    });\n  });\n\n  it('should support mergeChildMappings with undefined input', () => {\n    let prev = {\n      one: true,\n      two: true,\n    };\n\n    let next;\n\n    expect(ChildMapping.mergeChildMappings(prev, next)).toEqual({\n      one: true,\n      two: true,\n    });\n\n    prev = undefined;\n\n    next = {\n      three: true,\n      four: true,\n    };\n\n    expect(ChildMapping.mergeChildMappings(prev, next)).toEqual({\n      three: true,\n      four: true,\n    });\n  });\n});\n"
  },
  {
    "path": "test/SSR-test.js",
    "content": "/**\n * @jest-environment node\n */\n\n// test that import does not crash\nimport * as ReactTransitionGroup from '../src'; // eslint-disable-line no-unused-vars\n\ndescribe('SSR', () => {\n  it('should import react-transition-group in node env', () => {});\n});\n"
  },
  {
    "path": "test/SwitchTransition-test.js",
    "content": "import React from 'react';\n\nimport { act, render } from './utils';\n\nimport Transition, { ENTERED } from '../src/Transition';\nimport SwitchTransition from '../src/SwitchTransition';\n\ndescribe('SwitchTransition', () => {\n  let log, Parent;\n  beforeEach(() => {\n    log = [];\n    let events = {\n      onEnter: (m) => log.push(m ? 'appear' : 'enter'),\n      onEntering: (m) => log.push(m ? 'appearing' : 'entering'),\n      onEntered: (m) => log.push(m ? 'appeared' : 'entered'),\n      onExit: () => log.push('exit'),\n      onExiting: () => log.push('exiting'),\n      onExited: () => log.push('exited'),\n    };\n\n    const nodeRef = React.createRef();\n    Parent = function Parent({ on, rendered = true }) {\n      return (\n        <SwitchTransition>\n          {rendered ? (\n            <Transition\n              nodeRef={nodeRef}\n              timeout={0}\n              key={on ? 'first' : 'second'}\n              {...events}\n            >\n              <span ref={nodeRef}>{on ? 'first' : 'second'}</span>\n            </Transition>\n          ) : null}\n        </SwitchTransition>\n      );\n    };\n\n    jest.useFakeTimers();\n  });\n\n  afterEach(() => {\n    jest.useRealTimers();\n  });\n\n  it('should have default status ENTERED', () => {\n    const nodeRef = React.createRef();\n    render(\n      <SwitchTransition>\n        <Transition nodeRef={nodeRef} timeout={0} key=\"first\">\n          {(status) => {\n            return <span ref={nodeRef}>status: {status}</span>;\n          }}\n        </Transition>\n      </SwitchTransition>\n    );\n\n    expect(nodeRef.current.textContent).toBe(`status: ${ENTERED}`);\n  });\n\n  it('should have default mode: out-in', () => {\n    const firstNodeRef = React.createRef();\n    const secondNodeRef = React.createRef();\n    const { rerender } = render(\n      <SwitchTransition>\n        <Transition nodeRef={firstNodeRef} timeout={0} key=\"first\">\n          {(status) => {\n            return <span ref={firstNodeRef}>first status: {status}</span>;\n          }}\n        </Transition>\n      </SwitchTransition>\n    );\n    rerender(\n      <SwitchTransition>\n        <Transition nodeRef={secondNodeRef} timeout={0} key=\"second\">\n          {(status) => {\n            return <span ref={secondNodeRef}>second status: {status}</span>;\n          }}\n        </Transition>\n      </SwitchTransition>\n    );\n\n    expect(firstNodeRef.current.textContent).toBe('first status: exiting');\n    expect(secondNodeRef.current).toBe(null);\n  });\n\n  it('should work without childs', () => {\n    const nodeRef = React.createRef();\n    expect(() => {\n      render(\n        <SwitchTransition>\n          <Transition nodeRef={nodeRef} timeout={0} key=\"first\">\n            <span ref={nodeRef} />\n          </Transition>\n        </SwitchTransition>\n      );\n    }).not.toThrow();\n  });\n\n  it('should switch between components on change state', () => {\n    const { container, setProps } = render(<Parent on={true} />);\n\n    expect(container.textContent).toBe('first');\n    setProps({ on: false });\n    expect(log).toEqual(['exit', 'exiting']);\n    act(() => {\n      jest.runAllTimers();\n    });\n    act(() => {\n      jest.runAllTimers();\n    });\n    expect(log).toEqual([\n      'exit',\n      'exiting',\n      'exited',\n      'enter',\n      'entering',\n      'entered',\n    ]);\n    expect(container.textContent).toBe('second');\n  });\n\n  it('should switch between null and component', () => {\n    const { container, setProps } = render(\n      <Parent on={true} rendered={false} />\n    );\n\n    expect(container.textContent).toBe('');\n\n    jest.useFakeTimers();\n\n    setProps({ rendered: true });\n    act(() => {\n      jest.runAllTimers();\n    });\n    expect(log).toEqual(['enter', 'entering', 'entered']);\n    expect(container.textContent).toBe('first');\n\n    setProps({ on: false, rendered: true });\n    act(() => {\n      jest.runAllTimers();\n    });\n    act(() => {\n      jest.runAllTimers();\n    });\n    expect(log).toEqual([\n      'enter',\n      'entering',\n      'entered',\n      'exit',\n      'exiting',\n      'exited',\n      'enter',\n      'entering',\n      'entered',\n    ]);\n\n    expect(container.textContent).toBe('second');\n  });\n});\n"
  },
  {
    "path": "test/Transition-test.js",
    "content": "import React from 'react';\nimport ReactDOM from 'react-dom';\n\nimport { render, waitFor } from './utils';\n\nimport Transition, {\n  UNMOUNTED,\n  EXITED,\n  ENTERING,\n  ENTERED,\n  EXITING,\n} from '../src/Transition';\n\nexpect.extend({\n  toExist(received) {\n    const pass = received != null;\n    return pass\n      ? {\n          message: () => `expected ${received} to be null or undefined`,\n          pass: true,\n        }\n      : {\n          message: () => `expected ${received} not to be null or undefined`,\n          pass: false,\n        };\n  },\n});\n\ndescribe('Transition', () => {\n  it('should not transition on mount', () => {\n    const nodeRef = React.createRef();\n    render(\n      <Transition\n        in\n        nodeRef={nodeRef}\n        timeout={0}\n        onEnter={() => {\n          throw new Error('should not Enter');\n        }}\n      >\n        {(status) => <div ref={nodeRef}>status: {status}</div>}\n      </Transition>\n    );\n\n    expect(nodeRef.current.textContent).toEqual(`status: ${ENTERED}`);\n  });\n\n  it('should transition on mount with `appear`', (done) => {\n    const nodeRef = React.createRef();\n    render(\n      <Transition\n        in\n        nodeRef={nodeRef}\n        timeout={0}\n        onEnter={() => {\n          throw Error('Animated!');\n        }}\n      >\n        <div ref={nodeRef} />\n      </Transition>\n    );\n\n    render(\n      <Transition\n        nodeRef={nodeRef}\n        in\n        appear\n        timeout={0}\n        onEnter={() => done()}\n      >\n        <div ref={nodeRef} />\n      </Transition>\n    );\n  });\n\n  it('should pass filtered props to children', () => {\n    class Child extends React.Component {\n      render() {\n        return (\n          <div ref={this.props.nodeRef}>\n            foo: {this.props.foo}, bar: {this.props.bar}\n          </div>\n        );\n      }\n    }\n    const nodeRef = React.createRef();\n    render(\n      <Transition\n        foo=\"foo\"\n        bar=\"bar\"\n        in\n        nodeRef={nodeRef}\n        mountOnEnter\n        unmountOnExit\n        appear\n        enter\n        exit\n        timeout={0}\n        addEndListener={() => {}}\n        onEnter={() => {}}\n        onEntering={() => {}}\n        onEntered={() => {}}\n        onExit={() => {}}\n        onExiting={() => {}}\n        onExited={() => {}}\n      >\n        <Child nodeRef={nodeRef} />\n      </Transition>\n    );\n\n    expect(nodeRef.current.textContent).toBe('foo: foo, bar: bar');\n  });\n\n  it('should allow addEndListener instead of timeouts', async () => {\n    let listener = jest.fn((end) => setTimeout(end, 0));\n    let done = false;\n\n    const nodeRef = React.createRef();\n    const { setProps } = render(\n      <Transition\n        nodeRef={nodeRef}\n        addEndListener={listener}\n        onEntered={() => {\n          expect(listener).toHaveBeenCalledTimes(1);\n          done = true;\n        }}\n      >\n        <div ref={nodeRef} />\n      </Transition>\n    );\n\n    setProps({ in: true });\n\n    await waitFor(() => {\n      expect(done).toEqual(true);\n    });\n  });\n\n  it('should fallback to timeouts with addEndListener', async () => {\n    let calledEnd = false;\n    let done = false;\n    let listener = (end) =>\n      setTimeout(() => {\n        calledEnd = true;\n        end();\n      }, 100);\n\n    const nodeRef = React.createRef();\n    const { setProps } = render(\n      <Transition\n        timeout={0}\n        nodeRef={nodeRef}\n        addEndListener={listener}\n        onEntered={() => {\n          expect(calledEnd).toEqual(false);\n          done = true;\n        }}\n      >\n        <div ref={nodeRef} />\n      </Transition>\n    );\n\n    setProps({ in: true });\n\n    await waitFor(() => {\n      expect(done).toEqual(true);\n    });\n  });\n\n  it('should mount/unmount immediately if not have enter/exit timeout', async () => {\n    const nodeRef = React.createRef();\n    let done = false;\n    const { setProps } = render(\n      <Transition nodeRef={nodeRef} in={true} timeout={{}}>\n        {(status) => <div ref={nodeRef}>status: {status}</div>}\n      </Transition>\n    );\n\n    expect(nodeRef.current.textContent).toEqual(`status: ${ENTERED}`);\n    let calledAfterTimeout = false;\n    setTimeout(() => {\n      calledAfterTimeout = true;\n    }, 10);\n    setProps({\n      in: false,\n      onExited() {\n        expect(nodeRef.current.textContent).toEqual(`status: ${EXITED}`);\n        if (calledAfterTimeout) {\n          throw new Error('wrong timeout');\n        }\n        done = true;\n      },\n    });\n\n    await waitFor(() => {\n      expect(done).toEqual(true);\n    });\n  });\n\n  it('should use `React.findDOMNode` when `nodeRef` is not provided', () => {\n    const consoleSpy = jest.spyOn(console, 'error').mockImplementation();\n    const findDOMNodeSpy = jest.spyOn(ReactDOM, 'findDOMNode');\n\n    render(\n      <Transition in appear timeout={0}>\n        <div />\n      </Transition>\n    );\n\n    expect(findDOMNodeSpy).toHaveBeenCalled();\n    findDOMNodeSpy.mockRestore();\n    consoleSpy.mockRestore();\n  });\n\n  it('should not use `React.findDOMNode` when `nodeRef` is provided', () => {\n    const findDOMNodeSpy = jest.spyOn(ReactDOM, 'findDOMNode');\n\n    const nodeRef = React.createRef();\n    render(\n      <Transition nodeRef={nodeRef} in appear timeout={0}>\n        <div ref={nodeRef} />\n      </Transition>\n    );\n\n    expect(findDOMNodeSpy).not.toHaveBeenCalled();\n    findDOMNodeSpy.mockRestore();\n  });\n\n  describe('appearing timeout', () => {\n    it('should use enter timeout if appear not set', async () => {\n      let calledBeforeEntered = false;\n      let done = false;\n      setTimeout(() => {\n        calledBeforeEntered = true;\n      }, 10);\n      const nodeRef = React.createRef();\n      const { setProps } = render(\n        <Transition\n          nodeRef={nodeRef}\n          in={true}\n          timeout={{ enter: 20, exit: 10 }}\n          appear\n        >\n          <div ref={nodeRef} />\n        </Transition>\n      );\n\n      setProps({\n        onEntered() {\n          if (calledBeforeEntered) {\n            done = true;\n          } else {\n            throw new Error('wrong timeout');\n          }\n        },\n      });\n\n      await waitFor(() => {\n        expect(done).toEqual(true);\n      });\n    });\n\n    it('should use appear timeout if appear is set', async () => {\n      let done = false;\n      const nodeRef = React.createRef();\n      const { setProps } = render(\n        <Transition\n          nodeRef={nodeRef}\n          in={true}\n          timeout={{ enter: 20, exit: 10, appear: 5 }}\n          appear\n        >\n          <div ref={nodeRef} />\n        </Transition>\n      );\n\n      let isCausedLate = false;\n      setTimeout(() => {\n        isCausedLate = true;\n      }, 15);\n\n      setProps({\n        onEntered() {\n          if (isCausedLate) {\n            throw new Error('wrong timeout');\n          } else {\n            done = true;\n          }\n        },\n      });\n\n      await waitFor(() => {\n        expect(done).toEqual(true);\n      });\n    });\n  });\n\n  describe('entering', () => {\n    it('should fire callbacks', async () => {\n      let callOrder = [];\n      let done = false;\n      let onEnter = jest.fn(() => callOrder.push('onEnter'));\n      let onEntering = jest.fn(() => callOrder.push('onEntering'));\n      const nodeRef = React.createRef();\n      const { setProps } = render(\n        <Transition nodeRef={nodeRef} timeout={10}>\n          {(status) => <div ref={nodeRef}>status: {status}</div>}\n        </Transition>\n      );\n\n      expect(nodeRef.current.textContent).toEqual(`status: ${EXITED}`);\n\n      setProps({\n        in: true,\n\n        onEnter,\n\n        onEntering,\n\n        onEntered() {\n          expect(onEnter).toHaveBeenCalledTimes(1);\n          expect(onEntering).toHaveBeenCalledTimes(1);\n          expect(callOrder).toEqual(['onEnter', 'onEntering']);\n          done = true;\n        },\n      });\n\n      await waitFor(() => {\n        expect(done).toEqual(true);\n      });\n    });\n\n    it('should move to each transition state', async () => {\n      let count = 0;\n      const nodeRef = React.createRef();\n      const { setProps } = render(\n        <Transition nodeRef={nodeRef} timeout={10}>\n          {(status) => <div ref={nodeRef}>status: {status}</div>}\n        </Transition>\n      );\n\n      expect(nodeRef.current.textContent).toEqual(`status: ${EXITED}`);\n\n      setProps({\n        in: true,\n\n        onEnter() {\n          count++;\n          expect(nodeRef.current.textContent).toEqual(`status: ${EXITED}`);\n        },\n\n        onEntering() {\n          count++;\n          expect(nodeRef.current.textContent).toEqual(`status: ${ENTERING}`);\n        },\n\n        onEntered() {\n          expect(nodeRef.current.textContent).toEqual(`status: ${ENTERED}`);\n        },\n      });\n\n      await waitFor(() => {\n        expect(count).toEqual(2);\n      });\n    });\n  });\n\n  describe('exiting', () => {\n    it('should fire callbacks', async () => {\n      let callOrder = [];\n      let done = false;\n      let onExit = jest.fn(() => callOrder.push('onExit'));\n      let onExiting = jest.fn(() => callOrder.push('onExiting'));\n      const nodeRef = React.createRef();\n      const { setProps } = render(\n        <Transition nodeRef={nodeRef} in timeout={10}>\n          {(status) => <div ref={nodeRef}>status: {status}</div>}\n        </Transition>\n      );\n\n      expect(nodeRef.current.textContent).toEqual(`status: ${ENTERED}`);\n\n      setProps({\n        in: false,\n\n        onExit,\n\n        onExiting,\n\n        onExited() {\n          expect(onExit).toHaveBeenCalledTimes(1);\n          expect(onExiting).toHaveBeenCalledTimes(1);\n          expect(callOrder).toEqual(['onExit', 'onExiting']);\n          done = true;\n        },\n      });\n\n      await waitFor(() => {\n        expect(done).toEqual(true);\n      });\n    });\n\n    it('should move to each transition state', async () => {\n      let count = 0;\n      let done = false;\n      const nodeRef = React.createRef();\n      const { setProps } = render(\n        <Transition nodeRef={nodeRef} in timeout={10}>\n          {(status) => <div ref={nodeRef}>status: {status}</div>}\n        </Transition>\n      );\n\n      expect(nodeRef.current.textContent).toEqual(`status: ${ENTERED}`);\n\n      setProps({\n        in: false,\n\n        onExit() {\n          count++;\n          expect(nodeRef.current.textContent).toEqual(`status: ${ENTERED}`);\n        },\n\n        onExiting() {\n          count++;\n          expect(nodeRef.current.textContent).toEqual(`status: ${EXITING}`);\n        },\n\n        onExited() {\n          expect(nodeRef.current.textContent).toEqual(`status: ${EXITED}`);\n          expect(count).toEqual(2);\n          done = true;\n        },\n      });\n\n      await waitFor(() => {\n        expect(done).toEqual(true);\n      });\n    });\n  });\n\n  describe('mountOnEnter', () => {\n    class MountTransition extends React.Component {\n      nodeRef = React.createRef();\n\n      render() {\n        const { ...props } = this.props;\n        delete props.initialIn;\n\n        return (\n          <Transition\n            ref={(transition) =>\n              (this.transition = this.transition || transition)\n            }\n            nodeRef={this.nodeRef}\n            mountOnEnter\n            in={this.props.in}\n            timeout={10}\n            {...props}\n          >\n            {(status) => <div ref={this.nodeRef}>status: {status}</div>}\n          </Transition>\n        );\n      }\n\n      getStatus = () => {\n        return this.transition.state.status;\n      };\n    }\n\n    it('should mount when entering', (done) => {\n      const { container, setProps } = render(\n        <MountTransition\n          in={false}\n          onEnter={() => {\n            expect(container.textContent).toEqual(`status: ${EXITED}`);\n            done();\n          }}\n        />\n      );\n\n      expect(container.textContent).toEqual('');\n\n      setProps({ in: true });\n    });\n\n    it('should stay mounted after exiting', async () => {\n      let entered = false;\n      let exited = false;\n      const { container, setProps } = render(\n        <MountTransition\n          in={false}\n          onEntered={() => {\n            entered = true;\n          }}\n          onExited={() => {\n            exited = true;\n          }}\n        />\n      );\n\n      expect(container.textContent).toEqual('');\n      setProps({ in: true });\n\n      await waitFor(() => {\n        expect(entered).toEqual(true);\n      });\n      expect(container.textContent).toEqual(`status: ${ENTERED}`);\n\n      setProps({ in: false });\n\n      await waitFor(() => {\n        expect(exited).toEqual(true);\n      });\n      expect(container.textContent).toEqual(`status: ${EXITED}`);\n    });\n  });\n\n  describe('unmountOnExit', () => {\n    class UnmountTransition extends React.Component {\n      nodeRef = React.createRef();\n\n      render() {\n        const { ...props } = this.props;\n        delete props.initialIn;\n\n        return (\n          <Transition\n            ref={(transition) =>\n              (this.transition = this.transition || transition)\n            }\n            nodeRef={this.nodeRef}\n            unmountOnExit\n            in={this.props.in}\n            timeout={10}\n            {...props}\n          >\n            <div ref={this.nodeRef} />\n          </Transition>\n        );\n      }\n\n      getStatus = () => {\n        return this.transition.state.status;\n      };\n    }\n\n    it('should mount when entering', async () => {\n      let done = false;\n      const instanceRef = React.createRef();\n      const { setProps } = render(\n        <UnmountTransition\n          ref={instanceRef}\n          in={false}\n          onEnter={() => {\n            expect(instanceRef.current.getStatus()).toEqual(EXITED);\n            expect(instanceRef.current.nodeRef.current).toExist();\n\n            done = true;\n          }}\n        />\n      );\n\n      expect(instanceRef.current.getStatus()).toEqual(UNMOUNTED);\n      expect(instanceRef.current.nodeRef.current).toBeNull();\n\n      setProps({ in: true });\n\n      await waitFor(() => {\n        expect(done).toEqual(true);\n      });\n    });\n\n    it('should unmount after exiting', async () => {\n      let exited = false;\n      const instanceRef = React.createRef();\n      const { setProps } = render(\n        <UnmountTransition\n          ref={instanceRef}\n          in\n          onExited={() => {\n            setTimeout(() => {\n              exited = true;\n            });\n          }}\n        />\n      );\n\n      expect(instanceRef.current.getStatus()).toEqual(ENTERED);\n      expect(instanceRef.current.nodeRef.current).toExist();\n\n      setProps({ in: false });\n\n      await waitFor(() => {\n        expect(exited).toEqual(true);\n      });\n\n      expect(instanceRef.current.getStatus()).toEqual(UNMOUNTED);\n      expect(instanceRef.current.nodeRef.current).not.toExist();\n    });\n  });\n});\n"
  },
  {
    "path": "test/TransitionGroup-test.js",
    "content": "let React;\nlet TransitionGroup;\nlet Transition;\n\n// Most of the real functionality is covered in other unit tests, this just\n// makes sure we're wired up correctly.\ndescribe('TransitionGroup', () => {\n  let act, container, log, Child, renderStrict, render;\n\n  beforeEach(() => {\n    React = require('react');\n    Transition = require('../src/Transition').default;\n    TransitionGroup = require('../src/TransitionGroup');\n    const testUtils = require('./utils');\n    act = testUtils.act;\n    render = testUtils.render;\n\n    renderStrict = (element, container) =>\n      render(<React.StrictMode>{element}</React.StrictMode>, { container });\n\n    container = document.createElement('div');\n\n    log = [];\n    let events = {\n      onEnter: (m) => log.push(m ? 'appear' : 'enter'),\n      onEntering: (m) => log.push(m ? 'appearing' : 'entering'),\n      onEntered: (m) => log.push(m ? 'appeared' : 'entered'),\n      onExit: () => log.push('exit'),\n      onExiting: () => log.push('exiting'),\n      onExited: () => log.push('exited'),\n    };\n\n    const nodeRef = React.createRef();\n    Child = function Child(props) {\n      return (\n        <Transition nodeRef={nodeRef} timeout={0} {...props} {...events}>\n          <span ref={nodeRef} />\n        </Transition>\n      );\n    };\n  });\n\n  it('should allow null components', () => {\n    function FirstChild(props) {\n      const childrenArray = React.Children.toArray(props.children);\n      return childrenArray[0] || null;\n    }\n\n    render(\n      <TransitionGroup component={FirstChild}>\n        <Child />\n      </TransitionGroup>\n    );\n  });\n\n  it('should allow callback refs', () => {\n    const ref = jest.fn();\n\n    class Child extends React.Component {\n      render() {\n        return <span />;\n      }\n    }\n\n    render(\n      <TransitionGroup>\n        <Child ref={ref} />\n      </TransitionGroup>\n    );\n\n    expect(ref).toHaveBeenCalled();\n  });\n\n  it('should work with no children', () => {\n    renderStrict(<TransitionGroup />, container);\n  });\n\n  it('should handle transitioning correctly', () => {\n    function Parent({ count = 1 }) {\n      let children = [];\n      for (let i = 0; i < count; i++) children.push(<Child key={i} />);\n      return (\n        <TransitionGroup appear enter exit>\n          {children}\n        </TransitionGroup>\n      );\n    }\n\n    jest.useFakeTimers();\n    renderStrict(<Parent />, container);\n\n    act(() => {\n      jest.runAllTimers();\n    });\n    expect(log).toEqual(\n      // React 18 StrictEffects will call `componentDidMount` twice causing two `onEnter` calls.\n      React.useTransition !== undefined\n        ? ['appear', 'appear', 'appearing', 'appeared']\n        : ['appear', 'appearing', 'appeared']\n    );\n\n    log = [];\n    renderStrict(<Parent count={2} />, container);\n    act(() => {\n      jest.runAllTimers();\n    });\n    expect(log).toEqual(\n      // React 18 StrictEffects will call `componentDidMount` twice causing two `onEnter` calls.\n      React.useTransition !== undefined\n        ? ['enter', 'enter', 'entering', 'entered']\n        : ['enter', 'entering', 'entered']\n    );\n\n    log = [];\n    renderStrict(<Parent count={1} />, container);\n    act(() => {\n      jest.runAllTimers();\n    });\n    expect(log).toEqual(['exit', 'exiting', 'exited']);\n  });\n});\n"
  },
  {
    "path": "test/setup.js",
    "content": "global.requestAnimationFrame = function (callback) {\n  setTimeout(callback, 0);\n};\n"
  },
  {
    "path": "test/setupAfterEnv.js",
    "content": "import { cleanup } from '@testing-library/react/pure';\n\nafterEach(() => {\n  cleanup();\n});\n"
  },
  {
    "path": "test/utils.js",
    "content": "import { render as baseRender } from '@testing-library/react/pure';\nimport React from 'react';\n\nexport * from '@testing-library/react';\nexport function render(element, options) {\n  const result = baseRender(element, options);\n\n  return {\n    ...result,\n    setProps(props) {\n      result.rerender(React.cloneElement(element, props));\n    },\n  };\n}\n"
  },
  {
    "path": "www/.babelrc.js",
    "content": "module.exports = {\n  presets: ['babel-preset-gatsby'],\n};\n"
  },
  {
    "path": "www/.gitignore",
    "content": ".cache\npublic"
  },
  {
    "path": "www/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "www/gatsby-config.js",
    "content": "const path = require('path');\n\nmodule.exports = {\n  pathPrefix: `/react-transition-group`,\n  siteMetadata: {\n    title: 'React Transition Group Documentation',\n    author: 'Jason Quense',\n    componentPages: [\n      {\n        path: '/transition',\n        displayName: 'Transition',\n        codeSandboxId: null,\n      },\n      {\n        path: '/css-transition',\n        displayName: 'CSSTransition',\n        codeSandboxId: 'm77l2vp00x',\n      },\n      {\n        path: '/switch-transition',\n        displayName: 'SwitchTransition',\n        codeSandboxId: 'switchtransition-component-iqm0d',\n      },\n      {\n        path: '/transition-group',\n        displayName: 'TransitionGroup',\n        codeSandboxId: '00rqyo26kn',\n      },\n    ],\n  },\n  plugins: [\n    'gatsby-plugin-react-helmet',\n    {\n      resolve: 'gatsby-source-filesystem',\n      options: {\n        path: path.join(__dirname, 'src/pages'),\n        name: 'pages',\n      },\n    },\n    {\n      resolve: 'gatsby-source-filesystem',\n      options: {\n        path: path.join(__dirname, '../src'),\n        name: 'components',\n      },\n    },\n    {\n      resolve: 'gatsby-transformer-remark',\n      options: {\n        plugins: ['gatsby-remark-prismjs'],\n      },\n    },\n    'gatsby-transformer-react-docgen',\n    'gatsby-plugin-sass',\n  ],\n};\n"
  },
  {
    "path": "www/gatsby-node.js",
    "content": "const path = require('path');\nconst config = require('./gatsby-config');\n\nexports.createPages = ({ actions, graphql }) => {\n  const { createPage } = actions;\n  const componentTemplate = path.join(\n    __dirname,\n    'src',\n    'templates',\n    'component.js'\n  );\n  return new Promise((resolve, reject) => {\n    resolve(\n      graphql(`\n        {\n          allComponentMetadata {\n            edges {\n              node {\n                displayName\n              }\n            }\n          }\n        }\n      `).then((result) => {\n        if (result.errors) {\n          reject(result.errors);\n        }\n        const { componentPages } = config.siteMetadata;\n        result.data.allComponentMetadata.edges\n          .filter(({ node: { displayName } }) =>\n            componentPages.some((page) => page.displayName === displayName)\n          )\n          .forEach(({ node: { displayName } }) => {\n            createPage({\n              path: componentPages.find(\n                (page) => page.displayName === displayName\n              ).path,\n              component: componentTemplate,\n              context: {\n                displayName,\n              },\n            });\n          });\n      })\n    );\n  });\n};\n"
  },
  {
    "path": "www/package.json",
    "content": "{\n  \"private\": true,\n  \"name\": \"react-transition-group-docs\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\",\n    \"build\": \"NODE_ENV=production gatsby build --prefix-paths\",\n    \"deploy\": \"npm run build && gh-pages -d public\",\n    \"develop\": \"gatsby develop\"\n  },\n  \"author\": \"\",\n  \"license\": \"MIT\",\n  \"engines\": {\n    \"node\": \"<=16\"\n  },\n  \"dependencies\": {\n    \"@babel/core\": \"^7.3.4\",\n    \"babel-preset-gatsby\": \"^2.7.0\",\n    \"bootstrap\": \"^4.3.1\",\n    \"gatsby\": \"^2.1.22\",\n    \"gatsby-plugin-react-helmet\": \"^3.0.10\",\n    \"gatsby-plugin-sass\": \"^2.0.10\",\n    \"gatsby-remark-prismjs\": \"^3.2.4\",\n    \"gatsby-source-filesystem\": \"^2.0.23\",\n    \"gatsby-transformer-react-docgen\": \"^3.0.5\",\n    \"gatsby-transformer-remark\": \"^2.3.0\",\n    \"lodash\": \"^4.17.19\",\n    \"prismjs\": \"^1.25.0\",\n    \"react\": \"^16.8.3\",\n    \"react-bootstrap\": \"^1.0.0-beta.5\",\n    \"react-dom\": \"^16.8.3\",\n    \"react-helmet\": \"^5.2.0\",\n    \"sass\": \"^1.49.7\"\n  },\n  \"devDependencies\": {\n    \"gh-pages\": \"^2.0.1\"\n  }\n}\n"
  },
  {
    "path": "www/src/components/Example.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Container } from 'react-bootstrap';\n\nconst propTypes = {\n  codeSandbox: PropTypes.shape({\n    title: PropTypes.string.isRequired,\n    id: PropTypes.string.isRequired,\n  }).isRequired,\n};\n\nconst Example = ({ codeSandbox }) => (\n  <div style={{ marginBottom: '1.5rem' }}>\n    <Container>\n      <h2>Example</h2>\n    </Container>\n    <iframe\n      title={codeSandbox.title}\n      src={`https://codesandbox.io/embed/${codeSandbox.id}?fontsize=14`}\n      style={{\n        display: 'block',\n        width: '100%',\n        height: '500px',\n        border: 0,\n        borderRadius: 4,\n        overflow: 'hidden',\n      }}\n      sandbox=\"allow-modals allow-forms allow-popups allow-scripts allow-same-origin\"\n    />\n  </div>\n);\n\nExample.propTypes = propTypes;\n\nexport default Example;\n"
  },
  {
    "path": "www/src/components/Layout.js",
    "content": "import { graphql, Link } from 'gatsby';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport Helmet from 'react-helmet';\n\nimport { Navbar, Nav } from 'react-bootstrap';\n\nimport '../css/bootstrap.scss';\nimport '../css/prism-theme.scss';\n\nconst propTypes = {\n  data: PropTypes.shape({\n    site: PropTypes.shape({\n      siteMetadata: PropTypes.shape({\n        componentPages: PropTypes.arrayOf(\n          PropTypes.shape({\n            path: PropTypes.string.isRequired,\n            displayName: PropTypes.string.isRequired,\n          })\n        ).isRequired,\n      }).isRequired,\n    }).isRequired,\n  }).isRequired,\n  location: PropTypes.shape({\n    pathname: PropTypes.string.isRequired,\n  }).isRequired,\n};\n\nconst Layout = ({ data, children }) => (\n  <>\n    <Helmet>\n      <html lang=\"en\" />\n      <title>React Transition Group</title>\n    </Helmet>\n    <Navbar fixed=\"top\" bg=\"dark\" variant=\"dark\" expand=\"md\" collapseOnSelect>\n      <Navbar.Brand as={Link} to=\"/\">\n        React Transition Group\n      </Navbar.Brand>\n      <Navbar.Toggle />\n      <Navbar.Collapse>\n        <Nav className=\"mr-auto\">\n          {data.site.siteMetadata.componentPages.map(\n            ({ path, displayName }) => (\n              <Nav.Link key={path} as={Link} to={path} activeClassName=\"active\">\n                {displayName}\n              </Nav.Link>\n            )\n          )}\n        </Nav>\n        <Nav>\n          <Nav.Link as={Link} to=\"/with-react-router\" activeClassName=\"active\">\n            With React Router\n          </Nav.Link>\n          <Nav.Link as={Link} to=\"/testing\" activeClassName=\"active\">\n            Testing\n          </Nav.Link>\n        </Nav>\n      </Navbar.Collapse>\n    </Navbar>\n    <div style={{ paddingTop: '5rem' }}>{children}</div>\n  </>\n);\n\nLayout.propTypes = propTypes;\n\nexport default Layout;\n\nexport const exposedComponentsFragment = graphql`\n  fragment Layout_site on Site {\n    siteMetadata {\n      componentPages {\n        path\n        displayName\n        codeSandboxId\n      }\n    }\n  }\n`;\n"
  },
  {
    "path": "www/src/css/_variables.scss",
    "content": "$syntax-hue: 230;\n$syntax-saturation: 1%;\n$syntax-brightness: 98%;\n\n// Monochrome -----------------------------------\n$mono-1: hsl($syntax-hue, 8%, 24%);\n$mono-2: hsl($syntax-hue, 6%, 44%);\n$mono-3: hsl($syntax-hue, 4%, 64%);\n\n$hue-1: hsl(198, 99%, 37%); // <-cyan\n$hue-2: hsl(221, 87%, 60%); // <-blue\n$hue-3: hsl(301, 63%, 40%); // <-purple\n$hue-4: hsl(119, 34%, 47%); // <-green\n\n$hue-5: hsl(5, 74%, 59%); // <-red 1\n$hue-5-2: hsl(344, 84%, 43%); // <-red 2\n\n$hue-6: hsl(41, 99%, 30%); // <-orange 1\n$hue-6-2: hsl(41, 99%, 38%); // <-orange 2\n\n$syntax-fg: $mono-1;\n$syntax-bg: hsl($syntax-hue, $syntax-saturation, $syntax-brightness);\n$syntax-gutter: darken($syntax-bg, 36%);\n$syntax-guide: fade($syntax-fg, 20%);\n$syntax-accent: hsl($syntax-hue, 100%, 66%);\n"
  },
  {
    "path": "www/src/css/bootstrap.scss",
    "content": "@import '~bootstrap/dist/css/bootstrap.css';\n@import 'variables.scss';\n\nhtml {\n  font-size: 16px;\n}\n\nbody {\n  background: $syntax-bg;\n  font-size: 1rem;\n}\n\npre {\n  border: 0;\n  background: transparent;\n}\n\ncode {\n  padding: 0;\n  background: transparent;\n  color: $hue-3;\n  a & {\n    padding: 0;\n    color: inherit !important;\n  }\n}\n\nsection {\n  margin-bottom: 2rem;\n}\n\nh1,\nh2,\nh3,\nh4,\nh5 {\n  margin-bottom: 2rem;\n\n  & > a,\n  & > a:hover {\n    color: inherit;\n  }\n}\n\n// https://twitter.com/hakimel/status/1257252729128435712?s=20\n// https://twitter.com/bramus/status/1257255545897132032?s=20\n:target {\n  scroll-margin-top: 4rem;\n}\n"
  },
  {
    "path": "www/src/css/prism-theme.scss",
    "content": "/*\nName:       Base16 Atelier Sulphurpool Light\nAuthor:     Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/sulphurpool)\nPrism template by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/prism/)\nOriginal Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)\n*/\n@import 'variables.scss';\n\ncode[class*='language-'],\npre[class*='language-'] {\n  font-family: Consolas, Menlo, Monaco, 'Andale Mono WT', 'Andale Mono',\n    'Lucida Console', 'Lucida Sans Typewriter', 'DejaVu Sans Mono',\n    'Bitstream Vera Sans Mono', 'Liberation Mono', 'Nimbus Mono L',\n    'Courier New', Courier, monospace;\n  font-size: 14px;\n  line-height: 1.375;\n  direction: ltr;\n  text-align: left;\n  white-space: pre;\n  word-spacing: normal;\n  word-break: normal;\n  -moz-tab-size: 4;\n  -o-tab-size: 4;\n  tab-size: 4;\n  -webkit-hyphens: none;\n  -moz-hyphens: none;\n  -ms-hyphens: none;\n  hyphens: none;\n  background: $syntax-bg;\n  color: $syntax-fg;\n}\n\npre[class*='language-']::-moz-selection,\npre[class*='language-'] ::-moz-selection,\ncode[class*='language-']::-moz-selection,\ncode[class*='language-'] ::-moz-selection {\n  text-shadow: none;\n  background: darken($syntax-bg, 8%);\n}\n\npre[class*='language-']::selection,\npre[class*='language-'] ::selection,\ncode[class*='language-']::selection,\ncode[class*='language-'] ::selection {\n  text-shadow: none;\n  background: darken($syntax-bg, 8%);\n}\n\n/* Code blocks */\npre[class*='language-'] {\n  padding: 1em;\n  margin: 0.5em 0;\n  overflow: auto;\n}\n\n/* Inline code */\n:not(pre) > code[class*='language-'] {\n  padding: 0.1em;\n  border-radius: 0.3em;\n}\n\n.token.comment,\n.token.prolog,\n.token.doctype,\n.token.cdata {\n  color: $mono-3;\n}\n\n.token.punctuation {\n  color: #5e6687;\n}\n\n.token.namespace {\n  opacity: 0.7;\n}\n\n.token.operator,\n.token.boolean,\n.token.number {\n  color: $hue-6-2;\n}\n\n.token.property {\n  color: $hue-2;\n}\n\n.token.tag {\n  color: $hue-6;\n}\n\n.token.string {\n  color: $hue-4;\n}\n\n.token.function {\n  color: $hue-1;\n}\n\n.token.selector {\n  color: #6679cc;\n}\n\n.token.attr-name {\n  color: $hue-5;\n}\n\n.token.entity,\n.token.url,\n.language-css .token.string,\n.style .token.string {\n  color: $hue-1;\n}\n\n.token.attr-value,\n.token.keyword,\n.token.control,\n.token.directive,\n.token.unit {\n  color: $hue-3;\n}\n\n.token.statement,\n.token.regex,\n.token.atrule {\n  color: $hue-1;\n}\n\n.token.placeholder,\n.token.variable {\n  color: $hue-2;\n}\n\n.token.deleted {\n  text-decoration: line-through;\n}\n\n.token.inserted {\n  border-bottom: 1px dotted #202746;\n  text-decoration: none;\n}\n\n.token.italic {\n  font-style: italic;\n}\n\n.token.important,\n.token.bold {\n  font-weight: bold;\n}\n\n.token.important {\n  color: $hue-5;\n}\n\n.token.entity {\n  cursor: help;\n}\n\npre > code.highlight {\n  outline: 0.4em solid $hue-5;\n  outline-offset: 0.4em;\n}\n\n/* overrides color-values for the Line Numbers plugin\n * http://prismjs.com/plugins/line-numbers/\n */\n.line-numbers .line-numbers-rows {\n  border-right-color: $mono-1;\n}\n\n.line-numbers-rows > span:before {\n  color: $mono-1;\n}\n"
  },
  {
    "path": "www/src/pages/index.js",
    "content": "import { graphql, Link } from 'gatsby';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { Container } from 'react-bootstrap';\nimport Layout from '../components/Layout';\n\nconst propTypes = {\n  location: PropTypes.object.isRequired,\n  data: PropTypes.shape({\n    site: PropTypes.shape({\n      siteMetadata: PropTypes.shape({\n        componentPages: PropTypes.arrayOf(\n          PropTypes.shape({\n            path: PropTypes.string.isRequired,\n            displayName: PropTypes.string.isRequired,\n          })\n        ).isRequired,\n      }).isRequired,\n    }).isRequired,\n  }).isRequired,\n};\n\nclass Index extends React.Component {\n  render() {\n    const { data, location } = this.props;\n\n    return (\n      <Layout data={data} location={location}>\n        <Container>\n          <h1>React Transition Group</h1>\n          <blockquote>\n            <p>\n              Exposes simple components useful for defining entering and exiting\n              transitions. React Transition Group is not an animation library\n              like{' '}\n              <a href=\"https://github.com/chenglou/react-motion\">\n                React-Motion\n              </a>\n              , it does not animate styles by itself. Instead it exposes\n              transition stages, manages classes and group elements and\n              manipulates the DOM in useful ways, making the implementation of\n              actual visual transitions much easier.\n            </p>\n          </blockquote>\n          <section>\n            <h2>Getting Started</h2>\n            <p />\n            <h3 className=\"h4\">Installation</h3>\n            <pre className=\"language-bash\">\n              <code>\n                {`\n# npm\nnpm install react-transition-group --save\n\n# yarn\nyarn add react-transition-group\n              `.trim()}\n              </code>\n            </pre>\n\n            <h3 className=\"h4\">CDN / External</h3>\n            <p>\n              Since react-transition-group is fairly small, the overhead of\n              including the library in your application is negligible. However,\n              in situations where it may be useful to benefit from an external\n              CDN when bundling, link to the following CDN:{' '}\n              <a href=\"https://unpkg.com/react-transition-group/dist/react-transition-group.js\">\n                https://unpkg.com/react-transition-group/dist/react-transition-group.js\n              </a>\n            </p>\n          </section>\n          <h2>Components</h2>\n          <ul>\n            {data.site.siteMetadata.componentPages.map(\n              ({ path, displayName }) => (\n                <li key={path}>\n                  <Link to={path}>{displayName}</Link>\n                </li>\n              )\n            )}\n          </ul>\n        </Container>\n      </Layout>\n    );\n  }\n}\n\nIndex.propTypes = propTypes;\n\nexport default Index;\n\nexport const pageQuery = graphql`\n  query HomeQuery {\n    site {\n      ...Layout_site\n    }\n  }\n`;\n"
  },
  {
    "path": "www/src/pages/testing.js",
    "content": "import { graphql } from 'gatsby';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { Container } from 'react-bootstrap';\nimport Layout from '../components/Layout';\n\nconst propTypes = {\n  location: PropTypes.object.isRequired,\n  data: PropTypes.shape({\n    site: PropTypes.shape({\n      siteMetadata: PropTypes.shape({\n        componentPages: PropTypes.arrayOf(\n          PropTypes.shape({\n            path: PropTypes.string.isRequired,\n            displayName: PropTypes.string.isRequired,\n          })\n        ).isRequired,\n      }).isRequired,\n    }).isRequired,\n  }).isRequired,\n};\n\nconst Testing = ({ data, location }) => (\n  <Layout data={data} location={location}>\n    <Container>\n      <h1>Testing Components with Transitions</h1>\n      <p>\n        In some situations, like visual snapshot testing, it's helpful to\n        disable transitions so they don't complicate the test, or introduce\n        abitrary waits. To make this easier <code>react-transition-group</code>{' '}\n        exposes a way to globally toggle transitions. When set,{' '}\n        <strong>all</strong> transitions, when toggled, will immediately switch\n        to their entered or exited states as appropriate.\n      </p>\n      <pre className=\"language-js\">\n        <code>\n          {`\nimport { config } from 'react-transition-group'\n\nconfig.disabled = true\n              `.trim()}\n        </code>\n      </pre>\n      <blockquote>\n        <p>\n          <b>Note</b>: This <strong>does not</strong> automatically disable\n          animations. It only disabled waits in <code>Transition</code>. You may\n          also have to disable animation as appropriate for the library.\n          example:{' '}\n          <a href=\"http://velocityjs.org/#mock\">Mocking in Velocity.js</a>\n        </p>\n      </blockquote>\n    </Container>\n  </Layout>\n);\n\nTesting.propTypes = propTypes;\n\nexport default Testing;\n\nexport const pageQuery = graphql`\n  query TestingQuery {\n    site {\n      ...Layout_site\n    }\n  }\n`;\n"
  },
  {
    "path": "www/src/pages/with-react-router.js",
    "content": "import { graphql } from 'gatsby';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { Container } from 'react-bootstrap';\nimport Layout from '../components/Layout';\nimport Example from '../components/Example';\n\nconst propTypes = {\n  location: PropTypes.object.isRequired,\n  data: PropTypes.shape({\n    site: PropTypes.shape({\n      siteMetadata: PropTypes.shape({\n        componentPages: PropTypes.arrayOf(\n          PropTypes.shape({\n            path: PropTypes.string.isRequired,\n            displayName: PropTypes.string.isRequired,\n          })\n        ).isRequired,\n      }).isRequired,\n    }).isRequired,\n  }).isRequired,\n};\n\nconst WithReactRouter = ({ data, location }) => (\n  <Layout data={data} location={location}>\n    <Container>\n      <h1>Usage with React Router</h1>\n      <p>\n        People often want to animate route transitions, which can result in\n        delightful UX when used in moderation. The first instinct might be to\n        use wrap all routes in <code>TransitionGroup</code>, but that approach\n        requires hacks and falls apart easily when used with trickier components\n        of React Router like <code>Redirect</code>. You should use{' '}\n        <code>CSSTransition</code> for each route and manage their{' '}\n        <code>in</code> prop on their own.\n      </p>\n      <p>\n        The main challenge is the <strong>exit</strong> transition because React\n        Router changes to a new route instantly, so we need to keep the old\n        route around long enough to transition out of it. Fortunately,{' '}\n        <code>Route</code>\n        's <code>children</code> prop also accepts a <em>function</em>, which\n        should not be confused with the <code>render</code> prop! Unlike the{' '}\n        <code>render</code> prop, <code>children</code> function runs whether\n        the route is matched or not. React Router passes the object containing a{' '}\n        <code>match</code> object, which exists if the route matches, otherwise\n        it's <code>null</code>. This enables us to manage the <code>in</code>{' '}\n        prop of <code>CSSTransition</code> based on the presence of{' '}\n        <code>match</code>.\n      </p>\n      <p>\n        Exit transitions will cause the content of routes to linger until they\n        disappear, which might pose some styling challenges. Make sure that\n        routes don't affect each other's layout, for example you can remove them\n        from the flow of the document by using absolute or fixed positioning.\n      </p>\n      <blockquote>\n        <p>\n          <b>Note</b>: When using React Transition Group with React Router, make\n          sure to avoid using the <code>Switch</code> component because it only\n          executes the first matching <code>Route</code>. This would make the\n          exit transition impossible to achieve because the exiting route will\n          no longer match the current URL and the <code>children</code> function\n          won't execute.\n        </p>\n      </blockquote>\n    </Container>\n    <Example\n      codeSandbox={{\n        title: 'CSSTransition + React Router',\n        id: '38qm5m0mz1',\n      }}\n    />\n  </Layout>\n);\n\nWithReactRouter.propTypes = propTypes;\n\nexport default WithReactRouter;\n\nexport const pageQuery = graphql`\n  query WithReactRouterQuery {\n    site {\n      ...Layout_site\n    }\n  }\n`;\n"
  },
  {
    "path": "www/src/templates/component.js",
    "content": "import { graphql } from 'gatsby';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { Container } from 'react-bootstrap';\nimport transform from 'lodash/transform';\n\nimport Layout from '../components/Layout';\nimport Example from '../components/Example';\n\nfunction displayObj(obj) {\n  return JSON.stringify(obj, null, 2).replace(/\"|'/g, '');\n}\n\nlet cleanDocletValue = (str) =>\n  str.trim().replace(/^\\{/, '').replace(/\\}$/, '');\n\nconst extractMarkdown = ({ description }) =>\n  description &&\n  description.childMarkdownRemark &&\n  description.childMarkdownRemark.html;\n\nconst propTypes = {\n  location: PropTypes.shape({\n    pathname: PropTypes.string.isRequired,\n  }).isRequired,\n  data: PropTypes.shape({\n    site: PropTypes.shape({\n      siteMetadata: PropTypes.shape({\n        componentPages: PropTypes.arrayOf(\n          PropTypes.shape({\n            displayName: PropTypes.string.isRequired,\n            codeSandboxId: PropTypes.string,\n          })\n        ).isRequired,\n      }).isRequired,\n    }).isRequired,\n    metadata: PropTypes.shape({\n      displayName: PropTypes.string,\n      composes: PropTypes.arrayOf(PropTypes.string),\n      description: PropTypes.object.isRequired,\n    }),\n  }).isRequired,\n};\n\nclass ComponentTemplate extends React.Component {\n  render() {\n    const { data, location } = this.props;\n    const { metadata } = data;\n    const { componentPages } = data.site.siteMetadata;\n    const { codeSandboxId } = componentPages.find(\n      (page) => page.displayName === metadata.displayName\n    );\n    return (\n      <Layout data={data} location={location}>\n        <div>\n          <Container>\n            <h1 id={metadata.displayName}>{metadata.displayName}</h1>\n            <div\n              dangerouslySetInnerHTML={{ __html: extractMarkdown(metadata) }}\n            />\n\n            {codeSandboxId != null && (\n              <Example\n                codeSandbox={{\n                  title: `${metadata.displayName} Component`,\n                  id: codeSandboxId,\n                }}\n              />\n            )}\n\n            <h2 id={`${metadata.displayName}-props`}>\n              <a href={`#${metadata.displayName}-props`}>Props</a>\n              {metadata.composes && (\n                <>\n                  {' '}\n                  <small style={{ fontStyle: 'italic', fontSize: '70%' }}>\n                    Accepts all props from{' '}\n                    {metadata.composes\n                      .map((p) => (\n                        <code key={p}>{`<${p.replace('./', '')}>`}</code>\n                      ))\n                      .reduce((acc, el, i) => {\n                        acc.push(el);\n                        if (i < metadata.composes.length - 1) {\n                          acc.push(', ');\n                        }\n                        return acc;\n                      }, [])}{' '}\n                    unless otherwise noted.\n                  </small>\n                </>\n              )}\n            </h2>\n            {metadata.props.map((p) =>\n              this.renderProp(p, metadata.displayName)\n            )}\n          </Container>\n        </div>\n      </Layout>\n    );\n  }\n\n  renderProp = (prop, componentName) => {\n    const { defaultValue, name, required } = prop;\n    let typeInfo = this.renderType(prop);\n    let id = `${componentName}-prop-${name}`;\n\n    return (\n      <section key={name}>\n        <h3 id={id} style={{ marginTop: '1.5rem', marginBottom: '0.5rem' }}>\n          <a href={`#${id}`}>\n            <code>{name}</code>\n          </a>\n        </h3>\n        <div dangerouslySetInnerHTML={{ __html: extractMarkdown(prop) }} />\n\n        <div style={{ paddingLeft: 0 }}>\n          <div>\n            {'type: '}\n            {typeInfo && typeInfo.type === 'pre' ? (\n              typeInfo\n            ) : (\n              <code>{typeInfo}</code>\n            )}\n          </div>\n          {required && <div>required</div>}\n          {defaultValue && (\n            <div>\n              default: <code>{defaultValue.value.trim()}</code>\n            </div>\n          )}\n        </div>\n      </section>\n    );\n  };\n\n  renderType(prop) {\n    let type = prop.type || {};\n    let name = getDisplayTypeName(type.name);\n    let doclets = prop.doclets || {};\n\n    switch (name) {\n      case 'node':\n        return 'any';\n      case 'function':\n        return 'Function';\n      case 'elementType':\n        return 'ReactClass<any>';\n      case 'dateFormat':\n        return 'string | (date: Date, culture: ?string, localizer: Localizer) => string';\n      case 'dateRangeFormat':\n        return '(range: { start: Date, end: Date }, culture: ?string, localizer: Localizer) => string';\n      case 'object':\n      case 'Object':\n        if (type.value)\n          return (\n            <pre className=\"shape-prop\">\n              {displayObj(renderObject(type.value))}\n            </pre>\n          );\n\n        return name;\n      case 'union':\n        return type.value.reduce((current, val, i, list) => {\n          val = typeof val === 'string' ? { name: val } : val;\n          let item = this.renderType({ type: val });\n\n          if (React.isValidElement(item)) {\n            item = React.cloneElement(item, { key: i });\n          }\n\n          current = current.concat(item);\n\n          return i === list.length - 1 ? current : current.concat(' | ');\n        }, []);\n      case 'array':\n      case 'Array': {\n        let child = this.renderType({ type: type.value });\n\n        return (\n          <span>\n            {'Array<'}\n            {child}\n            {'>'}\n          </span>\n        );\n      }\n      case 'enum':\n        return this.renderEnum(type);\n      case 'custom':\n        return cleanDocletValue(doclets.type || name);\n      default:\n        return name;\n    }\n  }\n\n  renderEnum(enumType) {\n    const enumValues = enumType.value || [];\n    return <code>{enumValues.join(' | ')}</code>;\n  }\n}\n\nComponentTemplate.propTypes = propTypes;\n\nfunction getDisplayTypeName(typeName) {\n  if (typeName === 'func') {\n    return 'function';\n  } else if (typeName === 'bool') {\n    return 'boolean';\n  } else if (typeName === 'object') {\n    return 'Object';\n  }\n\n  return typeName;\n}\n\nfunction renderObject(props) {\n  return transform(\n    props,\n    (obj, val, key) => {\n      obj[val.required ? key : key + '?'] = simpleType(val);\n    },\n    {}\n  );\n}\n\nfunction simpleType(prop) {\n  let type = prop.type || {};\n  let name = getDisplayTypeName(type.name);\n  let doclets = prop.doclets || {};\n\n  switch (name) {\n    case 'node':\n      return 'any';\n    case 'function':\n      return 'Function';\n    case 'elementType':\n      return 'ReactClass<any>';\n    case 'object':\n    case 'Object':\n      if (type.value) return renderObject(type.value);\n      return name;\n    case 'array':\n    case 'Array': {\n      let child = simpleType({ type: type.value });\n\n      return 'Array<' + child + '>';\n    }\n    case 'custom':\n      return cleanDocletValue(doclets.type || name);\n    default:\n      return name;\n  }\n}\n\nexport const query = graphql`\n  query ComponentMetadata($displayName: String!) {\n    site {\n      ...Layout_site\n    }\n    metadata: componentMetadata(displayName: { eq: $displayName }) {\n      displayName\n      composes\n      description: childComponentDescription {\n        childMarkdownRemark {\n          html\n        }\n      }\n      props {\n        name\n        required\n        type {\n          name\n          value\n          raw\n        }\n        defaultValue {\n          value\n          computed\n        }\n        description: childComponentDescription {\n          childMarkdownRemark {\n            html\n          }\n        }\n        doclets\n      }\n    }\n  }\n`;\n\nexport default ComponentTemplate;\n"
  }
]