mirror of
https://github.com/anyproto/anytype-ts.git
synced 2025-06-08 05:57:02 +09:00
code-review
This commit is contained in:
parent
fca3c382b4
commit
75bf48024a
10 changed files with 67 additions and 57 deletions
1
dist/index.html
vendored
1
dist/index.html
vendored
|
@ -5,7 +5,6 @@
|
|||
<title>Anytype</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="floater-root"></div>
|
||||
<div id="root"></div>
|
||||
<script src="./js/run.js" type="text/javascript"></script>
|
||||
|
||||
|
|
1
dist/index.web.html
vendored
1
dist/index.web.html
vendored
|
@ -20,7 +20,6 @@
|
|||
<script src="./js/polyfill.js" type="text/javascript"></script>
|
||||
</head>
|
||||
<body onload="onload();">
|
||||
<div id="floater-root"></div>
|
||||
<div id="root"></div>
|
||||
<script src="./js/run.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
|
|
|
@ -1,3 +1,2 @@
|
|||
.floater { position: absolute; pointer-events: none; z-index: 200; }
|
||||
.floater.show > * { opacity: 1; pointer-events: auto; transition: opacity 0.2s ease-in-out; }
|
||||
.floater.hide > * { opacity: 0; pointer-events: none; transition: opacity 0.2s ease-in-out; }
|
||||
.floater { position: absolute; pointer-events: none; z-index: 200; transition: opacity 0.2s ease-in-out; opacity: 0; }
|
||||
.floater.show { opacity: 1; pointer-events: auto; }
|
|
@ -193,7 +193,9 @@ class App extends React.Component<object, State> {
|
|||
) : ''}
|
||||
|
||||
{drag}
|
||||
<div id="floaterContainer" />
|
||||
<div id="tooltipContainer" />
|
||||
|
||||
<div id="globalFade">
|
||||
<Loader id="loader" />
|
||||
</div>
|
||||
|
|
|
@ -2,13 +2,12 @@ import { H } from 'Lib';
|
|||
import React, { useState, useEffect, ReactNode, useRef } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
|
||||
interface Props {
|
||||
children: ReactNode;
|
||||
anchorEl: HTMLElement | null;
|
||||
gap?: number;
|
||||
isShown?: boolean;
|
||||
}
|
||||
};
|
||||
|
||||
export const Floater: React.FC<Props> = ({
|
||||
children,
|
||||
|
@ -18,42 +17,50 @@ export const Floater: React.FC<Props> = ({
|
|||
}) => {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const [ position, setPosition ] = useState({ top: 0, left: 0 });
|
||||
const cn = [ 'floater' ];
|
||||
|
||||
if (isShown) {
|
||||
cn.push('show');
|
||||
};
|
||||
|
||||
const onMove = () => {
|
||||
if (anchorEl && ref.current) {
|
||||
const anchorElRect = anchorEl.getBoundingClientRect();
|
||||
const elRect = ref.current.getBoundingClientRect();
|
||||
|
||||
const { top: at, left: al, width: aw, height: ah } = anchorElRect;
|
||||
|
||||
const sy = window.scrollY;
|
||||
|
||||
const eh = elRect.height;
|
||||
const ew = elRect.width;
|
||||
|
||||
const nl = al + aw / 2 - ew / 2;
|
||||
|
||||
let nt = at - eh - offset + sy;
|
||||
if (nt < 0) {
|
||||
nt = at + ah + offset + sy;
|
||||
} else {
|
||||
nt = at - eh - offset + sy;
|
||||
}
|
||||
|
||||
setPosition({ top: nt, left: nl });
|
||||
if (!anchorEl || !ref.current) {
|
||||
return;
|
||||
};
|
||||
|
||||
const anchorElRect = anchorEl.getBoundingClientRect();
|
||||
const elRect = ref.current.getBoundingClientRect();
|
||||
|
||||
const { top: at, left: al, width: aw, height: ah } = anchorElRect;
|
||||
const sy = window.scrollY;
|
||||
|
||||
const eh = elRect.height;
|
||||
const ew = elRect.width;
|
||||
const nl = al + aw / 2 - ew / 2;
|
||||
|
||||
let nt = at - eh - offset + sy;
|
||||
if (nt < 0) {
|
||||
nt = at + ah + offset + sy;
|
||||
} else {
|
||||
nt = at - eh - offset + sy;
|
||||
};
|
||||
|
||||
setPosition({ top: nt, left: nl });
|
||||
};
|
||||
|
||||
H.useElementMovement(anchorEl, onMove);
|
||||
useEffect(() => onMove(), [ anchorEl, ref.current, isShown ]);
|
||||
|
||||
return ReactDOM.createPortal(
|
||||
<div className={`floater ${isShown ? 'show' : 'hide'}`}
|
||||
ref={ref}
|
||||
style={{ transform: `translate3d(${position.left}px, ${position.top}px, 0px)`}}
|
||||
>
|
||||
{children}
|
||||
</div>,
|
||||
document.getElementById('floater-root')
|
||||
(
|
||||
<div
|
||||
className={cn.join(' ')}
|
||||
ref={ref}
|
||||
style={{ transform: `translate3d(${position.left}px, ${position.top}px, 0px)`}}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
),
|
||||
document.getElementById('floaterContainer')
|
||||
);
|
||||
};
|
||||
};
|
|
@ -31,9 +31,7 @@ class ElementMovementObserver {
|
|||
});
|
||||
|
||||
this.startObserving();
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
private checkForMovement = () => {
|
||||
const currentPosition = this.getPosition();
|
||||
|
@ -41,7 +39,7 @@ class ElementMovementObserver {
|
|||
if (this.hasPositionChanged(currentPosition)) {
|
||||
this.lastPosition = currentPosition;
|
||||
this.onMove(currentPosition);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
private getPosition (): Position {
|
||||
|
@ -53,17 +51,16 @@ class ElementMovementObserver {
|
|||
width: rect.width,
|
||||
height: rect.height
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private hasPositionChanged (currentPosition: Position): boolean {
|
||||
private hasPositionChanged (current: Position): boolean {
|
||||
return (
|
||||
currentPosition.x !== this.lastPosition.x ||
|
||||
currentPosition.y !== this.lastPosition.y ||
|
||||
currentPosition.width !== this.lastPosition.width ||
|
||||
currentPosition.height !== this.lastPosition.height
|
||||
(current.x !== this.lastPosition.x) ||
|
||||
(current.y !== this.lastPosition.y) ||
|
||||
(current.width !== this.lastPosition.width) ||
|
||||
(current.height !== this.lastPosition.height)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
private startObserving (): void {
|
||||
const config: MutationObserverInit = {
|
||||
|
@ -90,17 +87,17 @@ class ElementMovementObserver {
|
|||
this.movementObserver.disconnect();
|
||||
this.resizeObserver.disconnect();
|
||||
window.removeEventListener('scroll', this.checkForMovement);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export default function useElementMovement ( element: HTMLElement | null, callback: (position: Position) => void ) {
|
||||
useEffect(() => {
|
||||
if (!element) return;
|
||||
if (!element) {
|
||||
return;
|
||||
};
|
||||
|
||||
const movementObserver = new ElementMovementObserver(element, callback);
|
||||
|
||||
return () => {
|
||||
movementObserver.disconnect();
|
||||
};
|
||||
}, [element, callback]);
|
||||
}
|
||||
return () => movementObserver.disconnect();
|
||||
}, [ element, callback ]);
|
||||
};
|
|
@ -4,7 +4,7 @@ import * as M from 'Model'; // Models
|
|||
import * as S from 'Store'; // Stores
|
||||
import * as U from './util'; // Utils
|
||||
import * as C from './api/command'; // Commands
|
||||
import * as H from './hook'; // React Hooks
|
||||
import * as H from 'Hook'; // React Hooks
|
||||
|
||||
import Renderer from './renderer';
|
||||
import { dispatcher } from './api/dispatcher';
|
||||
|
|
|
@ -53,6 +53,12 @@
|
|||
],
|
||||
"Store": [
|
||||
"ts/store",
|
||||
],
|
||||
"Hook/*": [
|
||||
"ts/hook/*",
|
||||
],
|
||||
"Hook": [
|
||||
"ts/hook",
|
||||
],
|
||||
"dist/*": [
|
||||
"../dist/*"
|
||||
|
|
|
@ -44,6 +44,7 @@ module.exports = (env, argv) => {
|
|||
Interface: path.resolve(__dirname, 'src/ts/interface'),
|
||||
Model: path.resolve(__dirname, 'src/ts/model'),
|
||||
Docs: path.resolve(__dirname, 'src/ts/docs'),
|
||||
Hook: path.resolve(__dirname, 'src/ts/hook'),
|
||||
},
|
||||
modules: [
|
||||
path.resolve('./src/'),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue