1
0
Эх сурвалжийг харах

feat: tooltip use native anchor

DaiQiangReal 7 сар өмнө
parent
commit
cd80ea5060

+ 26 - 2
packages/semi-foundation/tooltip/foundation.ts

@@ -4,6 +4,7 @@ import BaseFoundation, { DefaultAdapter } from '../base/foundation';
 import { ArrayElement } from '../utils/type';
 import { strings } from './constants';
 import { handlePrevent } from '../utils/a11y';
+import { getUuidShort } from "../utils/uuid";
 
 const REGS = {
     TOP: /top/i,
@@ -81,7 +82,7 @@ export interface PopupContainerDOMRect extends DOMRectLikeType {
 export default class Tooltip<P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<TooltipAdapter<P, S>, P, S> {
     _timer: ReturnType<typeof setTimeout>;
     _mounted: boolean;
-
+    anchorName = `--native-semi-anchor-${getUuidShort()}`
     constructor(adapter: TooltipAdapter<P, S>) {
         super({ ...adapter });
         this._timer = null;
@@ -135,7 +136,7 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
     unBindResizeEvent() {
         this._adapter.unregisterResizeHandler(this.onResize);
     }
-  
+
     removePortal = () => {
         this._adapter.removePortal();
     }
@@ -199,6 +200,29 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
         }
     }
 
+    getNativeAnchorStyle = () => {
+        const style = {
+            positionAnchor: this.anchorName,
+            position: "fixed",
+        };
+        const position = this._adapter.getProp("position");
+        const spacing = this._adapter.getProp("spacing");
+        if (position === "top") {
+            style['bottom'] = `anchor(top)`;
+            style['justifySelf'] = "anchor-center";
+            style["transform"] = `translateY(-${spacing}px)`;
+           
+        } else if (position === "bottom") {
+            style['top'] = `anchor(bottom)`;
+            style['justifySelf'] = "anchor-center";
+            style["transform"] = `translateY(${spacing}px)`;
+
+        } else {
+            throw new Error(`Currently, not support position ${position} when enable native anchor ability, only 'top' 'bottom'.`);
+        }
+        return style;
+    }
+
     _generateEvent(types: ArrayElement<typeof strings.TRIGGER_SET>) {
         const eventNames = this._adapter.getEventName();
         const triggerEventSet = {

+ 5 - 1
packages/semi-ui/select/index.tsx

@@ -180,7 +180,8 @@ export type SelectProps = {
     children?: React.ReactNode;
     preventScroll?: boolean;
     showRestTagsPopover?: boolean;
-    restTagsPopoverProps?: PopoverProps
+    restTagsPopoverProps?: PopoverProps;
+    popoverProps?: PopoverProps
 } & Pick<
 TooltipProps,
 | 'spacing'
@@ -311,6 +312,7 @@ class Select extends BaseComponent<SelectProps, SelectState> {
         onListScroll: PropTypes.func,
         arrowIcon: PropTypes.node,
         preventScroll: PropTypes.bool,
+        popoverProps: PropTypes.object,
         // open: PropTypes.bool,
         // tagClosable: PropTypes.bool,
     };
@@ -1506,6 +1508,7 @@ class Select extends BaseComponent<SelectProps, SelectState> {
             spacing,
             stopPropagation,
             dropdownMargin,
+            popoverProps
         } = this.props;
         const { isOpen, optionKey } = this.state;
         const selection = this.renderSelection();
@@ -1529,6 +1532,7 @@ class Select extends BaseComponent<SelectProps, SelectState> {
                 disableArrowKeyDown={true}
                 onVisibleChange={status => this.handlePopoverVisibleChange(status)}
                 afterClose={() => this.foundation.handlePopoverClose()}
+                {...popoverProps}
             >
                 {selection}
             </Popover>

+ 10 - 0
packages/semi-ui/tooltip/_story/tooltip.stories.jsx

@@ -1712,3 +1712,13 @@ export const ViewportPrioritJudgment = () => {
     </div>
   )
 }
+
+export const NativeAnchor = ()=>{
+    return <div>
+        <Tooltip content={"hi bytedance"} visible={true} trigger={"custom"} position='bottom' enableNativeAnchor={true}>
+            <Button theme="solid" type="tertiary" style={{ marginBottom: 20, marginTop: 200,marginLeft:"500px" }}>
+                悬停显示
+            </Button>
+        </Tooltip>
+    </div>
+}

+ 10 - 6
packages/semi-ui/tooltip/index.tsx

@@ -15,7 +15,6 @@ import TooltipFoundation, {
     PopupContainerDOMRect
 } from '@douyinfe/semi-foundation/tooltip/foundation';
 import { strings, cssClasses, numbers } from '@douyinfe/semi-foundation/tooltip/constants';
-import { getUuidShort } from '@douyinfe/semi-foundation/utils/uuid';
 import '@douyinfe/semi-foundation/tooltip/tooltip.scss';
 
 import BaseComponent, { BaseProps } from '../_base/baseComponent';
@@ -33,6 +32,7 @@ import TriangleArrow from './TriangleArrow';
 import TriangleArrowVertical from './TriangleArrowVertical';
 import ArrowBoundingShape from './ArrowBoundingShape';
 import CSSAnimation from "../_cssAnimation";
+import { getUuidShort } from "@douyinfe/semi-foundation/utils/uuid";
 
 export type Trigger = ArrayElement<typeof strings.TRIGGER_SET>;
 export type { Position };
@@ -89,7 +89,8 @@ export interface TooltipProps extends BaseProps {
     preventScroll?: boolean;
     disableFocusListener?: boolean;
     afterClose?: () => void;
-    keepDOM?: boolean
+    keepDOM?: boolean;
+    enableNativeAnchor: boolean
 }
 
 interface TooltipState {
@@ -118,7 +119,6 @@ const blockDisplays = ['flex', 'block', 'table', 'flow-root', 'grid'];
 const defaultGetContainer = () => document.body;
 export default class Tooltip extends BaseComponent<TooltipProps, TooltipState> {
     static contextType = ConfigContext;
-
     static propTypes = {
         children: PropTypes.node,
         motion: PropTypes.bool,
@@ -155,6 +155,8 @@ export default class Tooltip extends BaseComponent<TooltipProps, TooltipState> {
         returnFocusOnClose: PropTypes.bool,
         preventScroll: PropTypes.bool,
         keepDOM: PropTypes.bool,
+        enableNativeAnchor: PropTypes.bool,
+
     };
     static __SemiComponentName__ = "Tooltip";
     static defaultProps = getDefaultPropsFromGlobalConfig(Tooltip.__SemiComponentName__, {
@@ -182,7 +184,8 @@ export default class Tooltip extends BaseComponent<TooltipProps, TooltipState> {
         onEscKeyDown: noop,
         disableFocusListener: false,
         disableArrowKeyDown: false,
-        keepDOM: false
+        keepDOM: false,
+        enableNativeAnchor: false
     });
 
     eventManager: Event;
@@ -649,7 +652,7 @@ export default class Tooltip extends BaseComponent<TooltipProps, TooltipState> {
             [`${prefixCls}-rtl`]: direction === 'rtl',
         });
         const icon = this.renderIcon();
-        const portalInnerStyle = omit(containerStyle, motion ? ['transformOrigin'] : undefined);
+        const portalInnerStyle = omit(this.props.enableNativeAnchor ? this.foundation.getNativeAnchorStyle() : containerStyle, motion ? ['transformOrigin'] : undefined) as CSSProperties;
         const transformOrigin = get(containerStyle, 'transformOrigin');
         const userOpacity: CSSProperties['opacity'] | null = get(style, 'opacity', null);
         const opacity = userOpacity ? userOpacity : 1;
@@ -755,7 +758,7 @@ export default class Tooltip extends BaseComponent<TooltipProps, TooltipState> {
 
     render() {
         const { isInsert, triggerEventSet, visible, id } = this.state;
-        const { wrapWhenSpecial, role, trigger } = this.props;
+        const { wrapWhenSpecial, role, trigger, enableNativeAnchor } = this.props;
         let { children } = this.props;
         const childrenStyle = { ...get(children, 'props.style') as React.CSSProperties };
         const extraStyle: React.CSSProperties = {};
@@ -800,6 +803,7 @@ export default class Tooltip extends BaseComponent<TooltipProps, TooltipState> {
             ...this.mergeEvents((children as React.ReactElement).props, triggerEventSet),
             style: {
                 ...get(children, 'props.style') as React.CSSProperties,
+                anchorName: enableNativeAnchor ? this.foundation.anchorName : undefined,
                 ...extraStyle,
             },
             className: classNames(