mirror of https://github.com/fantasticit/think.git
refactor: use re-resizeable
parent
bcde9ce598
commit
2095cafec2
|
@ -59,7 +59,6 @@
|
||||||
"copy-to-clipboard": "^3.3.1",
|
"copy-to-clipboard": "^3.3.1",
|
||||||
"deep-equal": "^2.0.5",
|
"deep-equal": "^2.0.5",
|
||||||
"dompurify": "^2.3.5",
|
"dompurify": "^2.3.5",
|
||||||
"interactjs": "^1.10.11",
|
|
||||||
"katex": "^0.15.2",
|
"katex": "^0.15.2",
|
||||||
"kity": "^2.0.4",
|
"kity": "^2.0.4",
|
||||||
"lib0": "^0.2.47",
|
"lib0": "^0.2.47",
|
||||||
|
@ -75,6 +74,7 @@
|
||||||
"prosemirror-tables": "^1.1.1",
|
"prosemirror-tables": "^1.1.1",
|
||||||
"prosemirror-utils": "^0.9.6",
|
"prosemirror-utils": "^0.9.6",
|
||||||
"prosemirror-view": "^1.23.6",
|
"prosemirror-view": "^1.23.6",
|
||||||
|
"re-resizable": "^6.9.9",
|
||||||
"react": "17.0.2",
|
"react": "17.0.2",
|
||||||
"react-countdown": "^2.3.2",
|
"react-countdown": "^2.3.2",
|
||||||
"react-dom": "17.0.2",
|
"react-dom": "17.0.2",
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import React, { useRef, useEffect } from 'react';
|
import React, { useCallback, useState } from 'react';
|
||||||
import cls from 'classnames';
|
import cls from 'classnames';
|
||||||
import { useClickOutside } from 'hooks/use-click-outside';
|
|
||||||
import interact from 'interactjs';
|
|
||||||
import styles from './style.module.scss';
|
import styles from './style.module.scss';
|
||||||
|
|
||||||
|
import { Resizable } from 're-resizable';
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
|
@ -15,71 +15,37 @@ interface IProps {
|
||||||
const MIN_WIDTH = 50;
|
const MIN_WIDTH = 50;
|
||||||
const MIN_HEIGHT = 50;
|
const MIN_HEIGHT = 50;
|
||||||
|
|
||||||
export const Resizeable: React.FC<IProps> = ({ width, height, className, onChange, onChangeEnd, children }) => {
|
export const Resizeable: React.FC<IProps> = ({
|
||||||
const $container = useRef<HTMLDivElement>(null);
|
width: defaultWidth,
|
||||||
const $topLeft = useRef<HTMLDivElement>(null);
|
height: defaultHeight,
|
||||||
const $topRight = useRef<HTMLDivElement>(null);
|
className,
|
||||||
const $bottomLeft = useRef<HTMLDivElement>(null);
|
onChange,
|
||||||
const $bottomRight = useRef<HTMLDivElement>(null);
|
onChangeEnd,
|
||||||
|
children,
|
||||||
|
}) => {
|
||||||
|
const [width, setWidth] = useState(defaultWidth);
|
||||||
|
const [height, setHeight] = useState(defaultHeight);
|
||||||
|
|
||||||
useClickOutside($container, {
|
const onResizeStop = useCallback(
|
||||||
in: () => $container.current.classList.add(styles.isActive),
|
(e, direction, ref, d) => {
|
||||||
out: () => $container.current.classList.remove(styles.isActive),
|
const nextWidth = width + d.width;
|
||||||
});
|
const nextHeight = height + d.height;
|
||||||
|
setWidth(nextWidth);
|
||||||
useEffect(() => {
|
setHeight(nextHeight);
|
||||||
interact($container.current).resizable({
|
onChangeEnd({ width: nextWidth, height: nextHeight });
|
||||||
edges: {
|
},
|
||||||
top: true,
|
[width, height]
|
||||||
right: true,
|
);
|
||||||
bottom: true,
|
|
||||||
left: true,
|
|
||||||
},
|
|
||||||
listeners: {
|
|
||||||
move: function (event) {
|
|
||||||
let { x, y } = event.target.dataset;
|
|
||||||
x = (parseFloat(x) || 0) + event.deltaRect.left;
|
|
||||||
y = (parseFloat(y) || 0) + event.deltaRect.top;
|
|
||||||
|
|
||||||
let { width, height } = event.rect;
|
|
||||||
width = width < MIN_WIDTH ? MIN_WIDTH : width;
|
|
||||||
height = height < MIN_HEIGHT ? MIN_HEIGHT : height;
|
|
||||||
|
|
||||||
Object.assign(event.target.style, {
|
|
||||||
width: `${width}px`,
|
|
||||||
height: `${height}px`,
|
|
||||||
// transform: `translate(${x}px, ${y}px)`,
|
|
||||||
});
|
|
||||||
Object.assign(event.target.dataset, { x, y });
|
|
||||||
onChange && onChange({ width, height });
|
|
||||||
},
|
|
||||||
end: function (event) {
|
|
||||||
let { width, height } = event.rect;
|
|
||||||
onChangeEnd && onChangeEnd({ width, height });
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
Object.assign($container.current.style, {
|
|
||||||
width: `${width}px`,
|
|
||||||
height: `${height}px`,
|
|
||||||
});
|
|
||||||
}, [width, height]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<Resizable
|
||||||
id="js-resizeable-container"
|
size={{ width, height }}
|
||||||
className={cls(className, styles.resizable)}
|
className={cls(className, styles.resizable)}
|
||||||
ref={$container}
|
minWidth={MIN_WIDTH}
|
||||||
style={{ width, height }}
|
minHeight={MIN_HEIGHT}
|
||||||
|
onResizeStop={onResizeStop}
|
||||||
>
|
>
|
||||||
<span className={styles.resizer + ' ' + styles.topLeft} ref={$topLeft} data-type={'topLeft'}></span>
|
|
||||||
<span className={styles.resizer + ' ' + styles.topRight} ref={$topRight} data-type={'topRight'}></span>
|
|
||||||
<span className={styles.resizer + ' ' + styles.bottomLeft} ref={$bottomLeft} data-type={'bottomLeft'}></span>
|
|
||||||
<span className={styles.resizer + ' ' + styles.bottomRight} ref={$bottomRight} data-type={'bottomRight'}></span>
|
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</Resizable>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,47 +4,8 @@
|
||||||
width: 100px;
|
width: 100px;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
.resizer {
|
|
||||||
position: absolute;
|
|
||||||
z-index: 9999;
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
background: white;
|
|
||||||
border: 3px solid #4286f4;
|
|
||||||
border-radius: 50%;
|
|
||||||
opacity: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.resizer.topLeft {
|
|
||||||
top: -5px;
|
|
||||||
left: -5px;
|
|
||||||
cursor: nwse-resize;
|
|
||||||
}
|
|
||||||
|
|
||||||
.resizer.topRight {
|
|
||||||
top: -5px;
|
|
||||||
right: -5px;
|
|
||||||
cursor: nesw-resize;
|
|
||||||
}
|
|
||||||
|
|
||||||
.resizer.bottomLeft {
|
|
||||||
bottom: -5px;
|
|
||||||
left: -5px;
|
|
||||||
cursor: nesw-resize;
|
|
||||||
}
|
|
||||||
|
|
||||||
.resizer.bottomRight {
|
|
||||||
right: -5px;
|
|
||||||
bottom: -5px;
|
|
||||||
cursor: nwse-resize;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.isActive {
|
&.isActive {
|
||||||
outline: 1px solid #4286f4;
|
|
||||||
|
|
||||||
.resizer {
|
.resizer {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,6 @@ importers:
|
||||||
copy-to-clipboard: ^3.3.1
|
copy-to-clipboard: ^3.3.1
|
||||||
deep-equal: ^2.0.5
|
deep-equal: ^2.0.5
|
||||||
dompurify: ^2.3.5
|
dompurify: ^2.3.5
|
||||||
interactjs: ^1.10.11
|
|
||||||
katex: ^0.15.2
|
katex: ^0.15.2
|
||||||
kity: ^2.0.4
|
kity: ^2.0.4
|
||||||
lib0: ^0.2.47
|
lib0: ^0.2.47
|
||||||
|
@ -105,6 +104,7 @@ importers:
|
||||||
prosemirror-tables: ^1.1.1
|
prosemirror-tables: ^1.1.1
|
||||||
prosemirror-utils: ^0.9.6
|
prosemirror-utils: ^0.9.6
|
||||||
prosemirror-view: ^1.23.6
|
prosemirror-view: ^1.23.6
|
||||||
|
re-resizable: ^6.9.9
|
||||||
react: 17.0.2
|
react: 17.0.2
|
||||||
react-countdown: ^2.3.2
|
react-countdown: ^2.3.2
|
||||||
react-dom: 17.0.2
|
react-dom: 17.0.2
|
||||||
|
@ -172,7 +172,6 @@ importers:
|
||||||
copy-to-clipboard: 3.3.1
|
copy-to-clipboard: 3.3.1
|
||||||
deep-equal: 2.0.5
|
deep-equal: 2.0.5
|
||||||
dompurify: 2.3.5
|
dompurify: 2.3.5
|
||||||
interactjs: 1.10.11
|
|
||||||
katex: 0.15.2
|
katex: 0.15.2
|
||||||
kity: 2.0.4
|
kity: 2.0.4
|
||||||
lib0: 0.2.47
|
lib0: 0.2.47
|
||||||
|
@ -188,6 +187,7 @@ importers:
|
||||||
prosemirror-tables: 1.1.1
|
prosemirror-tables: 1.1.1
|
||||||
prosemirror-utils: 0.9.6_prosemirror-tables@1.1.1
|
prosemirror-utils: 0.9.6_prosemirror-tables@1.1.1
|
||||||
prosemirror-view: 1.23.6
|
prosemirror-view: 1.23.6
|
||||||
|
re-resizable: 6.9.9_react-dom@17.0.2+react@17.0.2
|
||||||
react: 17.0.2
|
react: 17.0.2
|
||||||
react-countdown: 2.3.2_react-dom@17.0.2+react@17.0.2
|
react-countdown: 2.3.2_react-dom@17.0.2+react@17.0.2
|
||||||
react-dom: 17.0.2_react@17.0.2
|
react-dom: 17.0.2_react@17.0.2
|
||||||
|
@ -955,10 +955,6 @@ packages:
|
||||||
- y-protocols
|
- y-protocols
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@interactjs/types/1.10.11:
|
|
||||||
resolution: {integrity: sha512-YRsVFWjL8Gkkvlx3qnjeaxW4fnibSJ9791g8BA7Pv5ANByI64WmtR1vU7A2rXcrOn8XvyCEfY0ss1s8NhZP+MA==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@ioredis/commands/1.1.1:
|
/@ioredis/commands/1.1.1:
|
||||||
resolution: {integrity: sha512-fsR4P/ROllzf/7lXYyElUJCheWdTJVJvOTps8v9IWKFATxR61ANOlnoPqhH099xYLrJGpc2ZQ28B3rMeUt5VQg==}
|
resolution: {integrity: sha512-fsR4P/ROllzf/7lXYyElUJCheWdTJVJvOTps8v9IWKFATxR61ANOlnoPqhH099xYLrJGpc2ZQ28B3rMeUt5VQg==}
|
||||||
dev: false
|
dev: false
|
||||||
|
@ -4468,12 +4464,6 @@ packages:
|
||||||
through: 2.3.8
|
through: 2.3.8
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/interactjs/1.10.11:
|
|
||||||
resolution: {integrity: sha512-VPUWsGAOPmrZe1YF7Fq/4AIBBZ+3FikZRS8bpzT6VsAfUuhxl/CKJY73IAiZHd3fz9p174CXErn0Qs81XEFICA==}
|
|
||||||
dependencies:
|
|
||||||
'@interactjs/types': 1.10.11
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/internal-slot/1.0.3:
|
/internal-slot/1.0.3:
|
||||||
resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==}
|
resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
@ -6707,6 +6697,16 @@ packages:
|
||||||
unpipe: 1.0.0
|
unpipe: 1.0.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/re-resizable/6.9.9_react-dom@17.0.2+react@17.0.2:
|
||||||
|
resolution: {integrity: sha512-l+MBlKZffv/SicxDySKEEh42hR6m5bAHfNu3Tvxks2c4Ah+ldnWjfnVRwxo/nxF27SsUsxDS0raAzFuJNKABXA==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.13.1 || ^17.0.0 || ^18.0.0
|
||||||
|
react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0
|
||||||
|
dependencies:
|
||||||
|
react: 17.0.2
|
||||||
|
react-dom: 17.0.2_react@17.0.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/react-countdown/2.3.2_react-dom@17.0.2+react@17.0.2:
|
/react-countdown/2.3.2_react-dom@17.0.2+react@17.0.2:
|
||||||
resolution: {integrity: sha512-Q4SADotHtgOxNWhDdvgupmKVL0pMB9DvoFcxv5AzjsxVhzOVxnttMbAywgqeOdruwEAmnPhOhNv/awAgkwru2w==}
|
resolution: {integrity: sha512-Q4SADotHtgOxNWhDdvgupmKVL0pMB9DvoFcxv5AzjsxVhzOVxnttMbAywgqeOdruwEAmnPhOhNv/awAgkwru2w==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|
Loading…
Reference in New Issue