Skip to content

Commit

Permalink
fix(Overlay): overlay support ssr, close #4205
Browse files Browse the repository at this point in the history
  • Loading branch information
FairyYang committed Aug 30, 2024
1 parent 0d51216 commit 8f6c856
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 27 deletions.
4 changes: 3 additions & 1 deletion components/overlay/gateway.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ class Gateway extends Component<GatewayProps, GatewayState> {
};

static defaultProps = {
container: () => document.body,
container: () => {
if (typeof document !== 'undefined') return document.body;
},
};

child: Element | null | undefined;
Expand Down
29 changes: 19 additions & 10 deletions components/overlay/overlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,8 @@ class Overlay extends Component<OverlayV1Props, OverlayState> {
switch ((align as Array<string>)[0]) {
case 't':
return {
// 为了防止有的用户 js升级了而css没升级,所以把两个动画都保留了。
// 动画不会叠加,会替代,顺序根据 src/animate/main.scss 中的样式先后顺序遵循css覆盖原则
// 为了防止有的用户 js 升级了而 css 没升级,所以把两个动画都保留了。
// 动画不会叠加,会替代,顺序根据 src/animate/main.scss 中的样式先后顺序遵循 css 覆盖原则
// fadeInDownSmall fadeOutUpSmall 优先级更高
in: 'expandInDown fadeInDownSmall',
out: 'expandOutUp fadeOutUpSmall',
Expand All @@ -331,6 +331,9 @@ class Overlay extends Component<OverlayV1Props, OverlayState> {
}

addAnimationEvents() {
if (typeof window === 'undefined') {
return;
}
setTimeout(() => {
const node = this.getContentNode();
if (node) {
Expand Down Expand Up @@ -399,8 +402,8 @@ class Overlay extends Component<OverlayV1Props, OverlayState> {
});

this.onLeaved();
// dom结构首次出现 触发的是entering
// dom结构已经存在(例如设置了cache),触发的是mounting
// dom 结构首次出现 触发的是 entering
// dom 结构已经存在(例如设置了 cache),触发的是 mounting
} else if (this.state.status === 'entering' || this.state.status === 'mounting') {
this.setState({
status: 'none',
Expand Down Expand Up @@ -562,10 +565,11 @@ class Overlay extends Component<OverlayV1Props, OverlayState> {
* document global event
*/
addDocumentEvents() {
// FIXME: canCloseByEsc、canCloseByOutSideClick、canCloseByMask仅在didMount时生效,update时不生效
// FIXME: canCloseByEsc、canCloseByOutSideClick、canCloseByMask 仅在 didMount 时生效,update 时不生效
const { useCapture } = this.props;
// use capture phase listener to be compatible with react17
// https://reactjs.org/blog/2020/08/10/react-v17-rc.html#fixing-potential-issues
if (typeof document === undefined) return;

Check failure on line 572 in components/overlay/overlay.tsx

View workflow job for this annotation

GitHub Actions / changed

Invalid typeof comparison value
if (this.props.canCloseByEsc) {
this._keydownEvents = events.on(
document,
Expand Down Expand Up @@ -622,7 +626,7 @@ class Overlay extends Component<OverlayV1Props, OverlayState> {
const path = [] as Array<HTMLElement | Document | Window>;
while (el) {
path.push(el);
if (el.tagName === 'HTML') {
if (el.tagName === 'HTML' && typeof document !== undefined) {

Check failure on line 629 in components/overlay/overlay.tsx

View workflow job for this annotation

GitHub Actions / changed

Invalid typeof comparison value
path.push(document);
path.push(window);
return path;
Expand Down Expand Up @@ -658,9 +662,14 @@ class Overlay extends Component<OverlayV1Props, OverlayState> {
node &&
(node === e.target ||
node.contains(e.target as HTMLElement) ||
this.matchInShadowDOM(node, e) ||
(e.target !== document &&
!document.documentElement.contains(e.target as HTMLElement)))
this.matchInShadowDOM(node, e))
) {
return;
}
if (typeof document === undefined) return;

Check failure on line 669 in components/overlay/overlay.tsx

View workflow job for this annotation

GitHub Actions / changed

Invalid typeof comparison value
if (
e.target !== document &&
!document.documentElement.contains(e.target as HTMLElement)
) {
return;
}
Expand Down Expand Up @@ -690,7 +699,7 @@ class Overlay extends Component<OverlayV1Props, OverlayState> {
this.gatewayRef = ref;
};

// 兼容过去的用法: this.popupRef.getInstance().overlay.getInstance().getContentNode()
// 兼容过去的用法this.popupRef.getInstance().overlay.getInstance().getContentNode()
getInstance() {
return this;
}
Expand Down
10 changes: 6 additions & 4 deletions components/overlay/popup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,11 @@ class Popup extends Component<PopupProps, PopupState> {
*/
delay: PropTypes.number,
/**
* 鼠标放置后的延时显示, 单位毫秒 ms
* 鼠标放置后的延时显示单位毫秒 ms
*/
mouseEnterDelay: PropTypes.number,
/**
* 鼠标离开后的延时显示, 单位毫秒 ms
* 鼠标离开后的延时显示单位毫秒 ms
*/
mouseLeaveDelay: PropTypes.number,
/**
Expand All @@ -76,7 +76,7 @@ class Popup extends Component<PopupProps, PopupState> {
target: PropTypes.any,
safeNode: PropTypes.any,
/**
* 是否跟随trigger滚动
* 是否跟随 trigger 滚动
*/
followTrigger: PropTypes.bool,
container: PropTypes.any,
Expand Down Expand Up @@ -111,7 +111,9 @@ class Popup extends Component<PopupProps, PopupState> {
delay: 200,
canCloseByTrigger: true,
followTrigger: false,
container: () => document.body,
container: () => {
if (typeof document !== 'undefined') return document.body;
},
rtl: false,
};
_mouseNotFirstOnMask: boolean;
Expand Down
8 changes: 6 additions & 2 deletions components/overlay/position.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ export default class Position extends Component<PositionProps> {
this.setPosition();

if (this.props.needListenResize) {
events.on(window, 'resize', this.handleResize);
if (typeof window !== 'undefined') {
events.on(window, 'resize', this.handleResize);
}
this.observe();
}
}
Expand All @@ -84,7 +86,9 @@ export default class Position extends Component<PositionProps> {

componentWillUnmount() {
if (this.props.needListenResize) {
events.off(window, 'resize', this.handleResize);
if (typeof window !== 'undefined') {
events.off(window, 'resize', this.handleResize);
}
this.unobserve();
}

Expand Down
4 changes: 2 additions & 2 deletions components/overlay/utils/find-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default function findNode<T>(target?: Target<T>, param?: T): Element | Te
return null;
}

if (typeof realTarget === 'string') {
if (typeof realTarget === 'string' && typeof document !== 'undefined') {
return document.getElementById(realTarget);
}

Expand All @@ -24,7 +24,7 @@ export default function findNode<T>(target?: Target<T>, param?: T): Element | Te
}

try {
// @ts-expect-error realTarget需要判断是否是ReactInstance,还会存在Element Node Text的情况
// @ts-expect-error realTarget 需要判断是否是 ReactInstance,还会存在 Element Node Text 的情况
return findDOMNode(realTarget);
} catch (err) {
// @ts-expect-error 这个兜底逻辑十分破坏类型完备
Expand Down
20 changes: 12 additions & 8 deletions components/overlay/utils/position.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ import type { PositionProps, PointsType } from '../types';
const VIEWPORT = 'viewport' as const;

// IE8 not support pageXOffset
const getPageX = () => window.pageXOffset || document.documentElement.scrollLeft;
const getPageY = () => window.pageYOffset || document.documentElement.scrollTop;
const getPageX = () => {
return window.pageXOffset || document.documentElement.scrollLeft;
};
const getPageY = () => {
return window.pageYOffset || document.documentElement.scrollTop;
};

/**
* @internal get element size
Expand Down Expand Up @@ -98,7 +102,7 @@ function _getViewportSize(container: HTMLElement | SVGElement) {
}

const getContainer = ({ container, baseElement }: PositionProps) => {
// SSR下会有副作用
// SSR 下会有副作用
if (typeof document === 'undefined') {
return container;
}
Expand Down Expand Up @@ -257,11 +261,11 @@ export default class Position {

if (this.autoFit && align && this.container && this.container !== document.body) {
const baseElementRect = _getElementRect(
// @ts-expect-error _getElementRect baseElement不支持"viewport" 需要对baseElement做非"viewport"处理
// @ts-expect-error _getElementRect baseElement 不支持"viewport" 需要对 baseElement 做非"viewport"处理
this.baseElement,
this.container
);
// @ts-expect-error _getElementRect pinElement不支持"viewport" 需要对pinElement做非"viewport"处理
// @ts-expect-error _getElementRect pinElement 不支持"viewport" 需要对 pinElement 做非"viewport"处理
const pinElementRect = _getElementRect(this.pinElement, this.container);
const viewportSize = _getViewportSize(this.container);
const pinAlign = align.split(' ')[0];
Expand Down Expand Up @@ -399,7 +403,7 @@ export default class Position {
docElement = document.documentElement;

result.offset = (ignoreScroll: boolean) => {
// 这里是关键,第二个参数的含义以ing该是:是否为 fixed 布局,并且像 dialog 一样,不跟随 trigger 元素
// 这里是关键,第二个参数的含义以 ing 该是:是否为 fixed 布局,并且像 dialog 一样,不跟随 trigger 元素
if (ignoreElementOffset) {
return {
left: 0,
Expand Down Expand Up @@ -446,9 +450,9 @@ export default class Position {

// According to the location of the overflow to calculate the desired positioning
_getExpectedAlign() {
// @ts-expect-error align这里需要确定是string,不能是boolean
// @ts-expect-error align 这里需要确定是 string,不能是 boolean
const align: string = this.isRtl
? // @ts-expect-error align这里需要确定是string,不能是boolean
? // @ts-expect-error align 这里需要确定是 string,不能是 boolean
this._replaceAlignDir(this.align, /l|r/g, { l: 'r', r: 'l' })
: this.align;
const expectedAlign = [align];
Expand Down

0 comments on commit 8f6c856

Please sign in to comment.