Skip to content

Commit

Permalink
refactor: Each Portal control self lock
Browse files Browse the repository at this point in the history
  • Loading branch information
zombieJ committed Sep 28, 2022
1 parent af65767 commit b80be5a
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 78 deletions.
18 changes: 18 additions & 0 deletions docs/examples/basic.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.abs {
position: absolute;
z-index: 999999;
left: 0;
background: red;
}

.root {
top: 0;
}

.parent {
top: 50px;
}

.children {
top: 100px;
}
61 changes: 29 additions & 32 deletions docs/examples/basic.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import React, { version } from 'react';
import classNames from 'classnames';
import Portal from '../../src';
import './basic.less';

export default () => {
const [show, setShow] = React.useState(true);
Expand All @@ -16,46 +18,41 @@ export default () => {
);

const getContainer = customizeContainer ? () => divRef.current : undefined;
const contentCls = customizeContainer ? '' : 'abs';

return (
<React.StrictMode>
<div style={{ border: '2px solid red' }}>
Real Version: {version}
<button onClick={() => setShow(!show)}>show: {show.toString()}</button>
<button onClick={() => setCustomizeContainer(!customizeContainer)}>
customize container: {customizeContainer.toString()}
</button>
<button onClick={() => setLock(!lock)}>
lock scroll: {lock.toString()}
</button>
<div
id="customize"
ref={divRef}
style={{ border: '1px solid green', minHeight: 10 }}
/>
</div>
<div style={{ height: '200vh' }}>
<div style={{ border: '2px solid red' }}>
Real Version: {version}
<button onClick={() => setShow(!show)}>
show: {show.toString()}
</button>
<button onClick={() => setCustomizeContainer(!customizeContainer)}>
customize container: {customizeContainer.toString()}
</button>
<button onClick={() => setLock(!lock)}>
lock scroll: {lock.toString()}
</button>
<div
id="customize"
ref={divRef}
style={{ border: '1px solid green', minHeight: 10 }}
/>
</div>

<Portal open={show} getContainer={getContainer} autoLock={lock}>
<p>Hello Root</p>
<Portal open={show} getContainer={getContainer} autoLock={lock}>
<p>Hello Parent</p>
<p className={classNames(contentCls, 'root')}>Hello Root</p>
<Portal open={show} getContainer={getContainer} autoLock={lock}>
<p>Hello Children</p>
<p className={classNames(contentCls, 'parent')}>Hello Parent</p>
<Portal open={show} getContainer={getContainer} autoLock={lock}>
<p className={classNames(contentCls, 'children')}>
Hello Children
</p>
</Portal>
</Portal>
</Portal>
</Portal>

<div
style={{
position: 'absolute',
top: 0,
right: 0,
height: '200vh',
width: 1,
background: 'yellow',
zIndex: -1,
}}
/>
</div>
</React.StrictMode>
);
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
},
"dependencies": {
"@babel/runtime": "^7.18.0",
"classnames": "^2.3.2",
"rc-util": "^5.8.0"
},
"devDependencies": {
Expand Down
60 changes: 14 additions & 46 deletions src/useScrollLocker.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
import * as React from 'react';
import { updateCSS, removeCSS } from 'rc-util/lib/Dom/dynamicCSS';
import useLayoutEffect, {
useLayoutUpdateEffect,
} from 'rc-util/lib/hooks/useLayoutEffect';
import useLayoutEffect from 'rc-util/lib/hooks/useLayoutEffect';
import getScrollBarSize from 'rc-util/lib/getScrollBarSize';
import { isBodyOverflowing } from './util';

let lockCount = 0;
let locked = false;

const UNIQUE_ID = `rc-util-locker-${Date.now()}`;

function syncLocker() {
const nextLocked = lockCount > 0;
let uuid = 0;

if (locked !== nextLocked) {
locked = nextLocked;
export default function useScrollLocker(lock?: boolean) {
const mergedLock = !!lock;
const [id] = React.useState(() => {
uuid += 1;
return `${UNIQUE_ID}_${uuid}`;
});

if (locked) {
useLayoutEffect(() => {
if (mergedLock) {
const scrollbarSize = getScrollBarSize();
const isOverflow = isBodyOverflowing();

Expand All @@ -27,45 +26,14 @@ html body {
overflow-y: hidden;
${isOverflow ? `width: calc(100% - ${scrollbarSize}px);` : ''}
}`,
UNIQUE_ID,
id,
);
} else {
removeCSS(UNIQUE_ID);
removeCSS(id);
}
}
}

export default function useScrollLocker(lock?: boolean) {
const mergedLock = !!lock;

// Init only check lock
useLayoutEffect(() => {
if (mergedLock) {
lockCount += 1;
syncLocker();
}
}, []);

// Update will both check the lock state
useLayoutUpdateEffect(() => {
if (mergedLock) {
lockCount += 1;
syncLocker();
} else {
lockCount -= 1;
syncLocker();
}
}, [mergedLock]);

const lockRef = React.useRef(mergedLock);
lockRef.current = mergedLock;

useLayoutEffect(() => {
return () => {
if (lockRef.current) {
lockCount -= 1;
syncLocker();
}
removeCSS(id);
};
}, []);
}, [mergedLock, id]);
}

0 comments on commit b80be5a

Please sign in to comment.