Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions packages/components/common/Portal.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import React, { forwardRef, useMemo, useImperativeHandle } from 'react';
import React, { forwardRef, useImperativeHandle, useMemo } from 'react';
import { createPortal } from 'react-dom';
import { AttachNode, AttachNodeReturnValue } from '../common';

import { canUseDocument } from '../_util/dom';
import useConfig from '../hooks/useConfig';
import useIsomorphicLayoutEffect from '../hooks/useLayoutEffect';

import type { AttachNode, AttachNodeReturnValue } from '../common';

export interface PortalProps {
/**
* 指定挂载的 HTML 节点, false 为挂载在 body
Expand All @@ -15,6 +17,7 @@ export interface PortalProps {
*/
triggerNode?: HTMLElement;
children: React.ReactNode;
style?: React.CSSProperties;
}

export function getAttach(attach: PortalProps['attach'], triggerNode?: HTMLElement): AttachNodeReturnValue {
Expand All @@ -38,14 +41,18 @@ export function getAttach(attach: PortalProps['attach'], triggerNode?: HTMLEleme
}

const Portal = forwardRef((props: PortalProps, ref) => {
const { attach, children, triggerNode } = props;
const { attach, children, triggerNode, style } = props;
const { classPrefix } = useConfig();

const container = useMemo(() => {
if (!canUseDocument) return null;
const el = document.createElement('div');
el.className = `${classPrefix}-portal-wrapper`;
if (typeof style === 'object') {
Object.assign(el.style, style);
}
return el;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [classPrefix]);

useIsomorphicLayoutEffect(() => {
Expand Down
14 changes: 9 additions & 5 deletions packages/components/date-picker/base/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React, { useState, useMemo, useEffect, useCallback, useRef } from 'react';
import { useLocaleReceiver } from '../../locale/LocalReceiver';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import useConfig from '../../hooks/useConfig';
import { useLocaleReceiver } from '../../locale/LocalReceiver';
import { PaginationMini, type TdPaginationMiniProps } from '../../pagination';
import Select from '../../select';
import { TdDatePickerProps } from '../type';
import { PaginationMini, TdPaginationMiniProps } from '../../pagination';
import type { TdDatePickerProps } from '../type';

export interface DatePickerHeaderProps extends Pick<TdDatePickerProps, 'mode'> {
year?: number;
Expand Down Expand Up @@ -210,7 +210,11 @@ const DatePickerHeader = (props: DatePickerHeaderProps) => {
}}
popupProps={{
onScroll: handleScroll,
updateScrollTop: handleUpdateScrollTop,
updateScrollTop: (el) => {
setTimeout(() => {
handleUpdateScrollTop(el);
}, 0);
},
attach: (triggerElement: HTMLElement) => triggerElement.parentNode as HTMLElement,
overlayClassName: `${headerClassName}-controller-year-popup`,
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ exports[`Guide Component > GuideStep.body works fine 1`] = `
/>
<div
class="t-portal-wrapper appear appear-active"
style="position: absolute; width: 100%;"
>
<div
class="t-popup t-guide__popup t-popup--animation-enter-active t-popup--animation-enter-to"
Expand Down Expand Up @@ -290,6 +291,7 @@ exports[`Guide Component > GuideStep.children works fine 1`] = `
/>
<div
class="t-portal-wrapper appear appear-active"
style="position: absolute; width: 100%;"
>
<div
class="t-popup t-guide__popup t-popup--animation-enter-active t-popup--animation-enter-to"
Expand Down Expand Up @@ -427,6 +429,7 @@ exports[`Guide Component > GuideStep.content works fine 1`] = `
/>
<div
class="t-portal-wrapper appear appear-active"
style="position: absolute; width: 100%;"
>
<div
class="t-popup t-guide__popup t-popup--animation-enter-active t-popup--animation-enter-to"
Expand Down Expand Up @@ -571,6 +574,7 @@ exports[`Guide Component > GuideStep.highlightContent works fine 1`] = `
/>
<div
class="t-portal-wrapper appear appear-active"
style="position: absolute; width: 100%;"
>
<div
class="t-popup t-guide__popup t-popup--animation-enter-active t-popup--animation-enter-to"
Expand Down Expand Up @@ -940,6 +944,7 @@ exports[`Guide Component > GuideStep.placement is equal to bottom-left 1`] = `
/>
<div
class="t-portal-wrapper appear appear-active"
style="position: absolute; width: 100%;"
>
<div
class="t-popup t-guide__popup t-popup--animation-enter-active t-popup--animation-enter-to"
Expand Down Expand Up @@ -1113,6 +1118,7 @@ exports[`Guide Component > GuideStep.stepOverlayClass is equal to t-test-guide-s
/>
<div
class="t-portal-wrapper appear appear-active"
style="position: absolute; width: 100%;"
>
<div
class="t-popup t-guide__popup t-test-guide-step-overlay t-popup--animation-enter-active t-popup--animation-enter-to"
Expand Down Expand Up @@ -1286,6 +1292,7 @@ exports[`Guide Component > GuideStep.title works fine 1`] = `
/>
<div
class="t-portal-wrapper appear appear-active"
style="position: absolute; width: 100%;"
>
<div
class="t-popup t-guide__popup t-popup--animation-enter-active t-popup--animation-enter-to"
Expand Down
19 changes: 14 additions & 5 deletions packages/components/popup/Popup.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React, { forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
import { CSSTransition } from 'react-transition-group';

import { Placement, type Options } from '@popperjs/core';
import classNames from 'classnames';
import { debounce, isFunction } from 'lodash-es';
import React, { forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
import { CSSTransition } from 'react-transition-group';

import { getRefDom } from '../_util/ref';
import { getCssVarsValue } from '../_util/style';
import Portal from '../common/Portal';
Expand All @@ -16,9 +18,10 @@ import usePopper from '../hooks/usePopper';
import useWindowSize from '../hooks/useWindowSize';
import { popupDefaultProps } from './defaultProps';
import useTrigger from './hooks/useTrigger';
import type { TdPopupProps } from './type';
import { getTransitionParams } from './utils/transition';

import type { TdPopupProps } from './type';

export interface PopupProps extends TdPopupProps {
// 是否触发展开收起动画,内部下拉式组件使用
expandAnimation?: boolean;
Expand Down Expand Up @@ -115,11 +118,12 @@ const Popup = forwardRef<PopupRef, PopupProps>((originalProps, ref) => {
placement: popperPlacement,
...popperOptions,
});

/**
* 是否启用 popper.js 的 arrow 修饰符
* - 会自动根据属性 data-popper-arrow 来识别箭头元素
* - 从而支持使用 padding 调整箭头位置
* @ see https://popper.js.org/docs/v2/modifiers/arrow/
* @docs https://popper.js.org/docs/v2/modifiers/arrow/
*/
const hasArrowModifier = popperOptions?.modifiers?.some((modifier) => modifier.name === 'arrow');
const { styles, attributes } = popperRef.current;
Expand Down Expand Up @@ -191,7 +195,12 @@ const Popup = forwardRef<PopupRef, PopupProps>((originalProps, ref) => {
onEnter={handleEnter}
onExited={handleExited}
>
<Portal triggerNode={getRefDom(triggerRef)} attach={popupAttach} ref={portalRef}>
<Portal
ref={portalRef}
triggerNode={getRefDom(triggerRef)}
attach={popupAttach}
style={{ position: 'absolute', width: '100%' }}
>
<CSSTransition
appear
timeout={0}
Expand Down
2 changes: 1 addition & 1 deletion packages/components/popup/_example/container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Button, Popup, Space } from 'tdesign-react';

export default function Attach() {
return (
<Space className='attach-container' style={{ position: 'relative' }}>
<Space className='attach-container'>
<Popup trigger="click" content="触发元素的父元素是组件根元素,通过 CSS Selector 定义" attach=".attach-container">
<Button>点击查看我的父元素(CSS Selector)</Button>
</Popup>
Expand Down
4 changes: 2 additions & 2 deletions test/snap/__snapshots__/csr.test.jsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -78172,7 +78172,7 @@ exports[`csr snapshot test > csr test packages/components/popup/_example/contain
<div>
<div
class="t-space attach-container t-space-horizontal"
style="position: relative; gap: 16px;"
style="gap: 16px;"
>
<div
class="t-space-item"
Expand Down Expand Up @@ -150064,7 +150064,7 @@ exports[`ssr snapshot test > ssr test packages/components/popconfirm/_example/th

exports[`ssr snapshot test > ssr test packages/components/popup/_example/base.tsx 1`] = `"<button type="button" class="t-button t-button--theme-primary t-button--variant-base"><span class="t-button__text">Hover me</span></button>"`;

exports[`ssr snapshot test > ssr test packages/components/popup/_example/container.tsx 1`] = `"<div style="position:relative;gap:16px" class="t-space attach-container t-space-horizontal"><div class="t-space-item"><button type="button" class="t-button t-button--theme-primary t-button--variant-base"><span class="t-button__text">点击查看我的父元素(CSS Selector)</span></button></div><div class="t-space-item"><button type="button" class="t-button t-button--theme-primary t-button--variant-base"><span class="t-button__text">点击查看我的父元素(Function)</span></button></div></div>"`;
exports[`ssr snapshot test > ssr test packages/components/popup/_example/container.tsx 1`] = `"<div style="gap:16px" class="t-space attach-container t-space-horizontal"><div class="t-space-item"><button type="button" class="t-button t-button--theme-primary t-button--variant-base"><span class="t-button__text">点击查看我的父元素(CSS Selector)</span></button></div><div class="t-space-item"><button type="button" class="t-button t-button--theme-primary t-button--variant-base"><span class="t-button__text">点击查看我的父元素(Function)</span></button></div></div>"`;

exports[`ssr snapshot test > ssr test packages/components/popup/_example/destroy.tsx 1`] = `"<button type="button" class="t-button t-button--theme-primary t-button--variant-base"><span class="t-button__text">Hover me</span></button>"`;

Expand Down
2 changes: 1 addition & 1 deletion test/snap/__snapshots__/ssr.test.jsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ exports[`ssr snapshot test > ssr test packages/components/popconfirm/_example/th

exports[`ssr snapshot test > ssr test packages/components/popup/_example/base.tsx 1`] = `"<button type="button" class="t-button t-button--theme-primary t-button--variant-base"><span class="t-button__text">Hover me</span></button>"`;

exports[`ssr snapshot test > ssr test packages/components/popup/_example/container.tsx 1`] = `"<div style="position:relative;gap:16px" class="t-space attach-container t-space-horizontal"><div class="t-space-item"><button type="button" class="t-button t-button--theme-primary t-button--variant-base"><span class="t-button__text">点击查看我的父元素(CSS Selector)</span></button></div><div class="t-space-item"><button type="button" class="t-button t-button--theme-primary t-button--variant-base"><span class="t-button__text">点击查看我的父元素(Function)</span></button></div></div>"`;
exports[`ssr snapshot test > ssr test packages/components/popup/_example/container.tsx 1`] = `"<div style="gap:16px" class="t-space attach-container t-space-horizontal"><div class="t-space-item"><button type="button" class="t-button t-button--theme-primary t-button--variant-base"><span class="t-button__text">点击查看我的父元素(CSS Selector)</span></button></div><div class="t-space-item"><button type="button" class="t-button t-button--theme-primary t-button--variant-base"><span class="t-button__text">点击查看我的父元素(Function)</span></button></div></div>"`;

exports[`ssr snapshot test > ssr test packages/components/popup/_example/destroy.tsx 1`] = `"<button type="button" class="t-button t-button--theme-primary t-button--variant-base"><span class="t-button__text">Hover me</span></button>"`;

Expand Down
Loading