1
This commit is contained in:
+20
@@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2015-present Alipay.com, https://www.alipay.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
# @rc-component/dropdown
|
||||
|
||||
react dropdown component.
|
||||
|
||||
[![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]
|
||||
|
||||
[npm-image]: https://img.shields.io/npm/v/@rc-component/dropdown.svg?style=flat-square
|
||||
[npm-url]: https://npmjs.org/package/@rc-component/dropdown
|
||||
[travis-image]: https://img.shields.io/travis/react-component/dropdown/master?style=flat-square
|
||||
[travis-url]: https://travis-ci.com/react-component/dropdown
|
||||
[github-actions-image]: https://github.com/react-component/dropdown/actions/workflows/ci.yml/badge.svg
|
||||
[github-actions-url]: https://github.com/react-component/dropdown/actions/workflows/ci.yml
|
||||
[codecov-image]: https://img.shields.io/codecov/c/github/react-component/dropdown/master.svg?style=flat-square
|
||||
[codecov-url]: https://app.codecov.io/gh/react-component/dropdown
|
||||
[david-url]: https://david-dm.org/react-component/dropdown
|
||||
[david-image]: https://david-dm.org/react-component/dropdown/status.svg?style=flat-square
|
||||
[david-dev-url]: https://david-dm.org/react-component/dropdown?type=dev
|
||||
[david-dev-image]: https://david-dm.org/react-component/dropdown/dev-status.svg?style=flat-square
|
||||
[download-image]: https://img.shields.io/npm/dm/@rc-component/dropdown.svg?style=flat-square
|
||||
[download-url]: https://npmjs.org/package/@rc-component/dropdown
|
||||
[bundlephobia-url]: https://bundlephobia.com/package/@rc-component/dropdown
|
||||
[bundlephobia-image]: https://badgen.net/bundlephobia/minzip/@rc-component/dropdown
|
||||
[dumi-url]: https://github.com/umijs/dumi
|
||||
[dumi-image]: https://img.shields.io/badge/docs%20by-dumi-blue?style=flat-square
|
||||
|
||||
## Screenshot
|
||||
|
||||

|
||||
|
||||
## Example
|
||||
|
||||
online example: http://react-component.github.io/dropdown/examples/
|
||||
|
||||
## install
|
||||
|
||||
[](https://npmjs.org/package/@rc-component/dropdown)
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var Dropdown = require('@rc-component/dropdown');
|
||||
// use dropdown
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### props
|
||||
|
||||
<table class="table table-bordered table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 100px;">name</th>
|
||||
<th style="width: 50px;">type</th>
|
||||
<th style="width: 50px;">default</th>
|
||||
<th>description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>overlayClassName</td>
|
||||
<td>String</td>
|
||||
<td></td>
|
||||
<td>additional css class of root dom node</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>openClassName</td>
|
||||
<td>String</td>
|
||||
<td>`${prefixCls}-open`</td>
|
||||
<td>className of trigger when dropdown is opened</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>prefixCls</td>
|
||||
<td>String</td>
|
||||
<td>rc-dropdown</td>
|
||||
<td>prefix class name</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>transitionName</td>
|
||||
<td>String</td>
|
||||
<td></td>
|
||||
<td>dropdown menu's animation css class name</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>animation</td>
|
||||
<td>String</td>
|
||||
<td></td>
|
||||
<td>part of dropdown menu's animation css class name</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>placement</td>
|
||||
<td>String</td>
|
||||
<td>bottomLeft</td>
|
||||
<td>Position of menu item. There are: top, topCenter, topRight, bottomLeft, bottom, bottomRight </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>onVisibleChange</td>
|
||||
<td>Function</td>
|
||||
<td></td>
|
||||
<td>call when visible is changed</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>visible</td>
|
||||
<td>boolean</td>
|
||||
<td></td>
|
||||
<td>whether tooltip is visible</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>defaultVisible</td>
|
||||
<td>boolean</td>
|
||||
<td></td>
|
||||
<td>whether tooltip is visible initially</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>overlay</td>
|
||||
<td>rc-menu</td>
|
||||
<td></td>
|
||||
<td><a href="https://github.com/react-component/menu">rc-menu</a> element</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>onOverlayClick</td>
|
||||
<td>function(e)</td>
|
||||
<td></td>
|
||||
<td>call when overlay is clicked</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>minOverlayWidthMatchTrigger</td>
|
||||
<td>boolean</td>
|
||||
<td>true (false when set alignPoint)</td>
|
||||
<td>whether overlay's width must not be less than trigger's </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>getPopupContainer</td>
|
||||
<td>Function(menuDOMNode): HTMLElement</td>
|
||||
<th>() => document.body</th>
|
||||
<td>Where to render the DOM node of dropdown</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
Note: 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.
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
|
||||
## Test Case
|
||||
|
||||
```bash
|
||||
npm test
|
||||
npm run chrome-test
|
||||
```
|
||||
|
||||
## Coverage
|
||||
|
||||
```bash
|
||||
npm run coverage
|
||||
```
|
||||
|
||||
open coverage/ dir
|
||||
|
||||
## License
|
||||
|
||||
@rc-component/dropdown is released under the MIT license.
|
||||
+245
@@ -0,0 +1,245 @@
|
||||
@font-face {
|
||||
font-family: 'anticon';
|
||||
src: url('//at.alicdn.com/t/font_1434092639_4910953.eot');
|
||||
/* IE9*/
|
||||
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');
|
||||
/* iOS 4.1- */
|
||||
}
|
||||
.rc-dropdown {
|
||||
position: absolute;
|
||||
left: -9999px;
|
||||
top: -9999px;
|
||||
z-index: 1070;
|
||||
display: block;
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.rc-dropdown-hidden {
|
||||
display: none;
|
||||
}
|
||||
.rc-dropdown .rc-menu {
|
||||
outline: none;
|
||||
position: relative;
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin: 2px 0 2px;
|
||||
text-align: left;
|
||||
background-color: #fff;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 1px 5px #ccc;
|
||||
background-clip: padding-box;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
.rc-dropdown .rc-menu > li {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.rc-dropdown .rc-menu:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: -4px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 4px;
|
||||
background: #ffffff;
|
||||
background: rgba(255, 255, 255, 0.01);
|
||||
}
|
||||
.rc-dropdown .rc-menu > .rc-dropdown .rc-menu-item {
|
||||
position: relative;
|
||||
display: block;
|
||||
padding: 7px 10px;
|
||||
clear: both;
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
color: #666666;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.rc-dropdown .rc-menu > .rc-dropdown .rc-menu-item:hover,
|
||||
.rc-dropdown .rc-menu > .rc-dropdown .rc-menu-item-active,
|
||||
.rc-dropdown .rc-menu > .rc-dropdown .rc-menu-item-selected {
|
||||
background-color: #ebfaff;
|
||||
}
|
||||
.rc-dropdown .rc-menu > .rc-dropdown .rc-menu-item-selected {
|
||||
position: relative;
|
||||
}
|
||||
.rc-dropdown .rc-menu > .rc-dropdown .rc-menu-item-selected:after {
|
||||
content: '\e613';
|
||||
font-family: 'anticon';
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
right: 16px;
|
||||
color: #3CB8F0;
|
||||
}
|
||||
.rc-dropdown .rc-menu > .rc-dropdown .rc-menu-item-disabled {
|
||||
color: #ccc;
|
||||
cursor: not-allowed;
|
||||
pointer-events: none;
|
||||
}
|
||||
.rc-dropdown .rc-menu > .rc-dropdown .rc-menu-item-disabled:hover {
|
||||
color: #ccc;
|
||||
background-color: #fff;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.rc-dropdown .rc-menu > .rc-dropdown .rc-menu-item:last-child {
|
||||
border-bottom-left-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
}
|
||||
.rc-dropdown .rc-menu > .rc-dropdown .rc-menu-item:first-child {
|
||||
border-top-left-radius: 3px;
|
||||
border-top-right-radius: 3px;
|
||||
}
|
||||
.rc-dropdown .rc-menu > .rc-dropdown .rc-menu-item-divider {
|
||||
height: 1px;
|
||||
margin: 1px 0;
|
||||
overflow: hidden;
|
||||
background-color: #e5e5e5;
|
||||
line-height: 0;
|
||||
}
|
||||
.rc-dropdown-slide-up-enter,
|
||||
.rc-dropdown-slide-up-appear {
|
||||
animation-duration: 0.3s;
|
||||
animation-fill-mode: both;
|
||||
transform-origin: 0 0;
|
||||
display: block !important;
|
||||
opacity: 0;
|
||||
animation-timing-function: cubic-bezier(0.08, 0.82, 0.17, 1);
|
||||
animation-play-state: paused;
|
||||
}
|
||||
.rc-dropdown-slide-up-leave {
|
||||
animation-duration: 0.3s;
|
||||
animation-fill-mode: both;
|
||||
transform-origin: 0 0;
|
||||
display: block !important;
|
||||
opacity: 1;
|
||||
animation-timing-function: cubic-bezier(0.6, 0.04, 0.98, 0.34);
|
||||
animation-play-state: paused;
|
||||
}
|
||||
.rc-dropdown-slide-up-enter.rc-dropdown-slide-up-enter-active.rc-dropdown-placement-bottomLeft,
|
||||
.rc-dropdown-slide-up-appear.rc-dropdown-slide-up-appear-active.rc-dropdown-placement-bottomLeft,
|
||||
.rc-dropdown-slide-up-enter.rc-dropdown-slide-up-enter-active.rc-dropdown-placement-bottomCenter,
|
||||
.rc-dropdown-slide-up-appear.rc-dropdown-slide-up-appear-active.rc-dropdown-placement-bottomCenter,
|
||||
.rc-dropdown-slide-up-enter.rc-dropdown-slide-up-enter-active.rc-dropdown-placement-bottomRight,
|
||||
.rc-dropdown-slide-up-appear.rc-dropdown-slide-up-appear-active.rc-dropdown-placement-bottomRight {
|
||||
animation-name: rcDropdownSlideUpIn;
|
||||
animation-play-state: running;
|
||||
}
|
||||
.rc-dropdown-slide-up-enter.rc-dropdown-slide-up-enter-active.rc-dropdown-placement-topLeft,
|
||||
.rc-dropdown-slide-up-appear.rc-dropdown-slide-up-appear-active.rc-dropdown-placement-topLeft,
|
||||
.rc-dropdown-slide-up-enter.rc-dropdown-slide-up-enter-active.rc-dropdown-placement-topCenter,
|
||||
.rc-dropdown-slide-up-appear.rc-dropdown-slide-up-appear-active.rc-dropdown-placement-topCenter,
|
||||
.rc-dropdown-slide-up-enter.rc-dropdown-slide-up-enter-active.rc-dropdown-placement-topRight,
|
||||
.rc-dropdown-slide-up-appear.rc-dropdown-slide-up-appear-active.rc-dropdown-placement-topRight {
|
||||
animation-name: rcDropdownSlideDownIn;
|
||||
animation-play-state: running;
|
||||
}
|
||||
.rc-dropdown-slide-up-leave.rc-dropdown-slide-up-leave-active.rc-dropdown-placement-bottomLeft,
|
||||
.rc-dropdown-slide-up-leave.rc-dropdown-slide-up-leave-active.rc-dropdown-placement-bottomCenter,
|
||||
.rc-dropdown-slide-up-leave.rc-dropdown-slide-up-leave-active.rc-dropdown-placement-bottomRight {
|
||||
animation-name: rcDropdownSlideUpOut;
|
||||
animation-play-state: running;
|
||||
}
|
||||
.rc-dropdown-slide-up-leave.rc-dropdown-slide-up-leave-active.rc-dropdown-placement-topLeft,
|
||||
.rc-dropdown-slide-up-leave.rc-dropdown-slide-up-leave-active.rc-dropdown-placement-topCenter,
|
||||
.rc-dropdown-slide-up-leave.rc-dropdown-slide-up-leave-active.rc-dropdown-placement-topRight {
|
||||
animation-name: rcDropdownSlideDownOut;
|
||||
animation-play-state: running;
|
||||
}
|
||||
@keyframes rcDropdownSlideUpIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleY(0);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleY(1);
|
||||
}
|
||||
}
|
||||
@keyframes rcDropdownSlideUpOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleY(1);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleY(0);
|
||||
}
|
||||
}
|
||||
@keyframes rcDropdownSlideDownIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform-origin: 0% 100%;
|
||||
transform: scaleY(0);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform-origin: 0% 100%;
|
||||
transform: scaleY(1);
|
||||
}
|
||||
}
|
||||
@keyframes rcDropdownSlideDownOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform-origin: 0% 100%;
|
||||
transform: scaleY(1);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform-origin: 0% 100%;
|
||||
transform: scaleY(0);
|
||||
}
|
||||
}
|
||||
.rc-dropdown-arrow {
|
||||
position: absolute;
|
||||
border-width: 8px / 2;
|
||||
border-color: transparent;
|
||||
box-shadow: 0 1px 5px #ccc;
|
||||
border-style: solid;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
.rc-dropdown-show-arrow.rc-dropdown-placement-top,
|
||||
.rc-dropdown-show-arrow.rc-dropdown-placement-topLeft,
|
||||
.rc-dropdown-show-arrow.rc-dropdown-placement-topRight {
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
.rc-dropdown-show-arrow.rc-dropdown-placement-bottom,
|
||||
.rc-dropdown-show-arrow.rc-dropdown-placement-bottomLeft,
|
||||
.rc-dropdown-show-arrow.rc-dropdown-placement-bottomRight {
|
||||
padding-top: 6px;
|
||||
}
|
||||
.rc-dropdown-placement-top .rc-dropdown-arrow,
|
||||
.rc-dropdown-placement-topLeft .rc-dropdown-arrow,
|
||||
.rc-dropdown-placement-topRight .rc-dropdown-arrow {
|
||||
bottom: 4px;
|
||||
border-top-color: white;
|
||||
}
|
||||
.rc-dropdown-placement-top .rc-dropdown-arrow {
|
||||
left: 50%;
|
||||
}
|
||||
.rc-dropdown-placement-topLeft .rc-dropdown-arrow {
|
||||
left: 15%;
|
||||
}
|
||||
.rc-dropdown-placement-topRight .rc-dropdown-arrow {
|
||||
right: 15%;
|
||||
}
|
||||
.rc-dropdown-placement-bottom .rc-dropdown-arrow,
|
||||
.rc-dropdown-placement-bottomLeft .rc-dropdown-arrow,
|
||||
.rc-dropdown-placement-bottomRight .rc-dropdown-arrow {
|
||||
top: 4px;
|
||||
border-bottom-color: white;
|
||||
}
|
||||
.rc-dropdown-placement-bottom .rc-dropdown-arrow {
|
||||
left: 50%;
|
||||
}
|
||||
.rc-dropdown-placement-bottomLeft .rc-dropdown-arrow {
|
||||
left: 15%;
|
||||
}
|
||||
.rc-dropdown-placement-bottomRight .rc-dropdown-arrow {
|
||||
right: 15%;
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
import type { TriggerProps, TriggerRef } from '@rc-component/trigger';
|
||||
import type { ActionType, AlignType, AnimationType, BuildInPlacements } from '@rc-component/trigger/lib/interface';
|
||||
import React from 'react';
|
||||
import Placements from './placements';
|
||||
export interface DropdownProps extends Pick<TriggerProps, 'getPopupContainer' | 'children' | 'mouseEnterDelay' | 'mouseLeaveDelay' | 'onPopupAlign' | 'builtinPlacements' | 'autoDestroy'> {
|
||||
minOverlayWidthMatchTrigger?: boolean;
|
||||
arrow?: boolean;
|
||||
onVisibleChange?: (visible: boolean) => void;
|
||||
onOverlayClick?: (e: Event) => void;
|
||||
prefixCls?: string;
|
||||
transitionName?: string;
|
||||
overlayClassName?: string;
|
||||
openClassName?: string;
|
||||
animation?: AnimationType;
|
||||
align?: AlignType;
|
||||
overlayStyle?: React.CSSProperties;
|
||||
placement?: keyof typeof Placements;
|
||||
placements?: BuildInPlacements;
|
||||
overlay?: (() => React.ReactElement) | React.ReactElement;
|
||||
trigger?: ActionType | ActionType[];
|
||||
alignPoint?: boolean;
|
||||
showAction?: ActionType[];
|
||||
hideAction?: ActionType[];
|
||||
visible?: boolean;
|
||||
autoFocus?: boolean;
|
||||
}
|
||||
declare const Dropdown: React.ForwardRefExoticComponent<DropdownProps & React.RefAttributes<TriggerRef>>;
|
||||
export default Dropdown;
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
||||
import Trigger from '@rc-component/trigger';
|
||||
import { composeRef, getNodeRef, supportRef } from "@rc-component/util/es/ref";
|
||||
import { clsx } from 'clsx';
|
||||
import React from 'react';
|
||||
import useAccessibility from "./hooks/useAccessibility";
|
||||
import Overlay from "./Overlay";
|
||||
import Placements from "./placements";
|
||||
const Dropdown = /*#__PURE__*/React.forwardRef((props, ref) => {
|
||||
const {
|
||||
arrow = false,
|
||||
prefixCls = 'rc-dropdown',
|
||||
transitionName,
|
||||
animation,
|
||||
align,
|
||||
placement = 'bottomLeft',
|
||||
placements = Placements,
|
||||
getPopupContainer,
|
||||
showAction,
|
||||
hideAction,
|
||||
overlayClassName,
|
||||
overlayStyle,
|
||||
visible,
|
||||
trigger = ['hover'],
|
||||
autoFocus,
|
||||
overlay,
|
||||
children,
|
||||
onVisibleChange,
|
||||
...otherProps
|
||||
} = props;
|
||||
const [triggerVisible, setTriggerVisible] = React.useState();
|
||||
const mergedVisible = 'visible' in props ? visible : triggerVisible;
|
||||
const mergedMotionName = animation ? `${prefixCls}-${animation}` : transitionName;
|
||||
const triggerRef = React.useRef(null);
|
||||
const overlayRef = React.useRef(null);
|
||||
const childRef = React.useRef(null);
|
||||
React.useImperativeHandle(ref, () => triggerRef.current);
|
||||
const handleVisibleChange = newVisible => {
|
||||
setTriggerVisible(newVisible);
|
||||
onVisibleChange?.(newVisible);
|
||||
};
|
||||
useAccessibility({
|
||||
visible: mergedVisible,
|
||||
triggerRef: childRef,
|
||||
onVisibleChange: handleVisibleChange,
|
||||
autoFocus,
|
||||
overlayRef
|
||||
});
|
||||
const onClick = e => {
|
||||
const {
|
||||
onOverlayClick
|
||||
} = props;
|
||||
setTriggerVisible(false);
|
||||
if (onOverlayClick) {
|
||||
onOverlayClick(e);
|
||||
}
|
||||
};
|
||||
const getMenuElement = () => /*#__PURE__*/React.createElement(Overlay, {
|
||||
ref: overlayRef,
|
||||
overlay: overlay,
|
||||
prefixCls: prefixCls,
|
||||
arrow: arrow
|
||||
});
|
||||
const getMenuElementOrLambda = () => {
|
||||
if (typeof overlay === 'function') {
|
||||
return getMenuElement;
|
||||
}
|
||||
return getMenuElement();
|
||||
};
|
||||
const getMinOverlayWidthMatchTrigger = () => {
|
||||
const {
|
||||
minOverlayWidthMatchTrigger,
|
||||
alignPoint
|
||||
} = props;
|
||||
if ('minOverlayWidthMatchTrigger' in props) {
|
||||
return minOverlayWidthMatchTrigger;
|
||||
}
|
||||
return !alignPoint;
|
||||
};
|
||||
const getOpenClassName = () => {
|
||||
const {
|
||||
openClassName
|
||||
} = props;
|
||||
if (openClassName !== undefined) {
|
||||
return openClassName;
|
||||
}
|
||||
return `${prefixCls}-open`;
|
||||
};
|
||||
const childrenNode = /*#__PURE__*/React.cloneElement(children, {
|
||||
className: clsx(children.props?.className, mergedVisible && getOpenClassName()),
|
||||
ref: supportRef(children) ? composeRef(childRef, getNodeRef(children)) : undefined
|
||||
});
|
||||
let triggerHideAction = hideAction;
|
||||
if (!triggerHideAction && trigger.indexOf('contextMenu') !== -1) {
|
||||
triggerHideAction = ['click'];
|
||||
}
|
||||
return /*#__PURE__*/React.createElement(Trigger, _extends({
|
||||
builtinPlacements: placements
|
||||
}, otherProps, {
|
||||
prefixCls: prefixCls,
|
||||
ref: triggerRef,
|
||||
popupClassName: clsx(overlayClassName, {
|
||||
[`${prefixCls}-show-arrow`]: arrow
|
||||
}),
|
||||
popupStyle: overlayStyle,
|
||||
action: trigger,
|
||||
showAction: showAction,
|
||||
hideAction: triggerHideAction,
|
||||
popupPlacement: placement,
|
||||
popupAlign: align,
|
||||
popupMotion: {
|
||||
motionName: mergedMotionName
|
||||
},
|
||||
popupVisible: mergedVisible,
|
||||
stretch: getMinOverlayWidthMatchTrigger() ? 'minWidth' : '',
|
||||
popup: getMenuElementOrLambda(),
|
||||
onOpenChange: handleVisibleChange,
|
||||
onPopupClick: onClick,
|
||||
getPopupContainer: getPopupContainer
|
||||
}), childrenNode);
|
||||
});
|
||||
export default Dropdown;
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import React from 'react';
|
||||
import type { DropdownProps } from './Dropdown';
|
||||
export type OverlayProps = Pick<DropdownProps, 'overlay' | 'arrow' | 'prefixCls'>;
|
||||
declare const Overlay: React.ForwardRefExoticComponent<OverlayProps & React.RefAttributes<HTMLElement>>;
|
||||
export default Overlay;
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import { composeRef, getNodeRef, supportRef } from "@rc-component/util/es/ref";
|
||||
import React, { forwardRef, useMemo } from 'react';
|
||||
const Overlay = /*#__PURE__*/forwardRef((props, ref) => {
|
||||
const {
|
||||
overlay,
|
||||
arrow,
|
||||
prefixCls
|
||||
} = props;
|
||||
const overlayNode = useMemo(() => {
|
||||
let overlayElement;
|
||||
if (typeof overlay === 'function') {
|
||||
overlayElement = overlay();
|
||||
} else {
|
||||
overlayElement = overlay;
|
||||
}
|
||||
return overlayElement;
|
||||
}, [overlay]);
|
||||
const composedRef = composeRef(ref, getNodeRef(overlayNode));
|
||||
return /*#__PURE__*/React.createElement(React.Fragment, null, arrow && /*#__PURE__*/React.createElement("div", {
|
||||
className: `${prefixCls}-arrow`
|
||||
}), /*#__PURE__*/React.cloneElement(overlayNode, {
|
||||
ref: supportRef(overlayNode) ? composedRef : undefined
|
||||
}));
|
||||
});
|
||||
export default Overlay;
|
||||
Generated
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
import * as React from 'react';
|
||||
interface UseAccessibilityProps {
|
||||
visible: boolean;
|
||||
triggerRef: React.RefObject<any>;
|
||||
onVisibleChange?: (visible: boolean) => void;
|
||||
autoFocus?: boolean;
|
||||
overlayRef?: React.RefObject<any>;
|
||||
}
|
||||
export default function useAccessibility({ visible, triggerRef, onVisibleChange, autoFocus, overlayRef, }: UseAccessibilityProps): void;
|
||||
export {};
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
import KeyCode from "@rc-component/util/es/KeyCode";
|
||||
import raf from "@rc-component/util/es/raf";
|
||||
import * as React from 'react';
|
||||
const {
|
||||
ESC,
|
||||
TAB
|
||||
} = KeyCode;
|
||||
export default function useAccessibility({
|
||||
visible,
|
||||
triggerRef,
|
||||
onVisibleChange,
|
||||
autoFocus,
|
||||
overlayRef
|
||||
}) {
|
||||
const focusMenuRef = React.useRef(false);
|
||||
const handleCloseMenuAndReturnFocus = () => {
|
||||
if (visible) {
|
||||
triggerRef.current?.focus?.();
|
||||
onVisibleChange?.(false);
|
||||
}
|
||||
};
|
||||
const focusMenu = () => {
|
||||
if (overlayRef.current?.focus) {
|
||||
overlayRef.current.focus();
|
||||
focusMenuRef.current = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
const handleKeyDown = event => {
|
||||
switch (event.keyCode) {
|
||||
case ESC:
|
||||
handleCloseMenuAndReturnFocus();
|
||||
break;
|
||||
case TAB:
|
||||
{
|
||||
let focusResult = false;
|
||||
if (!focusMenuRef.current) {
|
||||
focusResult = focusMenu();
|
||||
}
|
||||
if (focusResult) {
|
||||
event.preventDefault();
|
||||
} else {
|
||||
handleCloseMenuAndReturnFocus();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
React.useEffect(() => {
|
||||
if (visible) {
|
||||
window.addEventListener('keydown', handleKeyDown);
|
||||
if (autoFocus) {
|
||||
// FIXME: hack with raf
|
||||
raf(focusMenu, 3);
|
||||
}
|
||||
return () => {
|
||||
window.removeEventListener('keydown', handleKeyDown);
|
||||
focusMenuRef.current = false;
|
||||
};
|
||||
}
|
||||
return () => {
|
||||
focusMenuRef.current = false;
|
||||
};
|
||||
}, [visible]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
export type { TriggerProps } from '@rc-component/trigger';
|
||||
export type { DropdownProps } from './Dropdown';
|
||||
export type { OverlayProps } from './Overlay';
|
||||
import Dropdown from './Dropdown';
|
||||
export default Dropdown;
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
import Dropdown from "./Dropdown";
|
||||
export default Dropdown;
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
declare const placements: {
|
||||
topLeft: {
|
||||
points: string[];
|
||||
overflow: {
|
||||
adjustX: number;
|
||||
adjustY: number;
|
||||
};
|
||||
offset: number[];
|
||||
targetOffset: number[];
|
||||
};
|
||||
top: {
|
||||
points: string[];
|
||||
overflow: {
|
||||
adjustX: number;
|
||||
adjustY: number;
|
||||
};
|
||||
offset: number[];
|
||||
targetOffset: number[];
|
||||
};
|
||||
topRight: {
|
||||
points: string[];
|
||||
overflow: {
|
||||
adjustX: number;
|
||||
adjustY: number;
|
||||
};
|
||||
offset: number[];
|
||||
targetOffset: number[];
|
||||
};
|
||||
bottomLeft: {
|
||||
points: string[];
|
||||
overflow: {
|
||||
adjustX: number;
|
||||
adjustY: number;
|
||||
};
|
||||
offset: number[];
|
||||
targetOffset: number[];
|
||||
};
|
||||
bottom: {
|
||||
points: string[];
|
||||
overflow: {
|
||||
adjustX: number;
|
||||
adjustY: number;
|
||||
};
|
||||
offset: number[];
|
||||
targetOffset: number[];
|
||||
};
|
||||
bottomRight: {
|
||||
points: string[];
|
||||
overflow: {
|
||||
adjustX: number;
|
||||
adjustY: number;
|
||||
};
|
||||
offset: number[];
|
||||
targetOffset: number[];
|
||||
};
|
||||
};
|
||||
export default placements;
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
const autoAdjustOverflow = {
|
||||
adjustX: 1,
|
||||
adjustY: 1
|
||||
};
|
||||
const targetOffset = [0, 0];
|
||||
const placements = {
|
||||
topLeft: {
|
||||
points: ['bl', 'tl'],
|
||||
overflow: autoAdjustOverflow,
|
||||
offset: [0, -4],
|
||||
targetOffset
|
||||
},
|
||||
top: {
|
||||
points: ['bc', 'tc'],
|
||||
overflow: autoAdjustOverflow,
|
||||
offset: [0, -4],
|
||||
targetOffset
|
||||
},
|
||||
topRight: {
|
||||
points: ['br', 'tr'],
|
||||
overflow: autoAdjustOverflow,
|
||||
offset: [0, -4],
|
||||
targetOffset
|
||||
},
|
||||
bottomLeft: {
|
||||
points: ['tl', 'bl'],
|
||||
overflow: autoAdjustOverflow,
|
||||
offset: [0, 4],
|
||||
targetOffset
|
||||
},
|
||||
bottom: {
|
||||
points: ['tc', 'bc'],
|
||||
overflow: autoAdjustOverflow,
|
||||
offset: [0, 4],
|
||||
targetOffset
|
||||
},
|
||||
bottomRight: {
|
||||
points: ['tr', 'br'],
|
||||
overflow: autoAdjustOverflow,
|
||||
offset: [0, 4],
|
||||
targetOffset
|
||||
}
|
||||
};
|
||||
export default placements;
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
import type { TriggerProps, TriggerRef } from '@rc-component/trigger';
|
||||
import type { ActionType, AlignType, AnimationType, BuildInPlacements } from '@rc-component/trigger/lib/interface';
|
||||
import React from 'react';
|
||||
import Placements from './placements';
|
||||
export interface DropdownProps extends Pick<TriggerProps, 'getPopupContainer' | 'children' | 'mouseEnterDelay' | 'mouseLeaveDelay' | 'onPopupAlign' | 'builtinPlacements' | 'autoDestroy'> {
|
||||
minOverlayWidthMatchTrigger?: boolean;
|
||||
arrow?: boolean;
|
||||
onVisibleChange?: (visible: boolean) => void;
|
||||
onOverlayClick?: (e: Event) => void;
|
||||
prefixCls?: string;
|
||||
transitionName?: string;
|
||||
overlayClassName?: string;
|
||||
openClassName?: string;
|
||||
animation?: AnimationType;
|
||||
align?: AlignType;
|
||||
overlayStyle?: React.CSSProperties;
|
||||
placement?: keyof typeof Placements;
|
||||
placements?: BuildInPlacements;
|
||||
overlay?: (() => React.ReactElement) | React.ReactElement;
|
||||
trigger?: ActionType | ActionType[];
|
||||
alignPoint?: boolean;
|
||||
showAction?: ActionType[];
|
||||
hideAction?: ActionType[];
|
||||
visible?: boolean;
|
||||
autoFocus?: boolean;
|
||||
}
|
||||
declare const Dropdown: React.ForwardRefExoticComponent<DropdownProps & React.RefAttributes<TriggerRef>>;
|
||||
export default Dropdown;
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _trigger = _interopRequireDefault(require("@rc-component/trigger"));
|
||||
var _ref = require("@rc-component/util/lib/ref");
|
||||
var _clsx = require("clsx");
|
||||
var _react = _interopRequireDefault(require("react"));
|
||||
var _useAccessibility = _interopRequireDefault(require("./hooks/useAccessibility"));
|
||||
var _Overlay = _interopRequireDefault(require("./Overlay"));
|
||||
var _placements = _interopRequireDefault(require("./placements"));
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
||||
const Dropdown = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
|
||||
const {
|
||||
arrow = false,
|
||||
prefixCls = 'rc-dropdown',
|
||||
transitionName,
|
||||
animation,
|
||||
align,
|
||||
placement = 'bottomLeft',
|
||||
placements = _placements.default,
|
||||
getPopupContainer,
|
||||
showAction,
|
||||
hideAction,
|
||||
overlayClassName,
|
||||
overlayStyle,
|
||||
visible,
|
||||
trigger = ['hover'],
|
||||
autoFocus,
|
||||
overlay,
|
||||
children,
|
||||
onVisibleChange,
|
||||
...otherProps
|
||||
} = props;
|
||||
const [triggerVisible, setTriggerVisible] = _react.default.useState();
|
||||
const mergedVisible = 'visible' in props ? visible : triggerVisible;
|
||||
const mergedMotionName = animation ? `${prefixCls}-${animation}` : transitionName;
|
||||
const triggerRef = _react.default.useRef(null);
|
||||
const overlayRef = _react.default.useRef(null);
|
||||
const childRef = _react.default.useRef(null);
|
||||
_react.default.useImperativeHandle(ref, () => triggerRef.current);
|
||||
const handleVisibleChange = newVisible => {
|
||||
setTriggerVisible(newVisible);
|
||||
onVisibleChange?.(newVisible);
|
||||
};
|
||||
(0, _useAccessibility.default)({
|
||||
visible: mergedVisible,
|
||||
triggerRef: childRef,
|
||||
onVisibleChange: handleVisibleChange,
|
||||
autoFocus,
|
||||
overlayRef
|
||||
});
|
||||
const onClick = e => {
|
||||
const {
|
||||
onOverlayClick
|
||||
} = props;
|
||||
setTriggerVisible(false);
|
||||
if (onOverlayClick) {
|
||||
onOverlayClick(e);
|
||||
}
|
||||
};
|
||||
const getMenuElement = () => /*#__PURE__*/_react.default.createElement(_Overlay.default, {
|
||||
ref: overlayRef,
|
||||
overlay: overlay,
|
||||
prefixCls: prefixCls,
|
||||
arrow: arrow
|
||||
});
|
||||
const getMenuElementOrLambda = () => {
|
||||
if (typeof overlay === 'function') {
|
||||
return getMenuElement;
|
||||
}
|
||||
return getMenuElement();
|
||||
};
|
||||
const getMinOverlayWidthMatchTrigger = () => {
|
||||
const {
|
||||
minOverlayWidthMatchTrigger,
|
||||
alignPoint
|
||||
} = props;
|
||||
if ('minOverlayWidthMatchTrigger' in props) {
|
||||
return minOverlayWidthMatchTrigger;
|
||||
}
|
||||
return !alignPoint;
|
||||
};
|
||||
const getOpenClassName = () => {
|
||||
const {
|
||||
openClassName
|
||||
} = props;
|
||||
if (openClassName !== undefined) {
|
||||
return openClassName;
|
||||
}
|
||||
return `${prefixCls}-open`;
|
||||
};
|
||||
const childrenNode = /*#__PURE__*/_react.default.cloneElement(children, {
|
||||
className: (0, _clsx.clsx)(children.props?.className, mergedVisible && getOpenClassName()),
|
||||
ref: (0, _ref.supportRef)(children) ? (0, _ref.composeRef)(childRef, (0, _ref.getNodeRef)(children)) : undefined
|
||||
});
|
||||
let triggerHideAction = hideAction;
|
||||
if (!triggerHideAction && trigger.indexOf('contextMenu') !== -1) {
|
||||
triggerHideAction = ['click'];
|
||||
}
|
||||
return /*#__PURE__*/_react.default.createElement(_trigger.default, _extends({
|
||||
builtinPlacements: placements
|
||||
}, otherProps, {
|
||||
prefixCls: prefixCls,
|
||||
ref: triggerRef,
|
||||
popupClassName: (0, _clsx.clsx)(overlayClassName, {
|
||||
[`${prefixCls}-show-arrow`]: arrow
|
||||
}),
|
||||
popupStyle: overlayStyle,
|
||||
action: trigger,
|
||||
showAction: showAction,
|
||||
hideAction: triggerHideAction,
|
||||
popupPlacement: placement,
|
||||
popupAlign: align,
|
||||
popupMotion: {
|
||||
motionName: mergedMotionName
|
||||
},
|
||||
popupVisible: mergedVisible,
|
||||
stretch: getMinOverlayWidthMatchTrigger() ? 'minWidth' : '',
|
||||
popup: getMenuElementOrLambda(),
|
||||
onOpenChange: handleVisibleChange,
|
||||
onPopupClick: onClick,
|
||||
getPopupContainer: getPopupContainer
|
||||
}), childrenNode);
|
||||
});
|
||||
var _default = exports.default = Dropdown;
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import React from 'react';
|
||||
import type { DropdownProps } from './Dropdown';
|
||||
export type OverlayProps = Pick<DropdownProps, 'overlay' | 'arrow' | 'prefixCls'>;
|
||||
declare const Overlay: React.ForwardRefExoticComponent<OverlayProps & React.RefAttributes<HTMLElement>>;
|
||||
export default Overlay;
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _ref = require("@rc-component/util/lib/ref");
|
||||
var _react = _interopRequireWildcard(require("react"));
|
||||
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
||||
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
||||
const Overlay = /*#__PURE__*/(0, _react.forwardRef)((props, ref) => {
|
||||
const {
|
||||
overlay,
|
||||
arrow,
|
||||
prefixCls
|
||||
} = props;
|
||||
const overlayNode = (0, _react.useMemo)(() => {
|
||||
let overlayElement;
|
||||
if (typeof overlay === 'function') {
|
||||
overlayElement = overlay();
|
||||
} else {
|
||||
overlayElement = overlay;
|
||||
}
|
||||
return overlayElement;
|
||||
}, [overlay]);
|
||||
const composedRef = (0, _ref.composeRef)(ref, (0, _ref.getNodeRef)(overlayNode));
|
||||
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, arrow && /*#__PURE__*/_react.default.createElement("div", {
|
||||
className: `${prefixCls}-arrow`
|
||||
}), /*#__PURE__*/_react.default.cloneElement(overlayNode, {
|
||||
ref: (0, _ref.supportRef)(overlayNode) ? composedRef : undefined
|
||||
}));
|
||||
});
|
||||
var _default = exports.default = Overlay;
|
||||
Generated
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
import * as React from 'react';
|
||||
interface UseAccessibilityProps {
|
||||
visible: boolean;
|
||||
triggerRef: React.RefObject<any>;
|
||||
onVisibleChange?: (visible: boolean) => void;
|
||||
autoFocus?: boolean;
|
||||
overlayRef?: React.RefObject<any>;
|
||||
}
|
||||
export default function useAccessibility({ visible, triggerRef, onVisibleChange, autoFocus, overlayRef, }: UseAccessibilityProps): void;
|
||||
export {};
|
||||
Generated
Vendored
+75
@@ -0,0 +1,75 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = useAccessibility;
|
||||
var _KeyCode = _interopRequireDefault(require("@rc-component/util/lib/KeyCode"));
|
||||
var _raf = _interopRequireDefault(require("@rc-component/util/lib/raf"));
|
||||
var React = _interopRequireWildcard(require("react"));
|
||||
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
||||
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
const {
|
||||
ESC,
|
||||
TAB
|
||||
} = _KeyCode.default;
|
||||
function useAccessibility({
|
||||
visible,
|
||||
triggerRef,
|
||||
onVisibleChange,
|
||||
autoFocus,
|
||||
overlayRef
|
||||
}) {
|
||||
const focusMenuRef = React.useRef(false);
|
||||
const handleCloseMenuAndReturnFocus = () => {
|
||||
if (visible) {
|
||||
triggerRef.current?.focus?.();
|
||||
onVisibleChange?.(false);
|
||||
}
|
||||
};
|
||||
const focusMenu = () => {
|
||||
if (overlayRef.current?.focus) {
|
||||
overlayRef.current.focus();
|
||||
focusMenuRef.current = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
const handleKeyDown = event => {
|
||||
switch (event.keyCode) {
|
||||
case ESC:
|
||||
handleCloseMenuAndReturnFocus();
|
||||
break;
|
||||
case TAB:
|
||||
{
|
||||
let focusResult = false;
|
||||
if (!focusMenuRef.current) {
|
||||
focusResult = focusMenu();
|
||||
}
|
||||
if (focusResult) {
|
||||
event.preventDefault();
|
||||
} else {
|
||||
handleCloseMenuAndReturnFocus();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
React.useEffect(() => {
|
||||
if (visible) {
|
||||
window.addEventListener('keydown', handleKeyDown);
|
||||
if (autoFocus) {
|
||||
// FIXME: hack with raf
|
||||
(0, _raf.default)(focusMenu, 3);
|
||||
}
|
||||
return () => {
|
||||
window.removeEventListener('keydown', handleKeyDown);
|
||||
focusMenuRef.current = false;
|
||||
};
|
||||
}
|
||||
return () => {
|
||||
focusMenuRef.current = false;
|
||||
};
|
||||
}, [visible]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
export type { TriggerProps } from '@rc-component/trigger';
|
||||
export type { DropdownProps } from './Dropdown';
|
||||
export type { OverlayProps } from './Overlay';
|
||||
import Dropdown from './Dropdown';
|
||||
export default Dropdown;
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _Dropdown = _interopRequireDefault(require("./Dropdown"));
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
var _default = exports.default = _Dropdown.default;
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
declare const placements: {
|
||||
topLeft: {
|
||||
points: string[];
|
||||
overflow: {
|
||||
adjustX: number;
|
||||
adjustY: number;
|
||||
};
|
||||
offset: number[];
|
||||
targetOffset: number[];
|
||||
};
|
||||
top: {
|
||||
points: string[];
|
||||
overflow: {
|
||||
adjustX: number;
|
||||
adjustY: number;
|
||||
};
|
||||
offset: number[];
|
||||
targetOffset: number[];
|
||||
};
|
||||
topRight: {
|
||||
points: string[];
|
||||
overflow: {
|
||||
adjustX: number;
|
||||
adjustY: number;
|
||||
};
|
||||
offset: number[];
|
||||
targetOffset: number[];
|
||||
};
|
||||
bottomLeft: {
|
||||
points: string[];
|
||||
overflow: {
|
||||
adjustX: number;
|
||||
adjustY: number;
|
||||
};
|
||||
offset: number[];
|
||||
targetOffset: number[];
|
||||
};
|
||||
bottom: {
|
||||
points: string[];
|
||||
overflow: {
|
||||
adjustX: number;
|
||||
adjustY: number;
|
||||
};
|
||||
offset: number[];
|
||||
targetOffset: number[];
|
||||
};
|
||||
bottomRight: {
|
||||
points: string[];
|
||||
overflow: {
|
||||
adjustX: number;
|
||||
adjustY: number;
|
||||
};
|
||||
offset: number[];
|
||||
targetOffset: number[];
|
||||
};
|
||||
};
|
||||
export default placements;
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
const autoAdjustOverflow = {
|
||||
adjustX: 1,
|
||||
adjustY: 1
|
||||
};
|
||||
const targetOffset = [0, 0];
|
||||
const placements = {
|
||||
topLeft: {
|
||||
points: ['bl', 'tl'],
|
||||
overflow: autoAdjustOverflow,
|
||||
offset: [0, -4],
|
||||
targetOffset
|
||||
},
|
||||
top: {
|
||||
points: ['bc', 'tc'],
|
||||
overflow: autoAdjustOverflow,
|
||||
offset: [0, -4],
|
||||
targetOffset
|
||||
},
|
||||
topRight: {
|
||||
points: ['br', 'tr'],
|
||||
overflow: autoAdjustOverflow,
|
||||
offset: [0, -4],
|
||||
targetOffset
|
||||
},
|
||||
bottomLeft: {
|
||||
points: ['tl', 'bl'],
|
||||
overflow: autoAdjustOverflow,
|
||||
offset: [0, 4],
|
||||
targetOffset
|
||||
},
|
||||
bottom: {
|
||||
points: ['tc', 'bc'],
|
||||
overflow: autoAdjustOverflow,
|
||||
offset: [0, 4],
|
||||
targetOffset
|
||||
},
|
||||
bottomRight: {
|
||||
points: ['tr', 'br'],
|
||||
overflow: autoAdjustOverflow,
|
||||
offset: [0, 4],
|
||||
targetOffset
|
||||
}
|
||||
};
|
||||
var _default = exports.default = placements;
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"name": "@rc-component/dropdown",
|
||||
"version": "1.0.2",
|
||||
"description": "dropdown ui component for react",
|
||||
"keywords": [
|
||||
"react",
|
||||
"react-dropdown"
|
||||
],
|
||||
"homepage": "http://github.com/react-component/dropdown",
|
||||
"bugs": {
|
||||
"url": "http://github.com/react-component/dropdown/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:react-component/dropdown.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"maintainers": [
|
||||
"yiminghe@gmail.com",
|
||||
"hualei5280@gmail.com"
|
||||
],
|
||||
"main": "lib/index",
|
||||
"module": "./es/index",
|
||||
"files": [
|
||||
"lib",
|
||||
"es",
|
||||
"assets/*.css"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "dumi build",
|
||||
"compile": "father build && lessc assets/index.less assets/index.css",
|
||||
"coverage": "rc-test --coverage",
|
||||
"lint": "eslint src/ docs/examples/ --ext .tsx,.ts,.jsx,.js",
|
||||
"now-build": "npm run build",
|
||||
"prepare": "husky install && dumi setup",
|
||||
"prepublishOnly": "npm run compile && rc-np",
|
||||
"start": "dumi dev",
|
||||
"test": "rc-test"
|
||||
},
|
||||
"lint-staged": {
|
||||
"**/*.{js,jsx,tsx,ts,md,json}": [
|
||||
"prettier --write",
|
||||
"git add"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@rc-component/trigger": "^3.0.0",
|
||||
"@rc-component/util": "^1.2.1",
|
||||
"clsx": "^2.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rc-component/father-plugin": "^2.0.2",
|
||||
"@rc-component/menu": "^1.0.0",
|
||||
"@rc-component/np": "^1.0.3",
|
||||
"@rc-component/resize-observer": "^1.0.0",
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^14.0.0",
|
||||
"@types/jest": "^29.0.0",
|
||||
"@types/node": "^24.5.2",
|
||||
"@types/react": "^18.0.0",
|
||||
"@types/react-dom": "^18.0.0",
|
||||
"@types/warning": "^3.0.0",
|
||||
"@umijs/fabric": "^3.0.0",
|
||||
"dumi": "^2.0.0",
|
||||
"eslint": "^7.18.0",
|
||||
"father": "^4.0.0",
|
||||
"glob": "^10.0.0",
|
||||
"husky": "^8.0.3",
|
||||
"jest-environment-jsdom": "^29.5.0",
|
||||
"less": "^4.1.1",
|
||||
"lint-staged": "^13.2.1",
|
||||
"prettier": "^2.8.7",
|
||||
"rc-test": "^7.0.14",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0",
|
||||
"typescript": "^5.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.11.0",
|
||||
"react-dom": ">=16.11.0"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user