Interactive
Summary: _typescript_ Reviewed By: passy Differential Revision: D16830548 fbshipit-source-id: d0530ef3491af95bece7fba610a4b1cf19c80bd1
This commit is contained in:
committed by
Facebook Github Bot
parent
e00db4f6d3
commit
28a295bcf1
@@ -5,31 +5,34 @@
|
||||
* @format
|
||||
*/
|
||||
|
||||
import type {Rect} from '../../utils/geometry.tsx';
|
||||
import LowPassFilter from '../../utils/LowPassFilter.tsx';
|
||||
import {Rect} from '../../utils/geometry';
|
||||
import LowPassFilter from '../../utils/LowPassFilter';
|
||||
import {
|
||||
getDistanceTo,
|
||||
maybeSnapLeft,
|
||||
maybeSnapTop,
|
||||
SNAP_SIZE,
|
||||
} from '../../utils/snap.tsx';
|
||||
import styled from '../styled/index.js';
|
||||
} from '../../utils/snap';
|
||||
import styled from 'react-emotion';
|
||||
import invariant from 'invariant';
|
||||
import React from 'react';
|
||||
|
||||
const WINDOW_CURSOR_BOUNDARY = 5;
|
||||
|
||||
type CursorState = {|
|
||||
top: number,
|
||||
left: number,
|
||||
|};
|
||||
type CursorState = {
|
||||
top: number;
|
||||
left: number;
|
||||
};
|
||||
|
||||
type ResizingSides = ?{|
|
||||
left?: boolean,
|
||||
top?: boolean,
|
||||
bottom?: boolean,
|
||||
right?: boolean,
|
||||
|};
|
||||
type ResizingSides =
|
||||
| {
|
||||
left?: boolean;
|
||||
top?: boolean;
|
||||
bottom?: boolean;
|
||||
right?: boolean;
|
||||
}
|
||||
| null
|
||||
| undefined;
|
||||
|
||||
const ALL_RESIZABLE: ResizingSides = {
|
||||
bottom: true,
|
||||
@@ -38,52 +41,52 @@ const ALL_RESIZABLE: ResizingSides = {
|
||||
top: true,
|
||||
};
|
||||
|
||||
type InteractiveProps = {|
|
||||
isMovableAnchor?: (event: SyntheticMouseEvent<>) => boolean,
|
||||
onMoveStart?: () => void,
|
||||
onMoveEnd?: () => void,
|
||||
onMove?: (top: number, left: number, event: SyntheticMouseEvent<>) => void,
|
||||
id?: string,
|
||||
movable?: boolean,
|
||||
hidden?: boolean,
|
||||
moving?: boolean,
|
||||
grow?: boolean,
|
||||
siblings?: $Shape<{[key: string]: $Shape<Rect>}>,
|
||||
updateCursor?: (cursor: ?string) => void,
|
||||
zIndex?: number,
|
||||
top?: number,
|
||||
left?: number,
|
||||
minTop: number,
|
||||
minLeft: number,
|
||||
width?: number | string,
|
||||
height?: number | string,
|
||||
minWidth: number,
|
||||
minHeight: number,
|
||||
maxWidth?: number,
|
||||
maxHeight?: number,
|
||||
onCanResize?: (sides: ResizingSides) => void,
|
||||
onResizeStart?: () => void,
|
||||
onResizeEnd?: () => void,
|
||||
onResize?: (width: number, height: number) => void,
|
||||
resizing?: boolean,
|
||||
resizable?: boolean | ResizingSides,
|
||||
innerRef?: (elem: HTMLElement) => void,
|
||||
style?: Object,
|
||||
className?: string,
|
||||
children?: React$Element<*>,
|
||||
|};
|
||||
type InteractiveProps = {
|
||||
isMovableAnchor?: (event: React.MouseEvent) => boolean;
|
||||
onMoveStart?: () => void;
|
||||
onMoveEnd?: () => void;
|
||||
onMove?: (top: number, left: number, event: MouseEvent) => void;
|
||||
id?: string;
|
||||
movable?: boolean;
|
||||
hidden?: boolean;
|
||||
moving?: boolean;
|
||||
grow?: boolean;
|
||||
siblings?: Partial<{[key: string]: Rect}>;
|
||||
updateCursor?: (cursor?: string | null | undefined) => void;
|
||||
zIndex?: number;
|
||||
top?: number;
|
||||
left?: number;
|
||||
minTop?: number;
|
||||
minLeft?: number;
|
||||
width?: number | string;
|
||||
height?: number | string;
|
||||
minWidth: number;
|
||||
minHeight: number;
|
||||
maxWidth?: number;
|
||||
maxHeight?: number;
|
||||
onCanResize?: (sides: ResizingSides) => void;
|
||||
onResizeStart?: () => void;
|
||||
onResizeEnd?: () => void;
|
||||
onResize?: (width: number, height: number) => void;
|
||||
resizing?: boolean;
|
||||
resizable?: boolean | ResizingSides;
|
||||
innerRef?: (elem: HTMLElement) => void;
|
||||
style?: Object;
|
||||
className?: string;
|
||||
children?: React.ReactNode;
|
||||
};
|
||||
|
||||
type InteractiveState = {|
|
||||
moving: boolean,
|
||||
movingInitialProps: ?InteractiveProps,
|
||||
movingInitialCursor: ?CursorState,
|
||||
cursor: ?string,
|
||||
resizingSides: ResizingSides,
|
||||
couldResize: boolean,
|
||||
resizing: boolean,
|
||||
resizingInitialRect: ?Rect,
|
||||
resizingInitialCursor: ?CursorState,
|
||||
|};
|
||||
type InteractiveState = {
|
||||
moving: boolean;
|
||||
movingInitialProps: InteractiveProps | null | undefined;
|
||||
movingInitialCursor: CursorState | null | undefined;
|
||||
cursor: string | null | undefined;
|
||||
resizingSides: ResizingSides;
|
||||
couldResize: boolean;
|
||||
resizing: boolean;
|
||||
resizingInitialRect: Rect | null | undefined;
|
||||
resizingInitialCursor: CursorState | null | undefined;
|
||||
};
|
||||
|
||||
const InteractiveContainer = styled('div')({
|
||||
willChange: 'transform, height, width, z-index',
|
||||
@@ -91,7 +94,7 @@ const InteractiveContainer = styled('div')({
|
||||
|
||||
export default class Interactive extends React.Component<
|
||||
InteractiveProps,
|
||||
InteractiveState,
|
||||
InteractiveState
|
||||
> {
|
||||
constructor(props: InteractiveProps, context: Object) {
|
||||
super(props, context);
|
||||
@@ -114,9 +117,9 @@ export default class Interactive extends React.Component<
|
||||
globalMouse: boolean;
|
||||
ref: HTMLElement;
|
||||
|
||||
nextTop: ?number;
|
||||
nextLeft: ?number;
|
||||
nextEvent: ?SyntheticMouseEvent<>;
|
||||
nextTop: number | null | undefined;
|
||||
nextLeft: number | null | undefined;
|
||||
nextEvent: MouseEvent | null | undefined;
|
||||
|
||||
static defaultProps = {
|
||||
minHeight: 0,
|
||||
@@ -125,7 +128,7 @@ export default class Interactive extends React.Component<
|
||||
minWidth: 0,
|
||||
};
|
||||
|
||||
onMouseMove = (event: SyntheticMouseEvent<>) => {
|
||||
onMouseMove = (event: MouseEvent) => {
|
||||
if (this.state.moving) {
|
||||
this.calculateMove(event);
|
||||
} else if (this.state.resizing) {
|
||||
@@ -135,7 +138,7 @@ export default class Interactive extends React.Component<
|
||||
}
|
||||
};
|
||||
|
||||
startAction = (event: SyntheticMouseEvent<>) => {
|
||||
startAction = (event: React.MouseEvent) => {
|
||||
this.globalMouse = true;
|
||||
window.addEventListener('pointerup', this.endAction, {passive: true});
|
||||
window.addEventListener('pointermove', this.onMouseMove, {passive: true});
|
||||
@@ -148,7 +151,7 @@ export default class Interactive extends React.Component<
|
||||
}
|
||||
};
|
||||
|
||||
startTitleAction(event: SyntheticMouseEvent<>) {
|
||||
startTitleAction(event: React.MouseEvent) {
|
||||
if (this.state.couldResize) {
|
||||
this.startResizeAction(event);
|
||||
} else if (this.props.movable === true) {
|
||||
@@ -156,7 +159,7 @@ export default class Interactive extends React.Component<
|
||||
}
|
||||
}
|
||||
|
||||
startMoving(event: SyntheticMouseEvent<>) {
|
||||
startMoving(event: React.MouseEvent) {
|
||||
const {onMoveStart} = this.props;
|
||||
if (onMoveStart) {
|
||||
onMoveStart();
|
||||
@@ -229,13 +232,13 @@ export default class Interactive extends React.Component<
|
||||
return closeWindows;
|
||||
}
|
||||
|
||||
startWindowAction(event: SyntheticMouseEvent<>) {
|
||||
startWindowAction(event: React.MouseEvent) {
|
||||
if (this.state.couldResize) {
|
||||
this.startResizeAction(event);
|
||||
}
|
||||
}
|
||||
|
||||
startResizeAction(event: SyntheticMouseEvent<>) {
|
||||
startResizeAction(event: React.MouseEvent) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
@@ -254,7 +257,10 @@ export default class Interactive extends React.Component<
|
||||
});
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: InteractiveProps, prevState: InteractiveState) {
|
||||
componentDidUpdate(
|
||||
_prevProps: InteractiveProps,
|
||||
prevState: InteractiveState,
|
||||
) {
|
||||
if (prevState.cursor !== this.state.cursor) {
|
||||
const {updateCursor} = this.props;
|
||||
if (updateCursor) {
|
||||
@@ -323,13 +329,13 @@ export default class Interactive extends React.Component<
|
||||
}
|
||||
};
|
||||
|
||||
onClick = (e: SyntheticMouseEvent<>) => {
|
||||
onClick = (e: React.MouseEvent) => {
|
||||
if (this.state.couldResize) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
};
|
||||
|
||||
calculateMove(event: SyntheticMouseEvent<>) {
|
||||
calculateMove(event: MouseEvent) {
|
||||
const {movingInitialCursor, movingInitialProps} = this.state;
|
||||
|
||||
invariant(movingInitialProps, 'TODO');
|
||||
@@ -380,7 +386,7 @@ export default class Interactive extends React.Component<
|
||||
onResize(width, height);
|
||||
}
|
||||
|
||||
move(top: number, left: number, event: SyntheticMouseEvent<>) {
|
||||
move(top: number, left: number, event: MouseEvent) {
|
||||
top = Math.max(this.props.minTop, top);
|
||||
left = Math.max(this.props.minLeft, left);
|
||||
|
||||
@@ -395,7 +401,7 @@ export default class Interactive extends React.Component<
|
||||
}
|
||||
}
|
||||
|
||||
calculateResize(event: SyntheticMouseEvent<>) {
|
||||
calculateResize(event: MouseEvent) {
|
||||
const {
|
||||
resizingInitialCursor,
|
||||
resizingInitialRect,
|
||||
@@ -514,13 +520,15 @@ export default class Interactive extends React.Component<
|
||||
}
|
||||
|
||||
checkIfResizable(
|
||||
event: SyntheticMouseEvent<>,
|
||||
): ?{|
|
||||
left: boolean,
|
||||
right: boolean,
|
||||
top: boolean,
|
||||
bottom: boolean,
|
||||
|} {
|
||||
event: MouseEvent,
|
||||
):
|
||||
| {
|
||||
left: boolean;
|
||||
right: boolean;
|
||||
top: boolean;
|
||||
bottom: boolean;
|
||||
}
|
||||
| undefined {
|
||||
const canResize = this.getResizable();
|
||||
if (!canResize) {
|
||||
return;
|
||||
@@ -546,7 +554,7 @@ export default class Interactive extends React.Component<
|
||||
};
|
||||
}
|
||||
|
||||
calculateResizable(event: SyntheticMouseEvent<>) {
|
||||
calculateResizable(event: MouseEvent) {
|
||||
const resizing = this.checkIfResizable(event);
|
||||
if (!resizing) {
|
||||
return;
|
||||
@@ -629,7 +637,7 @@ export default class Interactive extends React.Component<
|
||||
|
||||
const {onCanResize} = this.props;
|
||||
if (onCanResize) {
|
||||
onCanResize();
|
||||
onCanResize({});
|
||||
}
|
||||
|
||||
this.setState({
|
||||
@@ -648,16 +656,16 @@ export default class Interactive extends React.Component<
|
||||
}
|
||||
};
|
||||
|
||||
onLocalMouseMove = (event: SyntheticMouseEvent<>) => {
|
||||
onLocalMouseMove = (event: React.MouseEvent) => {
|
||||
if (!this.globalMouse) {
|
||||
this.onMouseMove(event);
|
||||
this.onMouseMove(event.nativeEvent);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {grow, height, left, movable, top, width, zIndex} = this.props;
|
||||
|
||||
const style: Object = {
|
||||
const style: React.CSSProperties = {
|
||||
cursor: this.state.cursor,
|
||||
zIndex: zIndex == null ? 'auto' : zIndex,
|
||||
};
|
||||
@@ -5,7 +5,7 @@
|
||||
* @format
|
||||
*/
|
||||
|
||||
import Interactive from './Interactive.js';
|
||||
import Interactive from './Interactive';
|
||||
import FlexColumn from './FlexColumn.js';
|
||||
import {colors} from './colors';
|
||||
import {Component} from 'react';
|
||||
|
||||
@@ -17,7 +17,7 @@ import type {
|
||||
import {normaliseColumnWidth, isPercentage} from './utils.js';
|
||||
import {PureComponent} from 'react';
|
||||
import ContextMenu from '../ContextMenu.js';
|
||||
import Interactive from '../Interactive.js';
|
||||
import Interactive from '../Interactive.tsx';
|
||||
import styled from '../../styled/index.js';
|
||||
import {colors} from '../colors.tsx';
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ export {default as ErrorBoundary} from './components/ErrorBoundary.js';
|
||||
|
||||
// interactive components
|
||||
export type {OrderableOrder} from './components/Orderable.tsx';
|
||||
export {default as Interactive} from './components/Interactive.js';
|
||||
export {default as Interactive} from './components/Interactive.tsx';
|
||||
export {default as Orderable} from './components/Orderable.tsx';
|
||||
export {default as VirtualList} from './components/VirtualList.tsx';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user