Skip to content

Commit

Permalink
feat: code refinement
Browse files Browse the repository at this point in the history
  • Loading branch information
leonwgc committed Apr 20, 2024
1 parent eac0dfe commit 4206fe2
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 40 deletions.
2 changes: 1 addition & 1 deletion dist/index.esm.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/index.85f90a.js → docs/index.5b9c63.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!doctype html><html lang="zh-cn"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,minimal-ui,viewport-fit=cover"/><meta name="format-detection" content="telephone=no, email=no"/><meta name="apple-mobile-web-app-capable" content="yes"/><meta name="apple-touch-fullscreen" content="yes"/><title></title><script defer="defer" src="runtime.a08797.js"></script><script defer="defer" src="vendor.25d206.js"></script><script defer="defer" src="index.85f90a.js"></script></head><body style="font-size:14px"><div id="root"></div></body></html>
<!doctype html><html lang="zh-cn"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,minimal-ui,viewport-fit=cover"/><meta name="format-detection" content="telephone=no, email=no"/><meta name="apple-mobile-web-app-capable" content="yes"/><meta name="apple-touch-fullscreen" content="yes"/><title></title><script defer="defer" src="runtime.a08797.js"></script><script defer="defer" src="vendor.25d206.js"></script><script defer="defer" src="index.5b9c63.js"></script></head><body style="font-size:14px"><div id="root"></div></body></html>
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "w-popover",
"version": "2.0.2",
"version": "2.0.3",
"description": "React Popover component",
"keywords": [
"Popover",
Expand Down
70 changes: 37 additions & 33 deletions src/Popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import ReactDOM from 'react-dom';
import IconClose from './IconClose';
import Mask from './Mask';
import { getMountContainer, getTransformPosition } from './helper';
import { applyStyleOrClsToElement } from './hooks/dom';
import useCSSTransition from './hooks/useCSSTransition';
import useEventListener from './hooks/useEventListener';
import useLatest from './hooks/useLatest';
Expand All @@ -14,6 +15,10 @@ import { getArrowStyle, getModalStyle } from './utils';
import { MARGIN } from './utils/getModalStyle';
import { getScrollParent } from './utils/getScrollParent';

const transformFrom = { opacity: 0, transform: `scale(0)` };
const transformTo = { opacity: 1, transform: `scale(1)` };
const transitionProperty = 'transform, opacity';

/**
* React Popover
* @param {PopoverProps} props
Expand Down Expand Up @@ -52,10 +57,6 @@ const Popover = (props: PopoverProps): React.ReactElement => {
const mountNode = getMountContainer(mountContainer);
const mountedRef = useRef(false);

useUpdateEffect(() => {
onVisibleChange?.(visible);
}, [visible]);

const calculateStyle = React.useCallback(
(anchorEl, scrollContainer, isFirstMount = false) => {
const el = popoverRef.current;
Expand All @@ -70,22 +71,21 @@ const Popover = (props: PopoverProps): React.ReactElement => {
);
const arrowStyle = getArrowStyle(el, placement, MARGIN);

el.style.transitionProperty = 'none';
el.style.top = modalStyle.top + 'px';
el.style.left = modalStyle.left + 'px';
el.style.position = modalStyle.position;
applyStyleOrClsToElement(el, {
transitionProperty: 'none',
top: modalStyle.top + 'px',
left: modalStyle.left + 'px',
position: modalStyle.position,
});

if (transition && isFirstMount) {
el.style.visibility = 'hidden';
el.style.opacity = '0';
el.style.transform = 'scale(0)';
applyStyleOrClsToElement(el, transformFrom);

// trigger the browser to synchronously calculate the style and layout
// aka trigger reflow / layout thrashing
// in case of treeshaking
// in case of treeshaking
el['__oh__'] = el.offsetHeight;
el.style.transitionProperty = 'transform, opacity';
el.style.visibility = 'visible';
applyStyleOrClsToElement(el, { transitionProperty });
}
setArrowStyle(arrowStyle);
},
Expand All @@ -106,10 +106,24 @@ const Popover = (props: PopoverProps): React.ReactElement => {
});
};

const closeOutsideHandler = useCallback(
(e) => {
const el = popoverRef.current;
const anchor = anchorRef.current;

if (el && !el.contains(e.target) && !anchor.contains(e.target)) {
onCloseRef.current?.();
}
},
[onCloseRef]
);

useEventListener(() => window, 'resize', visible ? handleResize : null);

useEventListener(() => window, 'scroll', visible ? handleResize : null);

useEventListener(() => document, 'click', closeOnClickOutside ? closeOutsideHandler : null);

useLayoutEffect(() => {
const anchorEl = anchorRef.current;
const scrollContainer = getScrollParent(anchorEl);
Expand All @@ -122,32 +136,22 @@ const Popover = (props: PopoverProps): React.ReactElement => {
}
}, [visible, calculateStyle]);

const closeOutsideHandler = useCallback(
(e) => {
const el = popoverRef.current;
const anchor = anchorRef.current;

if (el && !el.contains(e.target) && !anchor.contains(e.target)) {
onCloseRef.current?.();
}
},
[onCloseRef]
);

useEventListener(() => document, 'click', closeOnClickOutside ? closeOutsideHandler : null);

const trasformOrigin = useMemo(() => {
const transformOrigin = useMemo(() => {
return getTransformPosition(placement);
}, [placement]);

const active = useCSSTransition(
() => popoverRef.current,
visible,
{ opacity: 0, transform: `scale(0)` },
{ opacity: 1, transform: `scale(1)` },
transformFrom,
transformTo,
transitionDuration
);

useUpdateEffect(() => {
onVisibleChange?.(visible);
}, [visible]);

return (
<>
<Mask
Expand All @@ -171,10 +175,10 @@ const Popover = (props: PopoverProps): React.ReactElement => {
position: 'absolute',
background: '#fff',
zIndex: 1000,
transformOrigin: trasformOrigin,
transformOrigin,
transitionDuration: `${transitionDuration}ms`,
transitionProperty: 'none',
willChange: 'transform, opacity',
willChange: transitionProperty,
...style,
}}
>
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export const getEventTarget = (target, defaultTarget): Element => {
export const applyStyleOrClsToElement = (
el: HTMLElement,
styleOrCls: React.CSSProperties | string,
toBeRemovedCls: React.CSSProperties | string
toBeRemovedCls?: React.CSSProperties | string
): void => {
if (typeof styleOrCls === 'object' && styleOrCls) {
for (const key of Object.keys(styleOrCls)) {
Expand Down
2 changes: 1 addition & 1 deletion types/hooks/dom.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ export declare const getEventTarget: (target: any, defaultTarget: any) => Elemen
* @param styleOrCls
* @param toBeRemovedCls
*/
export declare const applyStyleOrClsToElement: (el: HTMLElement, styleOrCls: React.CSSProperties | string, toBeRemovedCls: React.CSSProperties | string) => void;
export declare const applyStyleOrClsToElement: (el: HTMLElement, styleOrCls: React.CSSProperties | string, toBeRemovedCls?: React.CSSProperties | string) => void;

0 comments on commit 4206fe2

Please sign in to comment.