Skip to content

Commit a0d1785

Browse files
authored
refactor: Remove all coupling code (#218)
* chore: bump rc-trigger * refactor: clean up content * test: test fix
1 parent aee201b commit a0d1785

File tree

7 files changed

+34
-43
lines changed

7 files changed

+34
-43
lines changed

assets/index.less

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
display: none;
2929
}
3030

31-
&-menu {
31+
.rc-menu {
3232
outline: none;
3333
position: relative;
3434
list-style-type: none;

package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,17 @@
5555
"rc-menu": "^9.5.2",
5656
"react": "^16.11.0",
5757
"react-dom": "^16.11.0",
58+
"regenerator-runtime": "^0.13.9",
5859
"typescript": "^4.0.2"
5960
},
6061
"peerDependencies": {
6162
"react": ">=16.11.0",
6263
"react-dom": ">=16.11.0"
6364
},
6465
"dependencies": {
65-
"@babel/runtime": "^7.10.1",
66+
"@babel/runtime": "^7.18.3",
6667
"classnames": "^2.2.6",
67-
"rc-trigger": "^5.0.4",
68+
"rc-trigger": "^5.3.1",
6869
"rc-util": "^5.17.0"
6970
}
7071
}

src/Dropdown.tsx

+4-23
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import type {
1010
} from 'rc-trigger/lib/interface';
1111
import Placements from './placements';
1212
import useAccessibility from './hooks/useAccessibility';
13-
import { composeRef, supportRef } from 'rc-util/lib/ref';
1413

1514
export interface DropdownProps
1615
extends Pick<
@@ -70,14 +69,10 @@ function Dropdown(props: DropdownProps, ref) {
7069
const triggerRef = React.useRef(null);
7170
React.useImperativeHandle(ref, () => triggerRef.current);
7271

73-
const menuRef = React.useRef(null);
74-
const menuClassName = `${prefixCls}-menu`;
75-
7672
useAccessibility({
7773
visible: mergedVisible,
7874
setTriggerVisible,
7975
triggerRef,
80-
menuRef,
8176
onVisibleChange: props.onVisibleChange,
8277
autoFocus,
8378
});
@@ -95,15 +90,12 @@ function Dropdown(props: DropdownProps, ref) {
9590

9691
const onClick = (e) => {
9792
const { onOverlayClick } = props;
98-
const overlayProps = getOverlayElement().props;
9993
setTriggerVisible(false);
10094

95+
console.log('!!!!!!!!!!!!', onOverlayClick);
10196
if (onOverlayClick) {
10297
onOverlayClick(e);
10398
}
104-
if (overlayProps.onClick) {
105-
overlayProps.onClick(e);
106-
}
10799
};
108100

109101
const onVisibleChange = (newVisible: boolean) => {
@@ -116,23 +108,11 @@ function Dropdown(props: DropdownProps, ref) {
116108

117109
const getMenuElement = () => {
118110
const overlayElement = getOverlayElement();
119-
// @ts-ignore
120-
const composedMenuRef = composeRef(menuRef, overlayElement.ref);
121-
122-
const extraOverlayProps = {
123-
prefixCls: menuClassName,
124-
['data-dropdown-inject']: true,
125-
onClick,
126-
ref: supportRef(overlayElement) ? composedMenuRef : undefined,
127-
};
128-
if (typeof overlayElement.type === 'string') {
129-
delete extraOverlayProps.prefixCls;
130-
delete extraOverlayProps['data-dropdown-inject'];
131-
}
111+
132112
return (
133113
<>
134114
{arrow && <div className={`${prefixCls}-arrow`} />}
135-
{React.cloneElement(overlayElement, extraOverlayProps)}
115+
{overlayElement}
136116
</>
137117
);
138118
};
@@ -199,6 +179,7 @@ function Dropdown(props: DropdownProps, ref) {
199179
stretch={getMinOverlayWidthMatchTrigger() ? 'minWidth' : ''}
200180
popup={getMenuElementOrLambda()}
201181
onPopupVisibleChange={onVisibleChange}
182+
onPopupClick={onClick}
202183
getPopupContainer={getPopupContainer}
203184
>
204185
{renderChildren()}

src/hooks/useAccessibility.ts

+18-7
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import * as React from 'react';
22
import KeyCode from 'rc-util/lib/KeyCode';
33
import raf from 'rc-util/lib/raf';
4+
import { getFocusNodeList } from 'rc-util/lib/Dom/focus';
45

56
const { ESC, TAB } = KeyCode;
67

78
interface UseAccessibilityProps {
89
visible: boolean;
910
setTriggerVisible: (visible: boolean) => void;
1011
triggerRef: React.RefObject<any>;
11-
menuRef: React.RefObject<HTMLUListElement>;
1212
onVisibleChange?: (visible: boolean) => void;
1313
autoFocus?: boolean;
1414
}
@@ -17,7 +17,6 @@ export default function useAccessibility({
1717
visible,
1818
setTriggerVisible,
1919
triggerRef,
20-
menuRef,
2120
onVisibleChange,
2221
autoFocus,
2322
}: UseAccessibilityProps) {
@@ -34,23 +33,35 @@ export default function useAccessibility({
3433
};
3534

3635
const focusMenu = () => {
37-
menuRef.current?.focus?.();
38-
focusMenuRef.current = true;
36+
const elements = getFocusNodeList(triggerRef.current?.popupRef?.current?.getElement?.());
37+
const firstElement = elements[0];
38+
39+
if (firstElement?.focus) {
40+
firstElement.focus();
41+
focusMenuRef.current = true;
42+
return true;
43+
}
44+
return false;
3945
};
4046

4147
const handleKeyDown = (event) => {
4248
switch (event.keyCode) {
4349
case ESC:
4450
handleCloseMenuAndReturnFocus();
4551
break;
46-
case TAB:
47-
if (!focusMenuRef.current && menuRef.current?.focus) {
52+
case TAB: {
53+
let focusResult: boolean = false;
54+
if (!focusMenuRef.current) {
55+
focusResult = focusMenu();
56+
}
57+
58+
if (focusResult) {
4859
event.preventDefault();
49-
focusMenu();
5060
} else {
5161
handleCloseMenuAndReturnFocus();
5262
}
5363
break;
64+
}
5465
}
5566
};
5667

tests/__snapshots__/basic.test.js.snap

+4-5
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,14 @@ Array [
1313
style="opacity: 0;"
1414
>
1515
<ul
16-
class="rc-dropdown-menu rc-dropdown-menu-root rc-dropdown-menu-vertical"
17-
data-dropdown-inject="true"
16+
class="rc-menu rc-menu-root rc-menu-vertical"
1817
data-menu-list="true"
1918
role="menu"
2019
style="width: 140px;"
2120
tabindex="0"
2221
>
2322
<li
24-
class="rc-dropdown-menu-item"
23+
class="rc-menu-item"
2524
data-menu-id="rc-menu-uuid-test-1"
2625
role="menuitem"
2726
tabindex="-1"
@@ -33,10 +32,10 @@ Array [
3332
</span>
3433
</li>
3534
<li
36-
class="rc-dropdown-menu-item-divider"
35+
class="rc-menu-item-divider"
3736
/>
3837
<li
39-
class="rc-dropdown-menu-item"
38+
class="rc-menu-item"
4039
data-menu-id="rc-menu-uuid-test-2"
4140
role="menuitem"
4241
tabindex="-1"

tests/basic.test.js

+2-5
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,12 @@ describe('dropdown', () => {
6666

6767
it('simply works', async () => {
6868
let clicked;
69-
let overlayClicked;
7069

7170
function onClick({ key }) {
7271
clicked = key;
7372
}
7473

75-
function onOverlayClick({ key }) {
76-
overlayClicked = key;
77-
}
74+
const onOverlayClick = jest.fn();
7875

7976
const menu = (
8077
<Menu style={{ width: 140 }} onClick={onClick}>
@@ -100,7 +97,7 @@ describe('dropdown', () => {
10097

10198
dropdown.find('.my-menuitem').simulate('click');
10299
expect(clicked).toBe('1');
103-
expect(overlayClicked).toBe('1');
100+
expect(onOverlayClick).toHaveBeenCalled();
104101
expect(getPopupDomNode(dropdown).classList.contains('rc-dropdown-hidden')).toBe(true);
105102
});
106103

tests/setup.js

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ global.requestAnimationFrame =
44
return setTimeout(cb, 0);
55
};
66

7+
require('regenerator-runtime/runtime');
8+
79
const Enzyme = require('enzyme');
810
const Adapter = require('enzyme-adapter-react-16');
911

0 commit comments

Comments
 (0)