diff --git a/src/Placeholder.tsx b/src/Placeholder.tsx new file mode 100644 index 0000000..8ba1861 --- /dev/null +++ b/src/Placeholder.tsx @@ -0,0 +1,38 @@ +import Portal, { type PortalProps } from '@rc-component/portal'; +import * as React from 'react'; + +export interface PlaceholderProps + extends Pick { + domRef: React.RefObject; + className: string; + style: React.CSSProperties; + fallbackDOM: () => HTMLElement | null; +} + +const Placeholder = React.forwardRef( + (props, ref) => { + const { + open, + autoLock, + getContainer, + domRef, + className, + style, + fallbackDOM, + } = props; + + React.useImperativeHandle(ref, () => domRef.current || fallbackDOM()); + + return ( + +
+ + ); + }, +); + +if (process.env.NODE_ENV !== 'production') { + Placeholder.displayName = 'Placeholder'; +} + +export default Placeholder; diff --git a/src/Tour.tsx b/src/Tour.tsx index 9e167a0..fd96306 100644 --- a/src/Tour.tsx +++ b/src/Tour.tsx @@ -14,6 +14,7 @@ import Mask from './Mask'; import { getPlacements } from './placements'; import TourStep from './TourStep'; import { getPlacement } from './util'; +import Placeholder from './Placeholder'; const CENTER_PLACEHOLDER: React.CSSProperties = { left: '50%', @@ -201,8 +202,8 @@ const Tour: React.FC = props => { typeof mergedMask === 'boolean' ? undefined : mergedMask; // when targetElement is not exist, use body as triggerDOMNode - const getTriggerDOMNode = node => { - return node || targetElement || document.body; + const fallbackDOM = () => { + return targetElement || document.body; }; return ( @@ -237,29 +238,26 @@ const Tour: React.FC = props => { forceRender={false} autoDestroy zIndex={zIndex} - getTriggerDOMNode={getTriggerDOMNode} arrow={!!mergedArrow} > - -
- + domRef={placeholderRef} + fallbackDOM={fallbackDOM} + className={classNames( + className, + rootClassName, + `${prefixCls}-target-placeholder`, + )} + style={{ + ...(posInfo || CENTER_PLACEHOLDER), + position: inlineMode ? 'absolute' : 'fixed', + pointerEvents: 'none', + ...style, + }} + /> );