Skip to content

Commit e6626cf

Browse files
committed
feat: add portal
1 parent 30138b3 commit e6626cf

File tree

3 files changed

+41
-0
lines changed

3 files changed

+41
-0
lines changed

src/components/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@ export type { CacheComponentDOMProps } from './cache-component-dom';
66

77
export { default as LoadScript } from './load-script';
88
export { LoadScriptProps } from './load-script';
9+
10+
export { default as Portal } from './portal';

src/components/portal/index.tsx

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import React from 'react';
2+
import ReactDOM from 'react-dom';
3+
4+
export type PortalRef = {};
5+
6+
export interface PortalProps {
7+
didUpdate?: (prevProps: PortalProps) => void;
8+
getContainer: () => Element;
9+
children?: React.ReactNode;
10+
}
11+
12+
const Portal = React.forwardRef<PortalRef, PortalProps>((props, ref) => {
13+
const { didUpdate, getContainer, children } = props;
14+
15+
const containerRef = React.useRef<Element>();
16+
17+
React.useImperativeHandle(ref, () => ({}));
18+
19+
const initRef = React.useRef(false);
20+
if (!initRef.current) {
21+
containerRef.current = getContainer();
22+
initRef.current = true;
23+
}
24+
25+
React.useEffect(() => {
26+
didUpdate?.(props);
27+
});
28+
29+
React.useEffect(() => {
30+
return () => {
31+
containerRef.current?.parentNode?.removeChild(containerRef.current);
32+
};
33+
}, []);
34+
35+
return containerRef.current ? ReactDOM.createPortal(children, containerRef.current) : null;
36+
});
37+
38+
export default Portal;

src/hooks/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export { default as useEventListener } from './useEventListener';
3030
export { default as useHover } from './useHover';
3131
export { default as useSize } from './useSize';
3232

33+
// state
3334
export { default as useSet } from './useSet';
3435
export { default as useMap } from './useMap';
3536
export { default as useError } from './useError';

0 commit comments

Comments
 (0)