1
0
Fork 0
mirror of https://github.com/anyproto/anytype-ts.git synced 2025-06-08 05:57:02 +09:00

Fix a lot

This commit is contained in:
Nikita Dudnik (nek) 2024-10-28 14:52:11 +01:00
parent cf542cd1ac
commit c877d9c68f
16 changed files with 93 additions and 77 deletions

2
.gitignore vendored
View file

@ -25,3 +25,5 @@ licenses.json
/darwin-amd*/
/darwin-arm*/
/windows/
.aider*
.env

View file

@ -1,6 +1,5 @@
$easeInQuint: cubic-bezier(0.22, 1, 0.36, 1);
$transitionCommon: 0.1s $easeInQuint;
$transitionSmoothCommon: 0.35s $easeInQuint;
$transitionAllCommon: all $transitionCommon;
$transitionSidebarTime: 0.18s;

View file

@ -6,6 +6,7 @@
@import "./editor";
@import "./emptySearch";
@import "./error";
@import "./floater";
@import "./footer";
@import "./frame";
@import "./header";

View file

@ -0,0 +1 @@
.floater { position: absolute; pointer-events: none; z-index: 200; }

View file

@ -52,5 +52,5 @@
}
}
.volume.input-drag-vertical { opacity: 0; transition: opacity $transitionSmoothCommon; pointer-events: none; }
.volume.input-drag-vertical { opacity: 0; transition: opacity 0.35s ease-in-out; pointer-events: none; }
.volume.input-drag-vertical.visible { opacity: 1; pointer-events: auto; }

View file

@ -1,6 +1,6 @@
@import "./button";
@import "./dragHorizontal";
@import "./dragVertical";
@import "./drag/horizontal";
@import "./drag/vertical";
@import "./filter";
@import "./input";
@import "./inputWithFile";

View file

@ -1,6 +1,6 @@
import * as React from 'react';
import { useEffect, useImperativeHandle, useRef } from 'react';
import Input from './input';
import { Input } from 'Component';
interface Props {
id?: string;

View file

@ -51,8 +51,8 @@ import Checkbox from './form/checkbox';
import Textarea from './form/textarea';
import Button from './form/button';
import Select from './form/select';
import DragHorizontal from './form/dragHorizontal';
import DragVertical from './form/dragVertical';
import DragHorizontal from './form/drag/horizontal';
import DragVertical from './form/drag/vertical';
import Pin from './form/pin';
import Filter from './form/filter';
import Phrase from './form/phrase';

View file

@ -1,22 +1,28 @@
import { H } from 'Lib';
import React, { useState, useEffect, ReactNode, useRef } from 'react';
import ReactDOM from 'react-dom';
import { useElementMovement } from './useMovementObserver';
interface Props {
children: ReactNode;
anchorEl: HTMLElement | null;
anchorTo?: 'top' | 'bottom';
anchorTo?: AnchorTo;
offset?: {
x?: number;
y?: number;
left?: number;
top?: number;
};
}
export enum AnchorTo {
Top = 'top',
Bottom = 'bottom',
}
export const Floater: React.FC<Props> = ({
children,
anchorEl,
anchorTo = 'bottom',
offset = { x: 0, y: 0 },
anchorTo = AnchorTo.Bottom,
offset = { top: 0, left: 0 },
}) => {
const ref = useRef<HTMLDivElement>(null);
const [ position, setPosition ] = useState({ top: 0, left: 0 });
@ -24,44 +30,41 @@ export const Floater: React.FC<Props> = ({
const onMove = () => {
if (anchorEl && ref.current) {
const anchorElRect = anchorEl.getBoundingClientRect();
const floaterElRect = ref.current.getBoundingClientRect();
const elRect = ref.current.getBoundingClientRect();
const { top, left, bottom, width } = anchorElRect;
const fh = floaterElRect.height;
const fw = floaterElRect.width;
const { top: at, left: al, bottom: ab, width: aw } = anchorElRect;
const eh = elRect.height;
const ew = elRect.width;
const x = Number(offset.x) || 0;
const y = Number(offset.y) || 0;
const ot = Number(offset.top) || 0;
const ol = Number(offset.left) || 0;
let pt = 0;
let pl = 0;
let nt = 0;
let nl = 0;
if (anchorTo == 'top') {
pt = top - fh + y;
pl = left + width / 2 - fw / 2 + x;
} else {
pt = bottom + y;
pl = left + width / 2 - fw / 2 + x;
switch (anchorTo) {
case AnchorTo.Top:
nt = at - eh + ot;
nl = al + aw / 2 - ew / 2 + ol;
break;
case AnchorTo.Bottom:
nt = ab + ot;
nl = al + aw / 2 - ew / 2 + ol;
break;
};
setPosition({ top: pt, left: pl });
setPosition({ top: nt, left: nl });
};
};
useElementMovement(anchorEl, onMove);
H.useElementMovement(anchorEl, onMove);
useEffect(() => onMove(), [ anchorEl, ref.current ]);
return ReactDOM.createPortal(
<div
<div className="floater"
ref={ref}
style={{
position: 'absolute',
pointerEvents: 'none',
// This is hopefully the highest z-index in the app
zIndex: 200,
top: `${position.top}px`,
left: `${position.left}px`,
}}>
style={{ transform: `translate3d(${position.top}px, ${-position.left}px, 0px)`}}
>
{children}
</div>,
document.body

View file

@ -1,9 +1,8 @@
import * as React from 'react';
import $ from 'jquery';
import { Icon, DragHorizontal } from 'Component';
import { Icon, DragHorizontal, DragVertical } from 'Component';
import { U } from 'Lib';
import DragVertical from 'Component/form/dragVertical';
import { Floater } from '../floater';
import { AnchorTo, Floater } from '../floater';
import _ from 'lodash';
interface PlaylistItem {
@ -108,8 +107,8 @@ class MediaAudio extends React.Component<Props, State> {
<Floater
anchorEl={this.volumeIcon?.node}
anchorTo={'top'}
offset={{ y: -2 }}
anchorTo={AnchorTo.Top}
offset={{ top: -2 }}
>
<DragVertical
id="volume"

5
src/ts/lib/hook/index.ts Normal file
View file

@ -0,0 +1,5 @@
import useElementMovement from './useElementMovement';
export {
useElementMovement,
};

View file

@ -1,5 +1,4 @@
import React, { useState, useEffect, ReactNode, useRef } from 'react';
import ReactDOM from 'react-dom';
import { useEffect } from 'react';
interface Position {
x: number;
@ -9,9 +8,13 @@ interface Position {
}
class ElementMovementObserver {
private observer: MutationObserver;
private movementObserver: MutationObserver;
private resizeObserver: ResizeObserver;
private element: HTMLElement;
private lastPosition: Position;
private onMove: (position: Position) => void;
constructor(element: HTMLElement, callback: (position: Position) => void) {
@ -19,17 +22,31 @@ class ElementMovementObserver {
this.onMove = callback;
this.lastPosition = this.getPosition();
// Create observer instance
this.observer = new MutationObserver(() => {
this.movementObserver = new MutationObserver(() => {
this.checkForMovement();
});
this.resizeObserver = new ResizeObserver(() => {
this.checkForMovement();
});
// Start observing
this.startObserving();
}
private getPosition(): Position {
private checkForMovement = () => {
const currentPosition = this.getPosition();
if (this.hasPositionChanged(currentPosition)) {
this.lastPosition = currentPosition;
this.onMove(currentPosition);
}
};
private getPosition (): Position {
const rect = this.element.getBoundingClientRect();
return {
x: rect.left + window.scrollX,
y: rect.top + window.scrollY,
@ -38,16 +55,8 @@ class ElementMovementObserver {
};
}
private checkForMovement(): void {
const currentPosition = this.getPosition();
if (this.hasPositionChanged(currentPosition)) {
this.lastPosition = currentPosition;
this.onMove(currentPosition);
}
}
private hasPositionChanged(currentPosition: Position): boolean {
private hasPositionChanged (currentPosition: Position): boolean {
return (
currentPosition.x !== this.lastPosition.x ||
currentPosition.y !== this.lastPosition.y ||
@ -56,8 +65,7 @@ class ElementMovementObserver {
);
}
private startObserving(): void {
// Configure observer options
private startObserving (): void {
const config: MutationObserverInit = {
attributes: true,
childList: true,
@ -65,31 +73,27 @@ class ElementMovementObserver {
characterData: true
};
// Start observing the element and its descendants
this.observer.observe(this.element, config);
// Observe the element and its descendants for movement
this.movementObserver.observe(this.element, config);
// Observe the document body for layout changes
this.observer.observe(document.body, config);
this.movementObserver.observe(document.body, config);
const resizeObserver = new ResizeObserver(() => {
this.checkForMovement();
});
resizeObserver.observe(this.element);
// Observe the element for size changes
this.resizeObserver.observe(this.element);
window.addEventListener('scroll', () => {
this.checkForMovement();
});
// And handle scroll
window.addEventListener('scroll', this.checkForMovement);
}
public disconnect(): void {
this.observer.disconnect();
public disconnect (): void {
this.movementObserver.disconnect();
this.resizeObserver.disconnect();
window.removeEventListener('scroll', this.checkForMovement);
}
}
export function useElementMovement(
element: HTMLElement | null,
callback: (position: Position) => void
) {
export default function useElementMovement ( element: HTMLElement | null, callback: (position: Position) => void ) {
useEffect(() => {
if (!element) return;

View file

@ -4,6 +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 Renderer from './renderer';
import { dispatcher } from './api/dispatcher';
@ -34,6 +35,7 @@ export {
S,
U,
J,
H,
keyboard,
sidebar,
focus,