Skip to content

Commit 70ab693

Browse files
authored
refactor: Use rc-trigger v4 (#291)
* remove shim * clean up * fix trigger logic
1 parent 2f3cf12 commit 70ab693

File tree

6 files changed

+52
-84
lines changed

6 files changed

+52
-84
lines changed

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,8 @@
4848
"classnames": "2.x",
4949
"dom-scroll-into-view": "1.x",
5050
"mini-store": "^2.0.0",
51-
"mutationobserver-shim": "^0.3.2",
5251
"rc-animate": "^2.10.1",
53-
"rc-trigger": "^2.3.0",
52+
"rc-trigger": "^4.0.0-alpha.4",
5453
"rc-util": "^4.13.0",
5554
"resize-observer-polyfill": "^1.5.0",
5655
"shallowequal": "^1.1.0"

src/DOMWrap.tsx

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,9 @@ import SubMenu from './SubMenu';
55
import { getWidth, setStyle, menuAllProps } from './util';
66
import { MenuMode } from './interface';
77

8-
const canUseDOM = !!(
9-
typeof window !== 'undefined' &&
10-
window.document &&
11-
window.document.createElement
12-
);
13-
148
const MENUITEM_OVERFLOWED_CLASSNAME = 'menuitem-overflowed';
159
const FLOAT_PRECISION_ADJUST = 0.5;
1610

17-
// Fix ssr
18-
if (canUseDOM) {
19-
// eslint-disable-next-line global-require
20-
require('mutationobserver-shim');
21-
}
22-
2311
interface DOMWrapProps {
2412
className?: string;
2513
children?: React.ReactElement[];

src/SubMenu.tsx

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import React from 'react';
22
import ReactDOM from 'react-dom';
33
import Trigger from 'rc-trigger';
44
import KeyCode from 'rc-util/lib/KeyCode';
5-
// import Animate from 'rc-animate';
65
import CSSMotion from 'rc-animate/lib/CSSMotion';
76
import classNames from 'classnames';
87
import { connect } from 'mini-store';
@@ -388,9 +387,9 @@ export class SubMenu extends React.Component<SubMenuProps> {
388387
this.subMenuTitle = subMenuTitle;
389388
};
390389

391-
renderChildren(children: React.ReactNode) {
390+
getBaseProps = (): SubPopupMenuProps => {
392391
const { props } = this;
393-
const baseProps: SubPopupMenuProps = {
392+
return {
394393
mode: props.mode === 'horizontal' ? 'vertical' : props.mode,
395394
visible: this.props.isOpen,
396395
level: props.level + 1,
@@ -421,8 +420,31 @@ export class SubMenu extends React.Component<SubMenuProps> {
421420
itemIcon: props.itemIcon,
422421
expandIcon: props.expandIcon,
423422
};
423+
};
424424

425+
getMotion = (mode: MenuMode, visible: boolean) => {
425426
const { haveRendered } = this;
427+
const { motion, rootPrefixCls } = this.props;
428+
429+
// don't show transition on first rendering (no animation for opened menu)
430+
// show appear transition if it's not visible (not sure why)
431+
// show appear transition if it's not inline mode
432+
const mergedMotion: MotionType = {
433+
...motion,
434+
leavedClassName: `${rootPrefixCls}-hidden`,
435+
removeOnLeave: false,
436+
motionAppear: haveRendered || !visible || mode !== 'inline',
437+
};
438+
439+
return mergedMotion;
440+
};
441+
442+
renderChildren(children: React.ReactNode) {
443+
const baseProps = this.getBaseProps();
444+
445+
// [Legacy] getMotion must be called before `haveRendered`
446+
const mergedMotion = this.getMotion(baseProps.mode, baseProps.visible);
447+
426448
this.haveRendered = true;
427449

428450
this.haveOpened =
@@ -432,18 +454,6 @@ export class SubMenu extends React.Component<SubMenuProps> {
432454
return <div />;
433455
}
434456

435-
// ================== Motion ==================
436-
// don't show transition on first rendering (no animation for opened menu)
437-
// show appear transition if it's not visible (not sure why)
438-
// show appear transition if it's not inline mode
439-
const mergedMotion: MotionType = {
440-
...props.motion,
441-
leavedClassName: `${props.rootPrefixCls}-hidden`,
442-
removeOnLeave: false,
443-
motionAppear:
444-
haveRendered || !baseProps.visible || baseProps.mode !== 'inline',
445-
};
446-
447457
return (
448458
<CSSMotion visible={baseProps.visible} {...mergedMotion}>
449459
{({ className, style }) => {
@@ -550,6 +560,11 @@ export class SubMenu extends React.Component<SubMenuProps> {
550560
{icon || <i className={`${prefixCls}-arrow`} />}
551561
</div>
552562
);
563+
564+
// [Legacy] `getMotion` should call before `renderChildren`
565+
const baseProps = this.getBaseProps();
566+
const motion = this.getMotion(baseProps.mode, baseProps.visible);
567+
553568
const children = this.renderChildren(props.children);
554569

555570
const getPopupContainer = props.parentMenu.isRootMenu
@@ -594,6 +609,7 @@ export class SubMenu extends React.Component<SubMenuProps> {
594609
mouseLeaveDelay={subMenuCloseDelay}
595610
onPopupVisibleChange={this.onPopupVisibleChange}
596611
forceRender={forceSubMenuRender}
612+
popupMotion={motion}
597613
>
598614
{title}
599615
</Trigger>

src/interface.ts

Lines changed: 7 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
import {
2+
AnimationType,
3+
TransitionNameType,
4+
MotionType,
5+
} from 'rc-trigger/lib/interface';
6+
17
export type RenderIconType =
28
| React.ReactNode
39
| ((props: any) => React.ReactNode);
@@ -60,45 +66,4 @@ export type BuiltinPlacements = Record<string, any>;
6066
export type TriggerSubMenuAction = 'click' | 'hover';
6167

6268
// =================================== Motion ===================================
63-
export type AnimationType = string | Record<string, any>;
64-
65-
export type TransitionNameType = string;
66-
67-
/**
68-
* Follow Motion definition is copied from `rc-trigger@latest`.
69-
* These code can be removed when `rc-trigger` updated.
70-
*/
71-
// TODO: Use define by `rc-trigger@latest`
72-
type MotionStatus = 'none' | 'appear' | 'enter' | 'leave';
73-
74-
type MotionActiveStatus = 'appear-active' | 'enter-active' | 'leave-active';
75-
76-
type MotionNameObject = {
77-
[key in MotionStatus | MotionActiveStatus]?: string;
78-
};
79-
80-
type MotionEventHandler = (
81-
element: HTMLElement,
82-
event:
83-
| React.TransitionEvent<HTMLElement>
84-
| React.AnimationEvent<HTMLElement>
85-
| undefined,
86-
) => React.CSSProperties | false | null | undefined | void;
87-
export interface MotionType {
88-
motionName?: string | MotionNameObject;
89-
motionAppear?: boolean;
90-
motionEnter?: boolean;
91-
motionLeave?: boolean;
92-
motionLeaveImmediately?: boolean; // Trigger leave motion immediately
93-
removeOnLeave?: boolean;
94-
leavedClassName?: string;
95-
onAppearStart?: MotionEventHandler;
96-
onAppearActive?: MotionEventHandler;
97-
onAppearEnd?: MotionEventHandler;
98-
onEnterStart?: MotionEventHandler;
99-
onEnterActive?: MotionEventHandler;
100-
onEnterEnd?: MotionEventHandler;
101-
onLeaveStart?: MotionEventHandler;
102-
onLeaveActive?: MotionEventHandler;
103-
onLeaveEnd?: MotionEventHandler;
104-
}
69+
export { AnimationType, TransitionNameType, MotionType };

tests/Menu.spec.js

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
jest.mock('mutationobserver-shim');
2-
3-
const mockedUtil = require('../src/util');
4-
5-
/* eslint-disable no-undef, react/no-multi-comp */
1+
/* eslint-disable no-undef, react/no-multi-comp, react/jsx-curly-brace-presence */
62
import React from 'react';
73
import { render, mount } from 'enzyme';
84
import { renderToJson } from 'enzyme-to-json';
95
import KeyCode from 'rc-util/lib/KeyCode';
106
import Menu, { MenuItem, MenuItemGroup, SubMenu, Divider } from '../src';
7+
import * as mockedUtil from '../src/util';
118

129
describe('Menu', () => {
1310
describe('should render', () => {
@@ -76,7 +73,7 @@ describe('Menu', () => {
7673
);
7774
}
7875

79-
it(`renders menu correctly`, () => {
76+
it('renders menu correctly', () => {
8077
const wrapper = render(createMenu());
8178
expect(renderToJson(wrapper)).toMatchSnapshot();
8279
});
@@ -477,7 +474,9 @@ describe('Menu', () => {
477474
const widths = [...liWidths, indicatorWidth, availableWidth];
478475
let i = 0;
479476
mockedUtil.getWidth = () => {
480-
return widths[i++];
477+
const id = i;
478+
i += 1;
479+
return widths[id];
481480
};
482481
wrapper = mount(createMenu());
483482

@@ -535,7 +534,9 @@ describe('Menu', () => {
535534
const widths = [...liWidths, indicatorWidth, availableWidth];
536535
let i = 0;
537536
mockedUtil.getWidth = () => {
538-
return widths[i++];
537+
const id = i;
538+
i += 1;
539+
return widths[id];
539540
};
540541
wrapper = mount(createMenu());
541542

@@ -589,7 +590,9 @@ describe('Menu', () => {
589590
let i = 0;
590591

591592
mockedUtil.getWidth = () => {
592-
return widths[i++];
593+
const id = i;
594+
i += 1;
595+
return widths[id];
593596
};
594597

595598
wrapper = mount(createMenu());
@@ -626,3 +629,4 @@ describe('Menu', () => {
626629
});
627630
});
628631
});
632+
/* eslint-enable */

tests/__mocks__/mutationobserver-shim.js

Lines changed: 0 additions & 4 deletions
This file was deleted.

0 commit comments

Comments
 (0)