[
  {
    "path": ".dumirc.ts",
    "content": "// more config: https://d.umijs.org/config\nimport { defineConfig } from 'dumi';\n\nexport default defineConfig({\n  favicons: ['https://avatars0.githubusercontent.com/u/9441414?s=200&v=4'],\n  themeConfig: {\n    name: 'rc-dropdown',\n    logo: 'https://avatars0.githubusercontent.com/u/9441414?s=200&v=4',\n  },\n  outputPath: '.docs',\n  exportStatic: {},\n  styles: [\n    `\n      section.dumi-default-header-left  {\n        width: 240px;\n      }\n    `,\n  ],\n});\n"
  },
  {
    "path": ".editorconfig",
    "content": "# top-most EditorConfig file\nroot = true\n\n# Unix-style newlines with a newline ending every file\n[*.{js,css}]\nend_of_line = lf\ninsert_final_newline = true\nindent_style = space\nindent_size = 2\n"
  },
  {
    "path": ".eslintrc.js",
    "content": "const base = require('@umijs/fabric/dist/eslint');\n\nmodule.exports = {\n  ...base,\n  rules: {\n    ...base.rules,\n    'no-template-curly-in-string': 0,\n    'prefer-promise-reject-errors': 0,\n    'react/no-array-index-key': 0,\n    'react/sort-comp': 0,\n    '@typescript-eslint/no-explicit-any': 0,\n    'jsx-a11y/label-has-associated-control': 0,\n    'jsx-a11y/label-has-for': 0,\n    'no-shadow': 0\n  },\n};\n"
  },
  {
    "path": ".fatherrc.ts",
    "content": "import { defineConfig } from \"father\";\n\nexport default defineConfig({\n  plugins: [\"@rc-component/father-plugin\"],\n});\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where the package manifests are located.\n# Please see the documentation for all configuration options:\n# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file\n\nversion: 2\nupdates:\n  - package-ecosystem: \"\" # See documentation for possible values\n    directory: \"/\" # Location of package manifests\n    schedule:\n      interval: \"weekly\"\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: CI\n\non: ['push', 'pull_request']\n\njobs:\n  CI:\n    uses: react-component/rc-test/.github/workflows/test.yml@main\n    secrets: inherit\n"
  },
  {
    "path": ".github/workflows/codeql.yml",
    "content": "name: \"CodeQL\"\n\non:\n  push:\n    branches: [ \"master\" ]\n  pull_request:\n    branches: [ \"master\" ]\n  schedule:\n    - cron: \"38 3 * * 6\"\n\njobs:\n  analyze:\n    name: Analyze\n    runs-on: ubuntu-latest\n    permissions:\n      actions: read\n      contents: read\n      security-events: write\n\n    strategy:\n      fail-fast: false\n      matrix:\n        language: [ javascript ]\n\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v3\n\n      - name: Initialize CodeQL\n        uses: github/codeql-action/init@v2\n        with:\n          languages: ${{ matrix.language }}\n          queries: +security-and-quality\n\n      - name: Autobuild\n        uses: github/codeql-action/autobuild@v2\n\n      - name: Perform CodeQL Analysis\n        uses: github/codeql-action/analyze@v2\n        with:\n          category: \"/language:${{ matrix.language }}\"\n"
  },
  {
    "path": ".gitignore",
    "content": "*.iml\n*.log\n.idea/\n.ipr\n.iws\n*~\n~*\n*.diff\n*.patch\n*.bak\n.DS_Store\nThumbs.db\n.project\n.*proj\n.svn/\n*.swp\n*.swo\n*.pyc\n*.pyo\n.build\nnode_modules\n.cache\ndist\nassets/**/*.css\nbuild\nlib\nes\ncoverage\nyarn.lock\npackage-lock.json\npnpm-lock.yaml\n.vscode\n\n# dumi\n.dumi/tmp\n.dumi/tmp-test\n.dumi/tmp-production\n.docs\n"
  },
  {
    "path": ".husky/pre-commit",
    "content": "#!/usr/bin/env sh\n. \"$(dirname -- \"$0\")/_/husky.sh\"\n\nnpx lint-staged\n"
  },
  {
    "path": ".prettierrc",
    "content": "{\n  \"endOfLine\": \"lf\",\n  \"semi\": true,\n  \"singleQuote\": true,\n  \"tabWidth\": 2,\n  \"trailingComma\": \"all\",\n  \"proseWrap\": \"never\"\n}\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\n\nnode_js:\n  - 10\n\nscript:\n  - |\n    if [ \"$TEST_TYPE\" = test ]; then\n      npm run coverage && \\\n      bash <(curl -s https://codecov.io/bash)\n    else\n      npm run $TEST_TYPE\n    fi\nenv:\n  matrix:\n    - TEST_TYPE=lint\n    - TEST_TYPE=test\n"
  },
  {
    "path": "HISTORY.md",
    "content": "# History\n----\n\n## 2.4.0 / 2018-12-28\n\n- `overlay` support function render\n\n## 2.3.0 / 2018-12-21\n\n- add `openClassName`\n\n## 2.2.0 / 2018-06-06\n\n- add `alignPoint` to support mosue point align\n\n## 1.5.0 / 2016-07-27\n\n- Add `onOverlayClick`.\n\n-\n\n## 1.4.5 / 2016-03-02\n\n- if exists getPopupContainer it will be passed to Trigger component\n\n## 1.4.0 / 2015-10-26\n\n- update for react 0.14\n\n## 1.2.0 / 2015-06-07\n\n- remove closeOnSelect, use visible prop to control\n\n## 0.8.0 / 2015-06-07\n\nAlready available\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\nCopyright (c) 2015-present Alipay.com, https://www.alipay.com/\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS \nOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF \nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. \nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY \nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, \nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE \nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# @rc-component/dropdown\n\nreact dropdown component.\n\n[![NPM version][npm-image]][npm-url] [![npm download][download-image]][download-url] [![build status][github-actions-image]][github-actions-url] [![Codecov][codecov-image]][codecov-url] [![bundle size][bundlephobia-image]][bundlephobia-url] [![dumi][dumi-image]][dumi-url]\n\n[npm-image]: https://img.shields.io/npm/v/@rc-component/dropdown.svg?style=flat-square\n[npm-url]: https://npmjs.org/package/@rc-component/dropdown\n[travis-image]: https://img.shields.io/travis/react-component/dropdown/master?style=flat-square\n[travis-url]: https://travis-ci.com/react-component/dropdown\n[github-actions-image]: https://github.com/react-component/dropdown/actions/workflows/ci.yml/badge.svg\n[github-actions-url]: https://github.com/react-component/dropdown/actions/workflows/ci.yml\n[codecov-image]: https://img.shields.io/codecov/c/github/react-component/dropdown/master.svg?style=flat-square\n[codecov-url]: https://app.codecov.io/gh/react-component/dropdown\n[david-url]: https://david-dm.org/react-component/dropdown\n[david-image]: https://david-dm.org/react-component/dropdown/status.svg?style=flat-square\n[david-dev-url]: https://david-dm.org/react-component/dropdown?type=dev\n[david-dev-image]: https://david-dm.org/react-component/dropdown/dev-status.svg?style=flat-square\n[download-image]: https://img.shields.io/npm/dm/@rc-component/dropdown.svg?style=flat-square\n[download-url]: https://npmjs.org/package/@rc-component/dropdown\n[bundlephobia-url]: https://bundlephobia.com/package/@rc-component/dropdown\n[bundlephobia-image]: https://badgen.net/bundlephobia/minzip/@rc-component/dropdown\n[dumi-url]: https://github.com/umijs/dumi\n[dumi-image]: https://img.shields.io/badge/docs%20by-dumi-blue?style=flat-square\n\n## Screenshot\n\n![](https://t.alipayobjects.com/images/rmsweb/T1bWpgXgBaXXXXXXXX.png)\n\n## Example\n\nonline example: http://react-component.github.io/dropdown/examples/\n\n## install\n\n[![@rc-component/dropdown](https://nodei.co/npm/@rc-component/dropdown.png)](https://npmjs.org/package/@rc-component/dropdown)\n\n## Usage\n\n```js\nvar Dropdown = require('@rc-component/dropdown');\n// use dropdown\n```\n\n## API\n\n### props\n\n<table class=\"table table-bordered table-striped\">\n    <thead>\n    <tr>\n        <th style=\"width: 100px;\">name</th>\n        <th style=\"width: 50px;\">type</th>\n        <th style=\"width: 50px;\">default</th>\n        <th>description</th>\n    </tr>\n    </thead>\n    <tbody>\n        <tr>\n          <td>overlayClassName</td>\n          <td>String</td>\n          <td></td>\n          <td>additional css class of root dom node</td>\n        </tr>\n        <tr>\n          <td>openClassName</td>\n          <td>String</td>\n          <td>`${prefixCls}-open`</td>\n          <td>className of trigger when dropdown is opened</td>\n        </tr>\n        <tr>\n          <td>prefixCls</td>\n          <td>String</td>\n          <td>rc-dropdown</td>\n          <td>prefix class name</td>\n        </tr>\n        <tr>\n          <td>transitionName</td>\n          <td>String</td>\n          <td></td>\n          <td>dropdown menu's animation css class name</td>\n        </tr>\n        <tr>\n          <td>animation</td>\n          <td>String</td>\n          <td></td>\n          <td>part of dropdown menu's animation css class name</td>\n        </tr>\n        <tr>\n          <td>placement</td>\n          <td>String</td>\n          <td>bottomLeft</td>\n          <td>Position of menu item. There are: top, topCenter, topRight, bottomLeft, bottom, bottomRight </td>\n        </tr>\n        <tr>\n          <td>onVisibleChange</td>\n          <td>Function</td>\n          <td></td>\n          <td>call when visible is changed</td>\n        </tr>\n        <tr>\n          <td>visible</td>\n          <td>boolean</td>\n          <td></td>\n          <td>whether tooltip is visible</td>\n        </tr>\n        <tr>\n          <td>defaultVisible</td>\n          <td>boolean</td>\n          <td></td>\n          <td>whether tooltip is visible initially</td>\n        </tr>\n        <tr>\n          <td>overlay</td>\n          <td>rc-menu</td>\n          <td></td>\n          <td><a href=\"https://github.com/react-component/menu\">rc-menu</a> element</td>\n        </tr>\n        <tr>\n          <td>onOverlayClick</td>\n          <td>function(e)</td>\n          <td></td>\n          <td>call when overlay is clicked</td>\n        </tr>\n        <tr>\n          <td>minOverlayWidthMatchTrigger</td>\n          <td>boolean</td>\n          <td>true (false when set alignPoint)</td>\n          <td>whether overlay's width must not be less than trigger's </td>\n        </tr>\n        <tr>\n          <td>getPopupContainer</td>\n          <td>Function(menuDOMNode): HTMLElement</td>\n          <th>() => document.body</th>\n          <td>Where to render the DOM node of dropdown</td>\n        </tr>\n    </tbody>\n</table>\n\nNote: Additional props are passed into the underlying [rc-trigger](https://github.com/react-component/trigger) component. This can be useful for example, to display the dropdown in a separate [portal](https://reactjs.org/docs/portals.html)-driven window via the `getDocument()` rc-trigger prop.\n\n## Development\n\n```bash\nnpm install\nnpm start\n```\n\n## Test Case\n\n```bash\nnpm test\nnpm run chrome-test\n```\n\n## Coverage\n\n```bash\nnpm run coverage\n```\n\nopen coverage/ dir\n\n## License\n\n@rc-component/dropdown is released under the MIT license.\n"
  },
  {
    "path": "assets/index.less",
    "content": "@dropdownPrefixCls: rc-dropdown;\n\n@dropdown-arrow-width: 8px;\n@dropdown-distance: @dropdown-arrow-width + 4;\n@dropdown-arrow-color: #373737;\n@dropdown-overlay-shadow: 0 1px 5px #ccc;\n\n@font-face {\n  font-family: 'anticon';\n  src: url('//at.alicdn.com/t/font_1434092639_4910953.eot');\n  /* IE9*/\n  src: url('//at.alicdn.com/t/font_1434092639_4910953.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ url('//at.alicdn.com/t/font_1434092639_4910953.woff') format('woff'), /* chrome、firefox */ url('//at.alicdn.com/t/font_1434092639_4910953.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/ url('//at.alicdn.com/t/font_1434092639_4910953.svg#iconfont') format('svg');\n  /* iOS 4.1- */\n}\n\n.@{dropdownPrefixCls} {\n  position: absolute;\n  left: -9999px;\n  top: -9999px;\n  z-index: 1070;\n  display: block;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 1.5;\n\n  &-hidden {\n    display: none;\n  }\n\n  .rc-menu {\n    outline: none;\n    position: relative;\n    list-style-type: none;\n    padding: 0;\n    margin: 2px 0 2px;\n    text-align: left;\n    background-color: #fff;\n    border-radius: 3px;\n    box-shadow: @dropdown-overlay-shadow;\n    background-clip: padding-box;\n    border: 1px solid #ccc;\n\n    > li {\n      margin: 0;\n      padding: 0;\n    }\n\n    &:before {\n      content: \"\";\n      position: absolute;\n      top: -4px;\n      left: 0;\n      width: 100%;\n      height: 4px;\n      background: rgb(255, 255, 255);\n      background: rgba(255, 255, 255, 0.01);\n    }\n\n    & > &-item {\n      position: relative;\n      display: block;\n      padding: 7px 10px;\n      clear: both;\n      font-size: 12px;\n      font-weight: normal;\n      color: #666666;\n      white-space: nowrap;\n\n      &:hover, &-active, &-selected {\n        background-color: #ebfaff;\n      }\n\n      &-selected {\n        position: relative;\n        &:after {\n          content: '\\e613';\n          font-family: 'anticon';\n          font-weight: bold;\n          position: absolute;\n          top: 6px;\n          right: 16px;\n          color: #3CB8F0;\n        }\n      }\n\n      &-disabled {\n        color: #ccc;\n        cursor: not-allowed;\n        pointer-events: none;\n\n        &:hover {\n          color: #ccc;\n          background-color: #fff;\n          cursor: not-allowed;\n        }\n      }\n\n      &:last-child {\n        border-bottom-left-radius: 3px;\n        border-bottom-right-radius: 3px;\n      }\n\n      &:first-child {\n        border-top-left-radius: 3px;\n        border-top-right-radius: 3px;\n      }\n\n      &-divider {\n        height: 1px;\n        margin: 1px 0;\n        overflow: hidden;\n        background-color: #e5e5e5;\n        line-height: 0;\n      }\n    }\n  }\n\n  .effect() {\n    animation-duration: 0.3s;\n    animation-fill-mode: both;\n    transform-origin: 0 0;\n    display: block !important;\n  }\n\n  &-slide-up-enter,&-slide-up-appear {\n    .effect();\n    opacity: 0;\n    animation-timing-function: cubic-bezier(0.08, 0.82, 0.17, 1);\n    animation-play-state: paused;\n  }\n\n  &-slide-up-leave {\n    .effect();\n    opacity: 1;\n    animation-timing-function: cubic-bezier(0.6, 0.04, 0.98, 0.34);\n    animation-play-state: paused;\n  }\n\n  &-slide-up-enter&-slide-up-enter-active&-placement-bottomLeft,\n  &-slide-up-appear&-slide-up-appear-active&-placement-bottomLeft,\n  &-slide-up-enter&-slide-up-enter-active&-placement-bottomCenter,\n  &-slide-up-appear&-slide-up-appear-active&-placement-bottomCenter,\n  &-slide-up-enter&-slide-up-enter-active&-placement-bottomRight,\n  &-slide-up-appear&-slide-up-appear-active&-placement-bottomRight {\n    animation-name: rcDropdownSlideUpIn;\n    animation-play-state: running;\n  }\n\n  &-slide-up-enter&-slide-up-enter-active&-placement-topLeft,\n  &-slide-up-appear&-slide-up-appear-active&-placement-topLeft,\n  &-slide-up-enter&-slide-up-enter-active&-placement-topCenter,\n  &-slide-up-appear&-slide-up-appear-active&-placement-topCenter,\n  &-slide-up-enter&-slide-up-enter-active&-placement-topRight,\n  &-slide-up-appear&-slide-up-appear-active&-placement-topRight {\n    animation-name: rcDropdownSlideDownIn;\n    animation-play-state: running;\n  }\n\n  &-slide-up-leave&-slide-up-leave-active&-placement-bottomLeft,\n  &-slide-up-leave&-slide-up-leave-active&-placement-bottomCenter,\n  &-slide-up-leave&-slide-up-leave-active&-placement-bottomRight {\n    animation-name: rcDropdownSlideUpOut;\n    animation-play-state: running;\n  }\n\n  &-slide-up-leave&-slide-up-leave-active&-placement-topLeft,\n  &-slide-up-leave&-slide-up-leave-active&-placement-topCenter,\n  &-slide-up-leave&-slide-up-leave-active&-placement-topRight {\n    animation-name: rcDropdownSlideDownOut;\n    animation-play-state: running;\n  }\n\n  @keyframes rcDropdownSlideUpIn {\n    0% {\n      opacity: 0;\n      transform-origin: 0% 0%;\n      transform: scaleY(0);\n    }\n    100% {\n      opacity: 1;\n      transform-origin: 0% 0%;\n      transform: scaleY(1);\n    }\n  }\n  @keyframes rcDropdownSlideUpOut {\n    0% {\n      opacity: 1;\n      transform-origin: 0% 0%;\n      transform: scaleY(1);\n    }\n    100% {\n      opacity: 0;\n      transform-origin: 0% 0%;\n      transform: scaleY(0);\n    }\n  }\n\n  @keyframes rcDropdownSlideDownIn {\n    0% {\n      opacity: 0;\n      transform-origin: 0% 100%;\n      transform: scaleY(0);\n    }\n    100% {\n      opacity: 1;\n      transform-origin: 0% 100%;\n      transform: scaleY(1);\n    }\n  }\n  @keyframes rcDropdownSlideDownOut {\n    0% {\n      opacity: 1;\n      transform-origin: 0% 100%;\n      transform: scaleY(1);\n    }\n    100% {\n      opacity: 0;\n      transform-origin: 0% 100%;\n      transform: scaleY(0);\n    }\n  }\n}\n\n// arrows\n.@{dropdownPrefixCls}-arrow {\n  position: absolute;\n  border-width: @dropdown-arrow-width / 2;\n  border-color: transparent;\n  box-shadow: @dropdown-overlay-shadow;\n  border-style: solid;\n  transform: rotate(45deg);\n}\n\n.@{dropdownPrefixCls} {\n  // adjust padding\n  &-show-arrow&-placement-top,\n  &-show-arrow&-placement-topLeft,\n  &-show-arrow&-placement-topRight {\n    padding-bottom: 6px;\n  }\n\n  &-show-arrow&-placement-bottom,\n  &-show-arrow&-placement-bottomLeft,\n  &-show-arrow&-placement-bottomRight {\n    padding-top: 6px;\n  }\n\n  // top-*\n  &-placement-top &-arrow,\n  &-placement-topLeft &-arrow,\n  &-placement-topRight &-arrow {\n    bottom: @dropdown-distance - @dropdown-arrow-width;\n    border-top-color: white;\n  }\n\n  &-placement-top &-arrow {\n    left: 50%;\n  }\n\n  &-placement-topLeft &-arrow {\n    left: 15%;\n  }\n\n  &-placement-topRight &-arrow {\n    right: 15%;\n  }\n\n  // bottom-*\n  &-placement-bottom &-arrow,\n  &-placement-bottomLeft &-arrow,\n  &-placement-bottomRight &-arrow {\n    top: @dropdown-distance - @dropdown-arrow-width;\n    border-bottom-color: white;\n  }\n\n  &-placement-bottom &-arrow {\n    left: 50%;\n  }\n\n  &-placement-bottomLeft &-arrow {\n    left: 15%;\n  }\n\n  &-placement-bottomRight &-arrow {\n    right: 15%;\n  }\n}\n"
  },
  {
    "path": "docs/demo/arrow.md",
    "content": "---\ntitle: arrow\nnav:\n  title: Demo\n  path: /demo\n---\n\n<code src=\"../examples/arrow.jsx\"></code>\n"
  },
  {
    "path": "docs/demo/context-menu.md",
    "content": "---\ntitle: context-menu\nnav:\n  title: Demo\n  path: /demo\n---\n\n<code src=\"../examples/context-menu.jsx\"></code>\n"
  },
  {
    "path": "docs/demo/dropdown-menu-width.md",
    "content": "---\ntitle: dropdown-menu-width\nnav:\n  title: Demo\n  path: /demo\n---\n\n<code src=\"../examples/dropdown-menu-width.jsx\"></code>\n"
  },
  {
    "path": "docs/demo/multiple.md",
    "content": "---\ntitle: multiple\nnav:\n  title: Demo\n  path: /demo\n---\n\n<code src=\"../examples/multiple.jsx\"></code>\n"
  },
  {
    "path": "docs/demo/overlay-callback.md",
    "content": "---\ntitle: overlay-callback\nnav:\n  title: Demo\n  path: /demo\n---\n\n<code src=\"../examples/overlay-callback.jsx\"></code>\n"
  },
  {
    "path": "docs/demo/simple.md",
    "content": "---\ntitle: simple\nnav:\n  title: Demo\n  path: /demo\n---\n\n<code src=\"../examples/simple.jsx\"></code>\n"
  },
  {
    "path": "docs/examples/arrow.jsx",
    "content": "import Dropdown from '@rc-component/dropdown';\nimport Menu, { Divider, Item as MenuItem } from '@rc-component/menu';\nimport React from 'react';\nimport '../../assets/index.less';\n\nfunction onSelect({ key }) {\n  console.log(`${key} selected`);\n}\n\nfunction onVisibleChange(visible) {\n  console.log(visible);\n}\n\nconst menu = (\n  <Menu onSelect={onSelect}>\n    <MenuItem disabled>disabled</MenuItem>\n    <MenuItem key=\"1\">one</MenuItem>\n    <Divider />\n    <MenuItem key=\"2\">two</MenuItem>\n  </Menu>\n);\n\nexport default function Arrow() {\n  return (\n    <div style={{ margin: 20 }}>\n      <div style={{ height: 100 }} />\n      <div>\n        <Dropdown\n          arrow\n          trigger={['click']}\n          overlay={menu}\n          animation=\"slide-up\"\n          onVisibleChange={onVisibleChange}\n        >\n          <button style={{ width: 100 }}>open</button>\n        </Dropdown>\n      </div>\n      <div>\n        <Dropdown\n          placement=\"topLeft\"\n          arrow\n          trigger={['click']}\n          overlay={menu}\n          animation=\"slide-up\"\n          onVisibleChange={onVisibleChange}\n        >\n          <button style={{ width: 100 }}>open</button>\n        </Dropdown>\n      </div>\n    </div>\n  );\n}\n"
  },
  {
    "path": "docs/examples/context-menu.jsx",
    "content": "import Dropdown from '@rc-component/dropdown';\nimport Menu, { Item as MenuItem } from '@rc-component/menu';\nimport React from 'react';\nimport '../../assets/index.less';\n\nfunction ContextMenu() {\n  const menu = (\n    <Menu style={{ width: 140 }}>\n      <MenuItem key=\"1\">one</MenuItem>\n      <MenuItem key=\"2\">two</MenuItem>\n    </Menu>\n  );\n\n  return (\n    <Dropdown\n      trigger={['contextMenu']}\n      overlay={menu}\n      animation=\"slide-up\"\n      alignPoint\n    >\n      <div\n        role=\"button\"\n        style={{\n          border: '1px solid #000',\n          padding: '100px 0',\n          textAlign: 'center',\n        }}\n      >\n        Right click me!\n      </div>\n    </Dropdown>\n  );\n}\n\nexport default ContextMenu;\n"
  },
  {
    "path": "docs/examples/dropdown-menu-width.jsx",
    "content": "import Dropdown from '@rc-component/dropdown';\nimport Menu, { Item as MenuItem } from '@rc-component/menu';\nimport React, { PureComponent } from 'react';\nimport '../../assets/index.less';\n\nclass Example extends PureComponent {\n  state = { longList: false };\n\n  short = () => {\n    this.setState({ longList: false });\n  };\n\n  long = () => {\n    this.setState({ longList: true });\n  };\n\n  render() {\n    const menuItems = [\n      <MenuItem key=\"1\">1st item</MenuItem>,\n      <MenuItem key=\"2\">2nd item</MenuItem>,\n    ];\n\n    if (this.state.longList) {\n      menuItems.push(<MenuItem key=\"3\">3rd LONG SUPER LONG item</MenuItem>);\n    }\n    const menu = <Menu>{menuItems}</Menu>;\n    return (\n      <div>\n        <Dropdown overlay={menu}>\n          <button>Actions</button>\n        </Dropdown>\n        <button onClick={this.long}>Long List</button>\n        <button onClick={this.short}>Short List</button>\n      </div>\n    );\n  }\n}\n\nexport default Example;\n"
  },
  {
    "path": "docs/examples/multiple.jsx",
    "content": "import Dropdown from '@rc-component/dropdown';\nimport Menu, { Divider, Item as MenuItem } from '@rc-component/menu';\nimport React, { Component } from 'react';\nimport '../../assets/index.less';\n\nclass Test extends Component {\n  state = {\n    visible: false,\n  };\n\n  onVisibleChange = (visible) => {\n    console.log('visible', visible);\n    this.setState({\n      visible,\n    });\n  };\n\n  selected = [];\n\n  saveSelected = ({ selectedKeys }) => {\n    this.selected = selectedKeys;\n  };\n\n  confirm = () => {\n    console.log(this.selected);\n    this.setState({\n      visible: false,\n    });\n  };\n\n  render() {\n    const menu = (\n      <Menu\n        style={{ width: 140 }}\n        multiple\n        onSelect={this.saveSelected}\n        onDeselect={this.saveSelected}\n      >\n        <MenuItem key=\"1\">one</MenuItem>\n        <MenuItem key=\"2\">two</MenuItem>\n        <Divider />\n        <MenuItem disabled>\n          <button\n            style={{\n              cursor: 'pointer',\n              color: '#000',\n              pointerEvents: 'visible',\n            }}\n            onClick={this.confirm}\n          >\n            确定\n          </button>\n        </MenuItem>\n      </Menu>\n    );\n\n    return (\n      <Dropdown\n        trigger={['click']}\n        onVisibleChange={this.onVisibleChange}\n        visible={this.state.visible}\n        closeOnSelect={false}\n        overlay={menu}\n        animation=\"slide-up\"\n      >\n        <button>open</button>\n      </Dropdown>\n    );\n  }\n}\n\nexport default Test;\n"
  },
  {
    "path": "docs/examples/overlay-callback.jsx",
    "content": "import Dropdown from '@rc-component/dropdown';\nimport Menu, { Divider, Item as MenuItem } from '@rc-component/menu';\nimport React from 'react';\nimport '../../assets/index.less';\n\nfunction onSelect({ key }) {\n  console.log(`${key} selected`);\n}\n\nfunction onVisibleChange(visible) {\n  console.log(visible);\n}\n\nconst menuCallback = () => (\n  <Menu onSelect={onSelect}>\n    <MenuItem disabled>disabled</MenuItem>\n    <MenuItem key=\"1\">one</MenuItem>\n    <Divider />\n    <MenuItem key=\"2\">two</MenuItem>\n  </Menu>\n);\n\nexport default function OverlayCallback() {\n  return (\n    <div style={{ margin: 20 }}>\n      <div style={{ height: 100 }} />\n      <div>\n        <Dropdown\n          trigger={['click']}\n          overlay={menuCallback}\n          animation=\"slide-up\"\n          onVisibleChange={onVisibleChange}\n        >\n          <button style={{ width: 100 }}>open</button>\n        </Dropdown>\n      </div>\n    </div>\n  );\n}\n"
  },
  {
    "path": "docs/examples/simple.jsx",
    "content": "/* eslint-disable no-console,react/button-has-type */\nimport Dropdown from '@rc-component/dropdown';\nimport Menu, { Divider, Item as MenuItem } from '@rc-component/menu';\nimport React from 'react';\nimport '../../assets/index.less';\n\nfunction onSelect({ key }) {\n  console.log(`${key} selected`);\n}\n\nfunction onVisibleChange(visible) {\n  console.log(visible);\n}\n\nconst menu = (\n  <Menu onSelect={onSelect}>\n    <MenuItem disabled>disabled</MenuItem>\n    <MenuItem key=\"1\">one</MenuItem>\n    <Divider />\n    <MenuItem key=\"2\">two</MenuItem>\n  </Menu>\n);\n\nexport default function Simple() {\n  return (\n    <div style={{ margin: 20 }}>\n      <div style={{ height: 100 }} />\n      <div>\n        <Dropdown\n          autoFocus\n          trigger={['click']}\n          overlay={menu}\n          animation=\"slide-up\"\n          onVisibleChange={onVisibleChange}\n        >\n          <button style={{ width: 100 }}>open</button>\n        </Dropdown>\n      </div>\n    </div>\n  );\n}\n"
  },
  {
    "path": "docs/index.md",
    "content": "---\nhero:\n  title: rc-dropdown\n  description: React Dropdown Component\n---\n\n<embed src=\"../README.md\"></embed>\n"
  },
  {
    "path": "index.js",
    "content": "'use strict';\n\nmodule.exports = require('./src');\n"
  },
  {
    "path": "now.json",
    "content": "{\n  \"version\": 2,\n  \"name\": \"rc-dropdown\",\n  \"builds\": [\n    {\n      \"src\": \"package.json\",\n      \"use\": \"@now/static-build\",\n      \"config\": { \"distDir\": \".docs\" }\n    }\n  ]\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"@rc-component/dropdown\",\n  \"version\": \"1.0.2\",\n  \"description\": \"dropdown ui component for react\",\n  \"keywords\": [\n    \"react\",\n    \"react-dropdown\"\n  ],\n  \"homepage\": \"http://github.com/react-component/dropdown\",\n  \"bugs\": {\n    \"url\": \"http://github.com/react-component/dropdown/issues\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git@github.com:react-component/dropdown.git\"\n  },\n  \"license\": \"MIT\",\n  \"maintainers\": [\n    \"yiminghe@gmail.com\",\n    \"hualei5280@gmail.com\"\n  ],\n  \"main\": \"lib/index\",\n  \"module\": \"./es/index\",\n  \"files\": [\n    \"lib\",\n    \"es\",\n    \"assets/*.css\"\n  ],\n  \"scripts\": {\n    \"build\": \"dumi build\",\n    \"compile\": \"father build && lessc assets/index.less assets/index.css\",\n    \"coverage\": \"rc-test --coverage\",\n    \"lint\": \"eslint src/ docs/examples/ --ext .tsx,.ts,.jsx,.js\",\n    \"now-build\": \"npm run build\",\n    \"prepare\": \"husky install && dumi setup\",\n    \"prepublishOnly\": \"npm run compile && rc-np\",\n    \"start\": \"dumi dev\",\n    \"test\": \"rc-test\"\n  },\n  \"lint-staged\": {\n    \"**/*.{js,jsx,tsx,ts,md,json}\": [\n      \"prettier --write\",\n      \"git add\"\n    ]\n  },\n  \"dependencies\": {\n    \"@rc-component/trigger\": \"^3.0.0\",\n    \"@rc-component/util\": \"^1.2.1\",\n    \"clsx\": \"^2.1.1\"\n  },\n  \"devDependencies\": {\n    \"@rc-component/father-plugin\": \"^2.0.2\",\n    \"@rc-component/menu\": \"^1.0.0\",\n    \"@rc-component/np\": \"^1.0.3\",\n    \"@rc-component/resize-observer\": \"^1.0.0\",\n    \"@testing-library/jest-dom\": \"^5.16.5\",\n    \"@testing-library/react\": \"^14.0.0\",\n    \"@types/jest\": \"^29.0.0\",\n    \"@types/node\": \"^24.5.2\",\n    \"@types/react\": \"^18.0.0\",\n    \"@types/react-dom\": \"^18.0.0\",\n    \"@types/warning\": \"^3.0.0\",\n    \"@umijs/fabric\": \"^3.0.0\",\n    \"dumi\": \"^2.0.0\",\n    \"eslint\": \"^7.18.0\",\n    \"father\": \"^4.0.0\",\n    \"glob\": \"^10.0.0\",\n    \"husky\": \"^8.0.3\",\n    \"jest-environment-jsdom\": \"^29.5.0\",\n    \"less\": \"^4.1.1\",\n    \"lint-staged\": \"^13.2.1\",\n    \"prettier\": \"^2.8.7\",\n    \"rc-test\": \"^7.0.14\",\n    \"react\": \"^18.0.0\",\n    \"react-dom\": \"^18.0.0\",\n    \"typescript\": \"^5.0.0\"\n  },\n  \"peerDependencies\": {\n    \"react\": \">=16.11.0\",\n    \"react-dom\": \">=16.11.0\"\n  }\n}\n"
  },
  {
    "path": "script/update-content.js",
    "content": "/*\n  用于 dumi 改造使用，\n  可用于将 examples 的文件批量修改为 demo 引入形式，\n  其他项目根据具体情况使用。\n*/\n\nconst fs = require('fs');\nconst glob = require('glob');\n\nconst paths = glob.sync('./docs/examples/*.jsx');\n\npaths.forEach((path) => {\n  const name = path.split('/').pop().split('.')[0];\n  fs.writeFile(\n    `./docs/demo/${name}.md`,\n    `---\ntitle: ${name}\nnav:\n  title: Demo\n  path: /demo\n---\n\n<code src=\"../examples/${name}.jsx\"></code>\n`,\n    'utf8',\n    function (error) {\n      if (error) {\n        console.log(error);\n        return false;\n      }\n      console.log(`${name} 更新成功~`);\n    },\n  );\n});\n"
  },
  {
    "path": "src/Dropdown.tsx",
    "content": "import type { TriggerProps, TriggerRef } from '@rc-component/trigger';\nimport Trigger from '@rc-component/trigger';\nimport type {\n  ActionType,\n  AlignType,\n  AnimationType,\n  BuildInPlacements,\n} from '@rc-component/trigger/lib/interface';\nimport { composeRef, getNodeRef, supportRef } from '@rc-component/util/lib/ref';\nimport { clsx } from 'clsx';\nimport React from 'react';\nimport useAccessibility from './hooks/useAccessibility';\nimport Overlay from './Overlay';\nimport Placements from './placements';\n\nexport interface DropdownProps\n  extends Pick<\n    TriggerProps,\n    | 'getPopupContainer'\n    | 'children'\n    | 'mouseEnterDelay'\n    | 'mouseLeaveDelay'\n    | 'onPopupAlign'\n    | 'builtinPlacements'\n    | 'autoDestroy'\n  > {\n  minOverlayWidthMatchTrigger?: boolean;\n  arrow?: boolean;\n  onVisibleChange?: (visible: boolean) => void;\n  onOverlayClick?: (e: Event) => void;\n  prefixCls?: string;\n  transitionName?: string;\n  overlayClassName?: string;\n  openClassName?: string;\n  animation?: AnimationType;\n  align?: AlignType;\n  overlayStyle?: React.CSSProperties;\n  placement?: keyof typeof Placements;\n  placements?: BuildInPlacements;\n  overlay?: (() => React.ReactElement) | React.ReactElement;\n  trigger?: ActionType | ActionType[];\n  alignPoint?: boolean;\n  showAction?: ActionType[];\n  hideAction?: ActionType[];\n  visible?: boolean;\n  autoFocus?: boolean;\n}\n\nconst Dropdown = React.forwardRef<TriggerRef, DropdownProps>((props, ref) => {\n  const {\n    arrow = false,\n    prefixCls = 'rc-dropdown',\n    transitionName,\n    animation,\n    align,\n    placement = 'bottomLeft',\n    placements = Placements,\n    getPopupContainer,\n    showAction,\n    hideAction,\n    overlayClassName,\n    overlayStyle,\n    visible,\n    trigger = ['hover'],\n    autoFocus,\n    overlay,\n    children,\n    onVisibleChange,\n    ...otherProps\n  } = props;\n\n  const [triggerVisible, setTriggerVisible] = React.useState<boolean>();\n  const mergedVisible = 'visible' in props ? visible : triggerVisible;\n  const mergedMotionName = animation\n    ? `${prefixCls}-${animation}`\n    : transitionName;\n\n  const triggerRef = React.useRef(null);\n  const overlayRef = React.useRef(null);\n  const childRef = React.useRef(null);\n  React.useImperativeHandle(ref, () => triggerRef.current);\n\n  const handleVisibleChange = (newVisible: boolean) => {\n    setTriggerVisible(newVisible);\n    onVisibleChange?.(newVisible);\n  };\n\n  useAccessibility({\n    visible: mergedVisible,\n    triggerRef: childRef,\n    onVisibleChange: handleVisibleChange,\n    autoFocus,\n    overlayRef,\n  });\n\n  const onClick = (e) => {\n    const { onOverlayClick } = props;\n    setTriggerVisible(false);\n\n    if (onOverlayClick) {\n      onOverlayClick(e);\n    }\n  };\n\n  const getMenuElement = () => (\n    <Overlay\n      ref={overlayRef}\n      overlay={overlay}\n      prefixCls={prefixCls}\n      arrow={arrow}\n    />\n  );\n\n  const getMenuElementOrLambda = () => {\n    if (typeof overlay === 'function') {\n      return getMenuElement;\n    }\n    return getMenuElement();\n  };\n\n  const getMinOverlayWidthMatchTrigger = () => {\n    const { minOverlayWidthMatchTrigger, alignPoint } = props;\n    if ('minOverlayWidthMatchTrigger' in props) {\n      return minOverlayWidthMatchTrigger;\n    }\n\n    return !alignPoint;\n  };\n\n  const getOpenClassName = () => {\n    const { openClassName } = props;\n    if (openClassName !== undefined) {\n      return openClassName;\n    }\n    return `${prefixCls}-open`;\n  };\n\n  const childrenNode = React.cloneElement(children as React.ReactElement, {\n    className: clsx(\n      (children as React.ReactElement).props?.className,\n      mergedVisible && getOpenClassName(),\n    ),\n    ref: supportRef(children)\n      ? composeRef(childRef, getNodeRef(children as React.ReactElement))\n      : undefined,\n  });\n\n  let triggerHideAction = hideAction;\n  if (!triggerHideAction && trigger.indexOf('contextMenu') !== -1) {\n    triggerHideAction = ['click'];\n  }\n\n  return (\n    <Trigger\n      builtinPlacements={placements}\n      {...otherProps}\n      prefixCls={prefixCls}\n      ref={triggerRef}\n      popupClassName={clsx(overlayClassName, {\n        [`${prefixCls}-show-arrow`]: arrow,\n      })}\n      popupStyle={overlayStyle}\n      action={trigger}\n      showAction={showAction}\n      hideAction={triggerHideAction}\n      popupPlacement={placement}\n      popupAlign={align}\n      popupMotion={{ motionName: mergedMotionName }}\n      popupVisible={mergedVisible}\n      stretch={getMinOverlayWidthMatchTrigger() ? 'minWidth' : ''}\n      popup={getMenuElementOrLambda()}\n      onOpenChange={handleVisibleChange}\n      onPopupClick={onClick}\n      getPopupContainer={getPopupContainer}\n    >\n      {childrenNode}\n    </Trigger>\n  );\n});\n\nexport default Dropdown;\n"
  },
  {
    "path": "src/Overlay.tsx",
    "content": "import { composeRef, getNodeRef, supportRef } from '@rc-component/util/lib/ref';\nimport React, { forwardRef, useMemo } from 'react';\nimport type { DropdownProps } from './Dropdown';\n\nexport type OverlayProps = Pick<\n  DropdownProps,\n  'overlay' | 'arrow' | 'prefixCls'\n>;\n\nconst Overlay = forwardRef<HTMLElement, OverlayProps>((props, ref) => {\n  const { overlay, arrow, prefixCls } = props;\n\n  const overlayNode = useMemo(() => {\n    let overlayElement: React.ReactElement;\n    if (typeof overlay === 'function') {\n      overlayElement = overlay();\n    } else {\n      overlayElement = overlay;\n    }\n    return overlayElement;\n  }, [overlay]);\n\n  const composedRef = composeRef(ref, getNodeRef(overlayNode));\n\n  return (\n    <>\n      {arrow && <div className={`${prefixCls}-arrow`} />}\n      {React.cloneElement(overlayNode, {\n        ref: supportRef(overlayNode) ? composedRef : undefined,\n      })}\n    </>\n  );\n});\n\nexport default Overlay;\n"
  },
  {
    "path": "src/hooks/useAccessibility.ts",
    "content": "import KeyCode from '@rc-component/util/lib/KeyCode';\nimport raf from '@rc-component/util/lib/raf';\nimport * as React from 'react';\n\nconst { ESC, TAB } = KeyCode;\n\ninterface UseAccessibilityProps {\n  visible: boolean;\n  triggerRef: React.RefObject<any>;\n  onVisibleChange?: (visible: boolean) => void;\n  autoFocus?: boolean;\n  overlayRef?: React.RefObject<any>;\n}\n\nexport default function useAccessibility({\n  visible,\n  triggerRef,\n  onVisibleChange,\n  autoFocus,\n  overlayRef,\n}: UseAccessibilityProps) {\n  const focusMenuRef = React.useRef<boolean>(false);\n\n  const handleCloseMenuAndReturnFocus = () => {\n    if (visible) {\n      triggerRef.current?.focus?.();\n      onVisibleChange?.(false);\n    }\n  };\n\n  const focusMenu = () => {\n    if (overlayRef.current?.focus) {\n      overlayRef.current.focus();\n      focusMenuRef.current = true;\n      return true;\n    }\n    return false;\n  };\n\n  const handleKeyDown = (event) => {\n    switch (event.keyCode) {\n      case ESC:\n        handleCloseMenuAndReturnFocus();\n        break;\n      case TAB: {\n        let focusResult: boolean = false;\n        if (!focusMenuRef.current) {\n          focusResult = focusMenu();\n        }\n\n        if (focusResult) {\n          event.preventDefault();\n        } else {\n          handleCloseMenuAndReturnFocus();\n        }\n        break;\n      }\n    }\n  };\n\n  React.useEffect(() => {\n    if (visible) {\n      window.addEventListener('keydown', handleKeyDown);\n      if (autoFocus) {\n        // FIXME: hack with raf\n        raf(focusMenu, 3);\n      }\n      return () => {\n        window.removeEventListener('keydown', handleKeyDown);\n        focusMenuRef.current = false;\n      };\n    }\n    return () => {\n      focusMenuRef.current = false;\n    };\n  }, [visible]); // eslint-disable-line react-hooks/exhaustive-deps\n}\n"
  },
  {
    "path": "src/index.tsx",
    "content": "export type { TriggerProps } from '@rc-component/trigger';\nexport type { DropdownProps } from './Dropdown';\nexport type { OverlayProps } from './Overlay';\n\nimport Dropdown from './Dropdown';\n\nexport default Dropdown;\n"
  },
  {
    "path": "src/placements.ts",
    "content": "const autoAdjustOverflow = {\n  adjustX: 1,\n  adjustY: 1,\n};\n\nconst targetOffset = [0, 0];\n\nconst placements = {\n  topLeft: {\n    points: ['bl', 'tl'],\n    overflow: autoAdjustOverflow,\n    offset: [0, -4],\n    targetOffset,\n  },\n  top: {\n    points: ['bc', 'tc'],\n    overflow: autoAdjustOverflow,\n    offset: [0, -4],\n    targetOffset,\n  },\n  topRight: {\n    points: ['br', 'tr'],\n    overflow: autoAdjustOverflow,\n    offset: [0, -4],\n    targetOffset,\n  },\n  bottomLeft: {\n    points: ['tl', 'bl'],\n    overflow: autoAdjustOverflow,\n    offset: [0, 4],\n    targetOffset,\n  },\n  bottom: {\n    points: ['tc', 'bc'],\n    overflow: autoAdjustOverflow,\n    offset: [0, 4],\n    targetOffset,\n  },\n  bottomRight: {\n    points: ['tr', 'br'],\n    overflow: autoAdjustOverflow,\n    offset: [0, 4],\n    targetOffset,\n  },\n};\n\nexport default placements;\n"
  },
  {
    "path": "tests/__mocks__/@rc-component/trigger.tsx",
    "content": "import Trigger from '@rc-component/trigger/lib/mock';\n\nexport default Trigger;\n"
  },
  {
    "path": "tests/__snapshots__/basic.test.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`dropdown simply works 1`] = `\n<div>\n  <button\n    class=\"my-button rc-dropdown-open\"\n  >\n    open\n  </button>\n  <div\n    class=\"rc-dropdown rc-dropdown-placement-bottomLeft\"\n    style=\"--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box; min-width: 100px;\"\n  >\n    <ul\n      class=\"rc-menu rc-menu-root rc-menu-vertical\"\n      data-menu-list=\"true\"\n      role=\"menu\"\n      style=\"width: 140px;\"\n      tabindex=\"0\"\n    >\n      <li\n        class=\"rc-menu-item\"\n        data-menu-id=\"rc-menu-uuid-1\"\n        role=\"menuitem\"\n        tabindex=\"-1\"\n      >\n        <span\n          class=\"my-menuitem\"\n        >\n          one\n        </span>\n      </li>\n      <li\n        class=\"rc-menu-item-divider\"\n        role=\"separator\"\n      />\n      <li\n        class=\"rc-menu-item\"\n        data-menu-id=\"rc-menu-uuid-2\"\n        role=\"menuitem\"\n        tabindex=\"-1\"\n      >\n        two\n      </li>\n    </ul>\n    <div\n      aria-hidden=\"true\"\n      style=\"display: none;\"\n    />\n  </div>\n</div>\n`;\n"
  },
  {
    "path": "tests/basic.test.tsx",
    "content": "/* eslint-disable react/button-has-type,react/no-find-dom-node,react/no-render-return-value,object-shorthand,func-names,max-len */\nimport type { MenuRef } from '@rc-component/menu';\nimport Menu, { Divider, Item as MenuItem } from '@rc-component/menu';\nimport { _rs } from '@rc-component/resize-observer';\nimport { spyElementPrototypes } from '@rc-component/util/lib/test/domHook';\nimport { act, fireEvent } from '@testing-library/react';\nimport type { HTMLAttributes } from 'react';\nimport * as React from 'react';\nimport { createRef, forwardRef, useImperativeHandle } from 'react';\nimport Dropdown from '../src';\nimport { render, sleep } from './utils';\n\nasync function waitForTime() {\n  for (let i = 0; i < 10; i += 1) {\n    await act(async () => {\n      jest.runAllTimers();\n    });\n  }\n}\n\nasync function triggerResize(target: Element) {\n  act(() => {\n    _rs([{ target } as ResizeObserverEntry]);\n  });\n\n  await waitForTime();\n}\n\nspyElementPrototypes(HTMLElement, {\n  offsetParent: {\n    get: () => document.body,\n  },\n  offsetLeft: {\n    get: function () {\n      return parseFloat(window.getComputedStyle(this).marginLeft) || 0;\n    },\n  },\n  offsetTop: {\n    get: function () {\n      return parseFloat(window.getComputedStyle(this).marginTop) || 0;\n    },\n  },\n  offsetHeight: {\n    get: function () {\n      return parseFloat(window.getComputedStyle(this).height) || 0;\n    },\n  },\n  offsetWidth: {\n    get: function () {\n      return parseFloat(window.getComputedStyle(this).width) || 0;\n    },\n  },\n\n  getBoundingClientRect: () => ({\n    width: 100,\n    height: 100,\n  }),\n});\n\ndescribe('dropdown', () => {\n  beforeEach(() => {\n    jest.clearAllTimers();\n  });\n\n  it('default visible', () => {\n    const { container } = render(\n      <Dropdown overlay={<div className=\"check-for-visible\">Test</div>} visible>\n        <button className=\"my-button\">open</button>\n      </Dropdown>,\n    );\n    expect(container instanceof HTMLDivElement).toBeTruthy();\n    expect(\n      container\n        .querySelector('.my-button')\n        ?.classList.contains('rc-dropdown-open'),\n    ).toBeTruthy();\n  });\n\n  it('supports controlled visible prop', () => {\n    const onVisibleChange = jest.fn();\n    const { container } = render(\n      <Dropdown\n        overlay={<div className=\"check-for-visible\">Test</div>}\n        visible\n        trigger={['click']}\n        onVisibleChange={onVisibleChange}\n      >\n        <button className=\"my-button\">open</button>\n      </Dropdown>,\n    );\n    expect(container instanceof HTMLDivElement).toBeTruthy();\n    expect(\n      container\n        .querySelector('.my-button')\n        ?.classList.contains('rc-dropdown-open'),\n    ).toBeTruthy();\n\n    fireEvent.click(container.querySelector('.my-button'));\n    expect(onVisibleChange).toHaveBeenCalledWith(false);\n  });\n\n  it('simply works', async () => {\n    let clicked;\n\n    function onClick({ key }) {\n      clicked = key;\n    }\n\n    const onOverlayClick = jest.fn();\n\n    const menu = (\n      <Menu style={{ width: 140 }} onClick={onClick}>\n        <MenuItem key=\"1\">\n          <span className=\"my-menuitem\">one</span>\n        </MenuItem>\n        <Divider />\n        <MenuItem key=\"2\">two</MenuItem>\n      </Menu>\n    );\n    const { container, baseElement } = render(\n      <Dropdown\n        trigger={['click']}\n        overlay={menu}\n        onOverlayClick={onOverlayClick}\n      >\n        <button className=\"my-button\">open</button>\n      </Dropdown>,\n    );\n    expect(container.querySelector('.my-button')).toBeTruthy();\n    // should not display until be triggered\n    expect(baseElement.querySelector('.rc-dropdown')).toBeFalsy();\n\n    fireEvent.click(container.querySelector('.my-button'));\n    expect(clicked).toBeUndefined();\n    expect(\n      baseElement\n        .querySelector('.rc-dropdown')\n        .classList.contains('rc-dropdown-hidden'),\n    ).toBeFalsy();\n    expect(container).toMatchSnapshot();\n\n    fireEvent.click(baseElement.querySelector('.my-menuitem'));\n    expect(clicked).toBe('1');\n    expect(onOverlayClick).toHaveBeenCalled();\n    expect(\n      baseElement\n        .querySelector('.rc-dropdown')\n        .classList.contains('rc-dropdown-hidden'),\n    ).toBeTruthy();\n  });\n\n  it('re-align works', async () => {\n    jest.useFakeTimers();\n\n    const onPopupAlign = jest.fn();\n\n    const buttonStyle = { width: 600, height: 20, marginLeft: 100 };\n    const menu = (\n      <Menu>\n        <MenuItem key=\"1\">one</MenuItem>\n      </Menu>\n    );\n    const { container } = render(\n      <Dropdown\n        trigger={['click']}\n        placement=\"bottomRight\"\n        overlay={menu}\n        onPopupAlign={onPopupAlign}\n      >\n        <button className=\"my-btn\" style={buttonStyle}>\n          open\n        </button>\n      </Dropdown>,\n    );\n\n    expect(onPopupAlign).not.toHaveBeenCalled();\n\n    fireEvent.click(container.querySelector('.my-btn'));\n    await waitForTime();\n\n    expect(onPopupAlign).toHaveBeenCalled();\n\n    jest.useRealTimers();\n  });\n\n  it('Test default minOverlayWidthMatchTrigger', async () => {\n    jest.useFakeTimers();\n\n    const overlayWidth = 50;\n    const overlay = <div style={{ width: overlayWidth }}>Test</div>;\n\n    const { container, baseElement } = render(\n      <Dropdown trigger={['click']} overlay={overlay} visible>\n        <button style={{ width: 100 }} className=\"my-button\">\n          open\n        </button>\n      </Dropdown>,\n    );\n\n    await triggerResize(container.querySelector('button'));\n\n    expect(baseElement.querySelector('.rc-dropdown')).toHaveStyle({\n      minWidth: '100px',\n    });\n\n    jest.useRealTimers();\n  });\n\n  it('user pass minOverlayWidthMatchTrigger', async () => {\n    jest.useFakeTimers();\n\n    const overlayWidth = 50;\n    const overlay = <div style={{ width: overlayWidth }}>Test</div>;\n\n    const { container, baseElement } = render(\n      <Dropdown\n        trigger={['click']}\n        overlay={overlay}\n        minOverlayWidthMatchTrigger={false}\n        visible\n      >\n        <button style={{ width: 100 }} className=\"my-button\">\n          open\n        </button>\n      </Dropdown>,\n    );\n\n    await triggerResize(container.querySelector('button'));\n\n    expect(baseElement.querySelector('.rc-dropdown')).not.toHaveStyle({\n      minWidth: '100px',\n    });\n\n    jest.useRealTimers();\n  });\n\n  it('should support default openClassName', () => {\n    const overlay = <div style={{ width: 50 }}>Test</div>;\n    const { container } = render(\n      <Dropdown\n        trigger={['click']}\n        overlay={overlay}\n        minOverlayWidthMatchTrigger={false}\n      >\n        <button style={{ width: 100 }} className=\"my-button\">\n          open\n        </button>\n      </Dropdown>,\n    );\n    fireEvent.click(container.querySelector('.my-button'));\n    expect(\n      container\n        .querySelector('.my-button')\n        .classList.contains('rc-dropdown-open'),\n    ).toBeTruthy();\n    fireEvent.click(container.querySelector('.my-button'));\n    expect(\n      container\n        .querySelector('.my-button')\n        .classList.contains('rc-dropdown-open'),\n    ).toBeFalsy();\n  });\n\n  it('should support custom openClassName', async () => {\n    const overlay = <div style={{ width: 50 }}>Test</div>;\n    const { container } = render(\n      <Dropdown\n        trigger={['click']}\n        overlay={overlay}\n        minOverlayWidthMatchTrigger={false}\n        openClassName=\"opened\"\n      >\n        <button style={{ width: 100 }} className=\"my-button\">\n          open\n        </button>\n      </Dropdown>,\n    );\n\n    fireEvent.click(container.querySelector('.my-button'));\n    expect(\n      container.querySelector('.my-button').classList.contains('opened'),\n    ).toBeTruthy();\n    fireEvent.click(container.querySelector('.my-button'));\n    expect(\n      container.querySelector('.my-button').classList.contains('opened'),\n    ).toBeFalsy();\n  });\n\n  it('overlay callback', async () => {\n    const overlay = <div style={{ width: 50 }}>Test</div>;\n    const { container, baseElement } = render(\n      <Dropdown trigger={['click']} overlay={() => overlay}>\n        <button className=\"my-button\">open</button>\n      </Dropdown>,\n    );\n\n    fireEvent.click(container.querySelector('.my-button'));\n    expect(\n      baseElement\n        .querySelector('.rc-dropdown')\n        .classList.contains('rc-dropdown-hidden'),\n    ).toBeFalsy();\n  });\n\n  it('should support arrow', async () => {\n    const overlay = <div style={{ width: 50 }}>Test</div>;\n    const { container, baseElement } = render(\n      <Dropdown arrow overlay={overlay} trigger={['click']}>\n        <button style={{ width: 100 }} className=\"my-button\">\n          open\n        </button>\n      </Dropdown>,\n    );\n\n    fireEvent.click(container.querySelector('.my-button'));\n    await sleep(500);\n    expect(\n      baseElement\n        .querySelector('.rc-dropdown')\n        .classList.contains('rc-dropdown-show-arrow'),\n    ).toBeTruthy();\n    expect(\n      baseElement\n        .querySelector('.rc-dropdown')\n        .firstElementChild.classList.contains('rc-dropdown-arrow'),\n    ).toBeTruthy();\n  });\n\n  it('Keyboard navigation works', async () => {\n    jest.useFakeTimers();\n\n    const overlay = (\n      <Menu>\n        <MenuItem key=\"1\">\n          <span className=\"my-menuitem\">one</span>\n        </MenuItem>\n        <MenuItem key=\"2\">two</MenuItem>\n      </Menu>\n    );\n    const { container, baseElement } = render(\n      <Dropdown trigger={['click']} overlay={overlay}>\n        <button className=\"my-button\">open</button>\n      </Dropdown>,\n    );\n    const trigger = container.querySelector('.my-button');\n\n    // Open menu;\n    fireEvent.click(trigger);\n    await waitForTime();\n    expect(\n      baseElement\n        .querySelector('.rc-dropdown')\n        .classList.contains('rc-dropdown-hidden'),\n    ).toBeFalsy();\n\n    // Close menu with Esc\n    fireEvent.keyDown(window, { key: 'Esc', keyCode: 27 });\n    await waitForTime();\n    expect(document.activeElement.className).toContain('my-button');\n\n    // Open menu\n    fireEvent.click(trigger);\n    await waitForTime();\n    expect(\n      baseElement\n        .querySelector('.rc-dropdown')\n        .classList.contains('rc-dropdown-hidden'),\n    ).toBeFalsy();\n\n    // Focus menu with Tab\n    window.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 9 })); // Tab\n    expect(document.activeElement.className).toContain('menu');\n\n    // Close menu with Tab\n    window.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 9 })); // Tab\n    await waitForTime();\n    expect(document.activeElement.className).toContain('my-button');\n\n    jest.useRealTimers();\n  });\n\n  it('Tab should close menu if overlay cannot be focused', async () => {\n    jest.useFakeTimers();\n\n    const Overlay = () => <div>test</div>;\n    const { container, baseElement } = render(\n      <Dropdown trigger={['click']} overlay={<Overlay />}>\n        <button className=\"my-button\">open</button>\n      </Dropdown>,\n    );\n    const trigger = container.querySelector('.my-button');\n\n    // Open menu;\n    fireEvent.click(trigger);\n    await waitForTime();\n    expect(\n      baseElement\n        .querySelector('.rc-dropdown')\n        .classList.contains('rc-dropdown-hidden'),\n    ).toBeFalsy();\n\n    // Close menu with Esc\n    fireEvent.keyDown(window, { key: 'Esc', keyCode: 27 });\n    await waitForTime();\n    expect(document.activeElement.className).toContain('my-button');\n\n    // Open menu\n    fireEvent.click(trigger);\n    await waitForTime();\n    expect(\n      baseElement\n        .querySelector('.rc-dropdown')\n        .classList.contains('rc-dropdown-hidden'),\n    ).toBeFalsy();\n\n    // Close menu with Tab\n    window.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 9 })); // Tab\n    await waitForTime();\n    expect(document.activeElement.className).toContain('my-button');\n\n    jest.useRealTimers();\n  });\n\n  it('keyboard should work if menu is wrapped', async () => {\n    const overlay = (\n      <div>\n        <Menu>\n          <MenuItem key=\"1\">\n            <span className=\"my-menuitem\">one</span>\n          </MenuItem>\n          <MenuItem key=\"2\">two</MenuItem>\n        </Menu>\n      </div>\n    );\n    const { container, baseElement } = render(\n      <Dropdown trigger={['click']} overlay={overlay}>\n        <button className=\"my-button\">open</button>\n      </Dropdown>,\n    );\n    const trigger = container.querySelector('.my-button');\n\n    // Open menu\n    fireEvent.click(trigger);\n    await sleep(200);\n    expect(\n      baseElement\n        .querySelector('.rc-dropdown')\n        .classList.contains('rc-dropdown-hidden'),\n    ).toBeFalsy();\n\n    // Close menu with Esc\n    window.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 27 })); // Esc\n    await sleep(200);\n    expect(document.activeElement.className).toContain('my-button');\n\n    // Open menu\n    fireEvent.click(trigger);\n    await sleep(200);\n    expect(\n      baseElement\n        .querySelector('.rc-dropdown')\n        .classList.contains('rc-dropdown-hidden'),\n    ).toBeFalsy();\n\n    // Focus menu with Tab\n    window.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 9 })); // Tab\n\n    // Close menu with Tab\n    window.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 9 })); // Tab\n    await sleep(200);\n    expect(document.activeElement.className).toContain('my-button');\n  });\n\n  it('support Menu expandIcon', async () => {\n    const props = {\n      overlay: (\n        <Menu expandIcon={<span id=\"customExpandIcon\" />}>\n          <Menu.Item key=\"1\">foo</Menu.Item>\n          <Menu.SubMenu title=\"SubMenu\">\n            <Menu.Item key=\"1\">foo</Menu.Item>\n          </Menu.SubMenu>\n        </Menu>\n      ),\n      visible: true,\n      getPopupContainer: (node) => node,\n    };\n\n    const { container } = render(\n      <Dropdown {...props}>\n        <button type=\"button\">button</button>\n      </Dropdown>,\n    );\n    await sleep(500);\n    expect(container.querySelector('#customExpandIcon')).toBeTruthy();\n  });\n\n  it('should support customized menuRef', async () => {\n    const menuRef = createRef<MenuRef>();\n    const props = {\n      overlay: (\n        <Menu ref={menuRef}>\n          <Menu.Item key=\"1\">foo</Menu.Item>\n        </Menu>\n      ),\n      visible: true,\n    };\n\n    render(\n      <Dropdown {...props}>\n        <button type=\"button\">button</button>\n      </Dropdown>,\n    );\n\n    await sleep(500);\n    expect(menuRef.current).toBeTruthy();\n  });\n\n  it('should support trigger when child provide nativeElement', async () => {\n    jest.useFakeTimers();\n    const Button = forwardRef<any, HTMLAttributes<HTMLButtonElement>>(\n      (props, ref) => {\n        const btnRef = createRef<HTMLButtonElement>();\n        useImperativeHandle(ref, () => ({\n          foo: () => {},\n          nativeElement: btnRef.current,\n        }));\n        return (\n          <button\n            ref={btnRef}\n            onClick={(e) => {\n              props?.onClick?.(e);\n            }}\n          >\n            trigger\n          </button>\n        );\n      },\n    );\n    const { container, baseElement } = render(\n      <Dropdown\n        trigger={['click']}\n        getPopupContainer={(node) => node}\n        overlay={\n          <Menu>\n            <Menu.Item key=\"1\">foo</Menu.Item>\n          </Menu>\n        }\n      >\n        <Button />\n      </Dropdown>,\n    );\n    fireEvent.click(container.querySelector('button'));\n    fireEvent.click(baseElement.querySelectorAll('li')[0]);\n\n    jest.runAllTimers();\n    jest.useRealTimers();\n  });\n\n  it('should support autoFocus', async () => {\n    jest.useFakeTimers();\n\n    const overlay = (\n      <Menu>\n        <MenuItem key=\"1\">\n          <span className=\"my-menuitem\">one</span>\n        </MenuItem>\n        <MenuItem key=\"2\">two</MenuItem>\n      </Menu>\n    );\n    const { container } = render(\n      <Dropdown autoFocus trigger={['click']} overlay={overlay}>\n        <button className=\"my-button\">open</button>\n      </Dropdown>,\n    );\n    const trigger = container.querySelector('.my-button');\n\n    // Open menu\n    fireEvent.click(trigger);\n\n    await waitForTime();\n\n    expect(\n      container\n        .querySelector('.rc-dropdown')\n        .classList.contains('rc-dropdown-hidden'),\n    ).toBeFalsy();\n    expect(document.activeElement.className).toContain('menu');\n\n    // Close menu with Tab\n    window.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 9 })); // Tab\n\n    await waitForTime();\n\n    expect(document.activeElement.className).toContain('my-button');\n\n    jest.useRealTimers();\n  });\n\n  it('children cannot be given ref should not throw', () => {\n    const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});\n    const Component = () => <div>test</div>;\n\n    render(\n      <Dropdown overlay={<div>test</div>}>\n        <Component />\n      </Dropdown>,\n    );\n    expect(errorSpy).not.toHaveBeenCalledWith(\n      expect.stringContaining(\n        'Warning: Function components cannot be given refs',\n      ),\n      expect.anything(),\n      expect.anything(),\n    );\n  });\n});\n"
  },
  {
    "path": "tests/point.test.tsx",
    "content": "/* eslint-disable react/button-has-type,react/no-render-return-value */\nimport { act, fireEvent } from '@testing-library/react';\nimport * as React from 'react';\nimport Dropdown from '../src';\nimport { render } from './utils';\n\n// Fix prettier rm this\nconsole.log(!!React);\n\nasync function waitForTime() {\n  for (let i = 0; i < 10; i += 1) {\n    await act(async () => {\n      jest.runAllTimers();\n    });\n  }\n}\n\ndescribe('point', () => {\n  beforeEach(() => {\n    jest.useFakeTimers();\n  });\n\n  afterEach(() => {\n    jest.clearAllTimers();\n    jest.useRealTimers();\n  });\n\n  it('click show', async () => {\n    const overlay = (\n      <div\n        className=\"check-for-visible\"\n        style={{\n          width: 10,\n        }}\n      >\n        Test\n      </div>\n    );\n\n    const onPopupAlign = jest.fn();\n\n    const { container } = render(\n      <Dropdown\n        onPopupAlign={onPopupAlign}\n        trigger={['contextMenu']}\n        overlay={overlay}\n        alignPoint\n        align={{\n          points: ['tl'],\n          overflow: {},\n        }}\n      >\n        <button className=\"my-button\">open</button>\n      </Dropdown>,\n    );\n\n    fireEvent.contextMenu(container.querySelector('.my-button'));\n    await waitForTime();\n\n    expect(container.querySelector('.rc-dropdown')).toBeTruthy();\n  });\n});\n"
  },
  {
    "path": "tests/utils.js",
    "content": "import { StrictMode } from 'react';\nimport { render, act } from '@testing-library/react';\n\nconst globalTimeout = global.setTimeout;\n\nexport async function sleep(timeout = 0) {\n  await act(async () => {\n    await new Promise((resolve) => {\n      globalTimeout(resolve, timeout);\n    });\n  });\n}\n\nfunction customRender(ui, options) {\n  return render(ui, { wrapper: StrictMode, ...options });\n}\n\nexport { customRender as render };\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"allowSyntheticDefaultImports\": true,\n    \"baseUrl\": \"./\",\n    \"declaration\": true,\n    \"module\": \"esnext\",\n    \"target\": \"esnext\",\n    \"moduleResolution\": \"node\",\n    \"jsx\": \"react\",\n    \"skipLibCheck\": true,\n    \"paths\": {\n      \"@@/*\": [\".dumi/tmp/*\"]\n    }\n  },\n  \"include\": [\"./src\", \"./tests\", \"./typings/\"],\n  \"typings\": \"./typings/index.d.ts\",\n  \"exclude\": [\n    \"node_modules\",\n    \"build\",\n    \"scripts\",\n    \"acceptance-tests\",\n    \"webpack\",\n    \"jest\",\n    \"src/setupTests.ts\",\n    \"tslint:latest\",\n    \"tslint-config-prettier\"\n  ]\n}\n"
  }
]