diff --git a/.eslintrc.js b/.eslintrc.js
index 7e19ab39..15621baf 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -10,5 +10,10 @@ module.exports = {
'react/sort-comp': 0,
'jsx-a11y/label-has-for': 0,
'jsx-a11y/label-has-associated-control': 0,
+ '@typescript-eslint/consistent-indexed-object-style': 0,
+ '@typescript-eslint/no-parameter-properties': 0,
+ '@typescript-eslint/ban-types': 0,
+ '@typescript-eslint/type-annotation-spacing': 0,
+ '@typescript-eslint/no-throw-literal': 0,
},
};
diff --git a/assets/index/Mobile.less b/assets/index/Mobile.less
index 3c302caf..81cdd3b9 100644
--- a/assets/index/Mobile.less
+++ b/assets/index/Mobile.less
@@ -1,25 +1,55 @@
.@{triggerPrefixCls} {
&-mobile {
- transition: all 0.3s;
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: auto;
- &-fade {
- &-appear,
- &-enter {
- &-start {
- transform: translateY(100%);
+ // Motion
+ &.raise {
+ &-enter,
+ &-appear {
+ transform: translateY(100%);
+
+ &-active {
+ transition: all 0.3s;
+ transform: translateY(0);
}
}
&-leave {
+ transform: translateY(0);
+
&-active {
+ transition: all 0.3s;
transform: translateY(100%);
}
}
}
+
+ // Mask
+ &-mask {
+ &.fade {
+ &-enter,
+ &-appear {
+ opacity: 0;
+
+ &-active {
+ transition: all 0.3s;
+ opacity: 1;
+ }
+ }
+
+ &-leave {
+ opacity: 1;
+
+ &-active {
+ transition: all 0.3s;
+ opacity: 0;
+ }
+ }
+ }
+ }
}
}
diff --git a/docs/demos/mobile.md b/docs/demos/mobile.md
new file mode 100644
index 00000000..298eb128
--- /dev/null
+++ b/docs/demos/mobile.md
@@ -0,0 +1,8 @@
+---
+title: Mobile
+nav:
+ title: Demo
+ path: /demo
+---
+
+
diff --git a/docs/examples/mobile.tsx b/docs/examples/mobile.tsx
new file mode 100644
index 00000000..37d50f3b
--- /dev/null
+++ b/docs/examples/mobile.tsx
@@ -0,0 +1,68 @@
+import Trigger from '@rc-component/trigger';
+import React from 'react';
+import '../../assets/index.less';
+
+const builtinPlacements = {
+ left: {
+ points: ['cr', 'cl'],
+ },
+ right: {
+ points: ['cl', 'cr'],
+ },
+ top: {
+ points: ['bc', 'tc'],
+ },
+ bottom: {
+ points: ['tc', 'bc'],
+ },
+ topLeft: {
+ points: ['bl', 'tl'],
+ },
+ topRight: {
+ points: ['br', 'tr'],
+ },
+ bottomRight: {
+ points: ['tr', 'br'],
+ },
+ bottomLeft: {
+ points: ['tl', 'bl'],
+ },
+};
+
+const Test = () => {
+ const [open1, setOpen1] = React.useState(false);
+
+ return (
+
+
+
+ Hello World
+
+ }
+ mobile={{
+ mask: true,
+ motion: { motionName: 'raise' },
+ maskMotion: { motionName: 'fade' },
+ }}
+ >
+
Click Me
+
+
+
+ );
+};
+
+export default Test;
diff --git a/package.json b/package.json
index 9920cf1c..1996c6d9 100644
--- a/package.json
+++ b/package.json
@@ -61,7 +61,7 @@
"react": "^18.0.0",
"react-dom": "^18.0.0",
"regenerator-runtime": "^0.14.0",
- "typescript": "^5.1.6"
+ "typescript": "~5.1.6"
},
"dependencies": {
"@rc-component/motion": "^1.1.4",
diff --git a/src/Popup/Mask.tsx b/src/Popup/Mask.tsx
index 125fe458..4c376da4 100644
--- a/src/Popup/Mask.tsx
+++ b/src/Popup/Mask.tsx
@@ -11,6 +11,8 @@ export interface MaskProps {
// Motion
motion?: CSSMotionProps;
+
+ mobile?: boolean;
}
export default function Mask(props: MaskProps) {
@@ -21,6 +23,8 @@ export default function Mask(props: MaskProps) {
mask,
motion,
+
+ mobile,
} = props;
if (!mask) {
@@ -32,7 +36,11 @@ export default function Mask(props: MaskProps) {
{({ className }) => (
)}
diff --git a/src/Popup/index.tsx b/src/Popup/index.tsx
index 167a4aa5..b617bb8b 100644
--- a/src/Popup/index.tsx
+++ b/src/Popup/index.tsx
@@ -11,6 +11,14 @@ import Arrow from './Arrow';
import Mask from './Mask';
import PopupContent from './PopupContent';
+export interface MobileConfig {
+ mask?: boolean;
+ /** Set popup motion. You can ref `rc-motion` for more info. */
+ motion?: CSSMotionProps;
+ /** Set mask motion. You can ref `rc-motion` for more info. */
+ maskMotion?: CSSMotionProps;
+}
+
export interface PopupProps {
prefixCls: string;
className?: string;
@@ -63,6 +71,9 @@ export interface PopupProps {
stretch?: string;
targetWidth?: number;
targetHeight?: number;
+
+ // Mobile
+ mobile?: MobileConfig;
}
const Popup = React.forwardRef((props, ref) => {
@@ -95,6 +106,9 @@ const Popup = React.forwardRef((props, ref) => {
motion,
maskMotion,
+ // Mobile
+ mobile,
+
// Portal
forceRender,
getPopupContainer,
@@ -126,6 +140,24 @@ const Popup = React.forwardRef((props, ref) => {
// We can not remove holder only when motion finished.
const isNodeVisible = open || keepDom;
+ // ========================= Mobile =========================
+ const isMobile = !!mobile;
+
+ // ========================== Mask ==========================
+ const [mergedMask, mergedMaskMotion, mergedPopupMotion] = React.useMemo<
+ [
+ mask: boolean,
+ maskMotion: CSSMotionProps | undefined,
+ popupMotion: CSSMotionProps | undefined,
+ ]
+ >(() => {
+ if (mobile) {
+ return [mobile.mask, mobile.maskMotion, mobile.motion];
+ }
+
+ return [mask, maskMotion, motion];
+ }, [mobile]);
+
// ======================= Container ========================
const getPopupContainerNeedParams = getPopupContainer?.length > 0;
@@ -148,15 +180,17 @@ const Popup = React.forwardRef((props, ref) => {
// >>>>> Offset
const AUTO = 'auto' as const;
- const offsetStyle: React.CSSProperties = {
- left: '-1000vw',
- top: '-1000vh',
- right: AUTO,
- bottom: AUTO,
- };
+ const offsetStyle: React.CSSProperties = isMobile
+ ? {}
+ : {
+ left: '-1000vw',
+ top: '-1000vh',
+ right: AUTO,
+ bottom: AUTO,
+ };
// Set align style
- if (ready || !open) {
+ if (!isMobile && (ready || !open)) {
const { points } = align;
const dynamicInset =
align.dynamicInset || (align as any)._experimental?.dynamicInset;
@@ -209,8 +243,9 @@ const Popup = React.forwardRef((props, ref) => {
prefixCls={prefixCls}
open={open}
zIndex={zIndex}
- mask={mask}
- motion={maskMotion}
+ mask={mergedMask}
+ motion={mergedMaskMotion}
+ mobile={isMobile}
/>
{(resizeObserverRef) => {
@@ -222,7 +257,7 @@ const Popup = React.forwardRef((props, ref) => {
removeOnLeave={false}
forceRender={forceRender}
leavedClassName={`${prefixCls}-hidden`}
- {...motion}
+ {...mergedPopupMotion}
onAppearPrepare={onPrepare}
onEnterPrepare={onPrepare}
visible={open}
@@ -235,7 +270,9 @@ const Popup = React.forwardRef((props, ref) => {
{ className: motionClassName, style: motionStyle },
motionRef,
) => {
- const cls = classNames(prefixCls, motionClassName, className);
+ const cls = classNames(prefixCls, motionClassName, className, {
+ [`${prefixCls}-mobile`]: isMobile,
+ });
return (
(val?: T | T[]) {
return val ? (Array.isArray(val) ? val : [val]) : [];
}
export default function useAction(
- mobile: boolean,
action: ActionTypes,
showAction?: ActionTypes,
hideAction?: ActionTypes,
-): [showAction: Set
, hideAction: Set] {
+): [showAction: Set, hideAction: Set] {
return React.useMemo(() => {
const mergedShowAction = toArray(showAction ?? action);
const mergedHideAction = toArray(hideAction ?? action);
@@ -20,18 +21,14 @@ export default function useAction(
const showActionSet = new Set(mergedShowAction);
const hideActionSet = new Set(mergedHideAction);
- if (mobile) {
- if (showActionSet.has('hover')) {
- showActionSet.delete('hover');
- showActionSet.add('click');
- }
+ if (showActionSet.has('hover') && !showActionSet.has('click')) {
+ showActionSet.add('touch');
+ }
- if (hideActionSet.has('hover')) {
- hideActionSet.delete('hover');
- hideActionSet.add('click');
- }
+ if (hideActionSet.has('hover') && !hideActionSet.has('click')) {
+ hideActionSet.add('touch');
}
return [showActionSet, hideActionSet];
- }, [mobile, action, showAction, hideAction]);
+ }, [action, showAction, hideAction]);
}
diff --git a/src/hooks/useAlign.ts b/src/hooks/useAlign.ts
index f352a33d..4d277b3c 100644
--- a/src/hooks/useAlign.ts
+++ b/src/hooks/useAlign.ts
@@ -95,6 +95,7 @@ export default function useAlign(
builtinPlacements: any,
popupAlign?: AlignType,
onPopupAlign?: TriggerProps['onPopupAlign'],
+ mobile?: boolean,
): [
ready: boolean,
offsetX: number,
@@ -109,15 +110,25 @@ export default function useAlign(
onAlign: VoidFunction,
] {
const [offsetInfo, setOffsetInfo] = React.useState<{
+ /** Align finished */
ready: boolean;
+ /** Offset Left of current Left */
offsetX: number;
+ /** Offset Top of current Top */
offsetY: number;
+ /** Offset Right of current Left */
offsetR: number;
+ /** Offset Bottom of current Top */
offsetB: number;
+ /** Arrow X offset related with popup */
arrowX: number;
+ /** Arrow Y offset related with popup */
arrowY: number;
+ /** Scale X of popup */
scaleX: number;
+ /** Scale Y of popup */
scaleY: number;
+ /** Calculated align info */
align: AlignType;
}>({
ready: false,
@@ -134,7 +145,7 @@ export default function useAlign(
const alignCountRef = React.useRef(0);
const scrollerList = React.useMemo(() => {
- if (!popupEle) {
+ if (!popupEle || mobile) {
return [];
}
@@ -161,7 +172,7 @@ export default function useAlign(
// ========================= Align =========================
const onAlign = useEvent(() => {
- if (popupEle && target && open) {
+ if (popupEle && target && open && !mobile) {
const popupElement = popupEle;
const doc = popupElement.ownerDocument;
@@ -659,10 +670,14 @@ export default function useAlign(
const targetTop = targetRect.y;
const targetBottom = targetTop + targetHeight;
+ /** Max left of the popup and target element */
const maxLeft = Math.max(popupLeft, targetLeft);
+ /** Min right of the popup and target element */
const minRight = Math.min(popupRight, targetRight);
+ /** The center X of popup & target cross area */
const xCenter = (maxLeft + minRight) / 2;
+ /** Arrow X of popup offset */
const nextArrowX = xCenter - popupLeft;
const maxTop = Math.max(popupTop, targetTop);
diff --git a/src/hooks/useWinClick.ts b/src/hooks/useWinClick.ts
index e14bb482..ce2afe12 100644
--- a/src/hooks/useWinClick.ts
+++ b/src/hooks/useWinClick.ts
@@ -3,6 +3,10 @@ import { warning } from '@rc-component/util/lib/warning';
import * as React from 'react';
import { getWin } from '../util';
+/**
+ * Close if click on the window.
+ * Return the function that click on the Popup element.
+ */
export default function useWinClick(
open: boolean,
clickToHide: boolean,
diff --git a/src/index.tsx b/src/index.tsx
index 2b5a696e..a2e35c4b 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -7,9 +7,8 @@ import { getShadowRoot } from '@rc-component/util/lib/Dom/shadow';
import useEvent from '@rc-component/util/lib/hooks/useEvent';
import useId from '@rc-component/util/lib/hooks/useId';
import useLayoutEffect from '@rc-component/util/lib/hooks/useLayoutEffect';
-import isMobile from '@rc-component/util/lib/isMobile';
import * as React from 'react';
-import Popup from './Popup';
+import Popup, { type MobileConfig } from './Popup';
import TriggerWrapper from './TriggerWrapper';
import type { TriggerContextProps } from './context';
import TriggerContext from './context';
@@ -121,9 +120,13 @@ export interface TriggerProps {
getTriggerDOMNode?: (node: React.ReactInstance) => HTMLElement;
// // ========================== Mobile ==========================
- // /** @private Bump fixed position at bottom in mobile.
- // * This is internal usage currently, do not use in your prod */
- // mobile?: MobileConfig;
+ /**
+ * @private Bump fixed position at bottom in mobile.
+ * Will replace the config of root props.
+ * This will directly trade as mobile view which will not check what real is.
+ * This is internal usage currently, do not use in your prod.
+ */
+ mobile?: MobileConfig;
}
export function generateTrigger(
@@ -190,6 +193,7 @@ export function generateTrigger(
// Private
getTriggerDOMNode,
+ mobile,
...restProps
} = props;
@@ -197,10 +201,7 @@ export function generateTrigger(
const mergedAutoDestroy = autoDestroy || false;
// =========================== Mobile ===========================
- const [mobile, setMobile] = React.useState(false);
- useLayoutEffect(() => {
- setMobile(isMobile());
- }, []);
+ const isMobile = !!mobile;
// ========================== Context ===========================
const subPopupElements = React.useRef>({});
@@ -250,7 +251,19 @@ export function generateTrigger(
// ========================== Children ==========================
const child = React.Children.only(children) as React.ReactElement;
const originChildProps = child?.props || {};
- const cloneProps: typeof originChildProps = {};
+ const cloneProps: Pick<
+ React.HTMLAttributes,
+ | 'onClick'
+ | 'onTouchStart'
+ | 'onMouseEnter'
+ | 'onMouseLeave'
+ | 'onMouseMove'
+ | 'onPointerEnter'
+ | 'onPointerLeave'
+ | 'onFocus'
+ | 'onBlur'
+ | 'onContextMenu'
+ > = {};
const inPopupOrChild = useEvent((ele: EventTarget) => {
const childDOM = targetEle;
@@ -377,10 +390,10 @@ export function generateTrigger(
builtinPlacements,
popupAlign,
onPopupAlign,
+ isMobile,
);
const [showActions, hideActions] = useAction(
- mobile,
action,
showAction,
hideAction,
@@ -482,22 +495,52 @@ export function generateTrigger(
// =========================== Action ===========================
/**
* Util wrapper for trigger action
+ * @param eventName Listen event name
+ * @param nextOpen Next open state after trigger
+ * @param delay Delay to trigger open change
+ * @param callback Callback if current event need additional action
+ * @param ignoreCheck Ignore current event if check return true
*/
function wrapperAction(
eventName: string,
nextOpen: boolean,
delay?: number,
- preEvent?: (event: Event) => void,
+ callback?: (event: Event) => void,
+ ignoreCheck?: () => boolean,
) {
cloneProps[eventName] = (event: any, ...args: any[]) => {
- preEvent?.(event);
- triggerOpen(nextOpen, delay);
+ if (!ignoreCheck || !ignoreCheck()) {
+ callback?.(event);
+ triggerOpen(nextOpen, delay);
+ }
// Pass to origin
originChildProps[eventName]?.(event, ...args);
};
}
+ // ======================= Action: Touch ========================
+ const touchToShow = showActions.has('touch');
+ const touchToHide = hideActions.has('touch');
+
+ /** Used for prevent `hover` event conflict with mobile env */
+ const touchedRef = React.useRef(false);
+
+ if (touchToShow || touchToHide) {
+ cloneProps.onTouchStart = (...args: any[]) => {
+ touchedRef.current = true;
+
+ if (openRef.current && touchToHide) {
+ triggerOpen(false);
+ } else if (!openRef.current && touchToShow) {
+ triggerOpen(true);
+ }
+
+ // Pass to origin
+ originChildProps.onTouchStart?.(...args);
+ };
+ }
+
// ======================= Action: Click ========================
if (clickToShow || clickToHide) {
cloneProps.onClick = (
@@ -513,13 +556,14 @@ export function generateTrigger(
// Pass to origin
originChildProps.onClick?.(event, ...args);
+ touchedRef.current = false;
};
}
// Click to hide is special action since click popup element should not hide
const onPopupPointerDown = useWinClick(
mergedOpen,
- clickToHide,
+ clickToHide || touchToHide,
targetEle,
popupEle,
mask,
@@ -535,24 +579,31 @@ export function generateTrigger(
let onPopupMouseEnter: React.MouseEventHandler;
let onPopupMouseLeave: VoidFunction;
+ const ignoreMouseTrigger = () => {
+ return touchedRef.current;
+ };
+
if (hoverToShow) {
+ const onMouseEnterCallback = (event: React.MouseEvent) => {
+ setMousePosByEvent(event);
+ };
+
// Compatible with old browser which not support pointer event
wrapperAction(
'onMouseEnter',
true,
mouseEnterDelay,
- (event) => {
- setMousePosByEvent(event);
- },
+ onMouseEnterCallback,
+ ignoreMouseTrigger,
);
wrapperAction(
'onPointerEnter',
true,
mouseEnterDelay,
- (event) => {
- setMousePosByEvent(event);
- },
+ onMouseEnterCallback,
+ ignoreMouseTrigger,
);
+
onPopupMouseEnter = (event) => {
// Only trigger re-open when popup is visible
if (
@@ -566,15 +617,27 @@ export function generateTrigger(
// Align Point
if (alignPoint) {
cloneProps.onMouseMove = (event: React.MouseEvent) => {
- // setMousePosByEvent(event);
originChildProps.onMouseMove?.(event);
};
}
}
if (hoverToHide) {
- wrapperAction('onMouseLeave', false, mouseLeaveDelay);
- wrapperAction('onPointerLeave', false, mouseLeaveDelay);
+ wrapperAction(
+ 'onMouseLeave',
+ false,
+ mouseLeaveDelay,
+ undefined,
+ ignoreMouseTrigger,
+ );
+ wrapperAction(
+ 'onPointerLeave',
+ false,
+ mouseLeaveDelay,
+ undefined,
+ ignoreMouseTrigger,
+ );
+
onPopupMouseLeave = () => {
triggerOpen(false, mouseLeaveDelay);
};
@@ -670,7 +733,10 @@ export function generateTrigger(
ref={setPopupRef}
prefixCls={prefixCls}
popup={popup}
- className={classNames(popupClassName, alignedClassName)}
+ className={classNames(
+ popupClassName,
+ !isMobile && alignedClassName,
+ )}
style={popupStyle}
target={targetEle}
onMouseEnter={onPopupMouseEnter}
@@ -711,6 +777,8 @@ export function generateTrigger(
stretch={stretch}
targetWidth={targetWidth / scaleX}
targetHeight={targetHeight / scaleY}
+ // Mobile
+ mobile={mobile}
/>
>
diff --git a/src/interface.ts b/src/interface.ts
index 93fe2832..0ff8cfd4 100644
--- a/src/interface.ts
+++ b/src/interface.ts
@@ -1,5 +1,3 @@
-import type { CSSMotionProps } from '@rc-component/motion';
-
export type Placement =
| 'top'
| 'left'
@@ -118,11 +116,3 @@ export interface Point {
export interface CommonEventHandler {
remove: () => void;
}
-
-export interface MobileConfig {
- /** Set popup motion. You can ref `rc-motion` for more info. */
- popupMotion?: CSSMotionProps;
- popupClassName?: string;
- popupStyle?: React.CSSProperties;
- popupRender?: (originNode: React.ReactNode) => React.ReactNode;
-}
diff --git a/tests/__snapshots__/mobile.test.tsx.snap b/tests/__snapshots__/mobile.test.tsx.snap
deleted file mode 100644
index 32c08942..00000000
--- a/tests/__snapshots__/mobile.test.tsx.snap
+++ /dev/null
@@ -1,14 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Trigger.Mobile popupRender 1`] = `
-
-`;
diff --git a/tests/mobile.test.tsx b/tests/mobile.test.tsx
index a3269c2b..5fecdafc 100644
--- a/tests/mobile.test.tsx
+++ b/tests/mobile.test.tsx
@@ -1,7 +1,7 @@
import { act, fireEvent, render } from '@testing-library/react';
import isMobile from '@rc-component/util/lib/isMobile';
import React from 'react';
-import Trigger from '../src';
+import Trigger, { type TriggerProps } from '../src';
import { placementAlignMap } from './util';
jest.mock('@rc-component/util/lib/isMobile');
@@ -36,24 +36,26 @@ describe('Trigger.Mobile', () => {
,
);
- flush();
- expect(document.querySelector('.rc-trigger-popup')).toBeFalsy();
+ const target = document.querySelector('.target');
- // Hover not work
- fireEvent.mouseEnter(document.querySelector('.target'));
flush();
expect(document.querySelector('.rc-trigger-popup')).toBeFalsy();
- // Click work
- fireEvent.click(document.querySelector('.target'));
+ // Touch work
+ fireEvent.touchStart(target);
+ fireEvent.mouseEnter(target);
+ fireEvent.mouseLeave(target);
flush();
expect(document.querySelector('.rc-trigger-popup')).toBeTruthy();
+
+ // Touch again
+ fireEvent.touchStart(target);
+ flush();
+ expect(document.querySelector('.rc-trigger-popup-hidden')).toBeTruthy();
});
// ====================================================================================
- // ZombieJ: back when we plan to support mobile
-
- function getTrigger(props?: any) {
+ function getTrigger(props?: Partial) {
return (
{
);
}
- it.skip('mobile config', () => {
- const { container } = render(
- getTrigger({
- mobile: {
- popupClassName: 'mobile-popup',
- popupStyle: { background: 'red' },
- },
- }),
- );
-
- fireEvent.click(container.querySelector('.target'));
+ describe('mobile config', () => {
+ it('enabled', () => {
+ const { container } = render(
+ getTrigger({
+ mobile: {},
+ }),
+ );
- expect(document.querySelector('.rc-trigger-popup')).toHaveClass(
- 'mobile-popup',
- );
+ fireEvent.click(container.querySelector('.target'));
- expect(document.querySelector('.rc-trigger-popup')).toHaveStyle({
- background: 'red',
+ expect(document.querySelector('.rc-trigger-popup')).toHaveClass(
+ 'rc-trigger-popup-mobile',
+ );
});
- });
- it.skip('popupRender', () => {
- const { container } = render(
- getTrigger({
- mobile: {
- popupRender: (node) => (
- <>
- Light
- {node}
- >
- ),
- },
- }),
- );
-
- fireEvent.click(container.querySelector('.target'));
- expect(document.querySelector('.rc-trigger-popup')).toMatchSnapshot();
- });
-
- it.skip('click inside not close', () => {
- const triggerRef = React.createRef();
- const { container } = render(getTrigger({ ref: triggerRef }));
- fireEvent.click(container.querySelector('.target'));
- expect(triggerRef.current.state.popupVisible).toBeTruthy();
- fireEvent.click(document.querySelector('.x-content'));
- expect(triggerRef.current.state.popupVisible).toBeTruthy();
-
- // Document click
- act(() => {
- fireEvent.mouseDown(document);
+ it('replace motion', () => {
+ render(
+ getTrigger({
+ mobile: {
+ motion: {
+ motionName: 'bamboo',
+ },
+ mask: true,
+ maskMotion: {
+ motionName: 'little',
+ },
+ },
+ popupVisible: true,
+ }),
+ );
+
+ expect(document.querySelector('.rc-trigger-popup-mobile')).toBeTruthy();
+ expect(
+ document.querySelector('.rc-trigger-popup-mobile-mask'),
+ ).toBeTruthy();
+
+ expect(document.querySelector('.rc-trigger-popup')).toHaveClass('bamboo');
+ expect(document.querySelector('.rc-trigger-popup-mask')).toHaveClass(
+ 'little',
+ );
});
- expect(triggerRef.current.state.popupVisible).toBeFalsy();
- });
-
- it.skip('legacy array children', () => {
- const { container } = render(
- getTrigger({
- popup: [Light
, Bamboo
],
- }),
- );
- fireEvent.click(container.querySelector('.target'));
- expect(document.querySelectorAll('.rc-trigger-popup-content')).toHaveLength(
- 1,
- );
});
});