Skip to content

Commit 94cf413

Browse files
authored
Merge pull request #41 from aeagle/feature/32-resize-events
Added final size to resizeEnd event
2 parents 017d086 + 078ad42 commit 94cf413

File tree

7 files changed

+61
-22
lines changed

7 files changed

+61
-22
lines changed

demo/src/ui-demo/CodeEditor.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,7 @@ const IconPane = () => {
8181

8282
const SideBar : React.FC<{ wide: boolean, visible: boolean }> = (props) => {
8383
return (
84-
props.visible ?
85-
<Space.LeftResizable order={2} className="side-bar" size={props.wide ? 500 : 300} handleSize={2} overlayHandle={false} style={{ backgroundColor: '#252526' }}>
84+
<Space.LeftResizable order={2} className="side-bar" size={props.visible ? (props.wide ? 500 : 300) : 0} handleSize={2} overlayHandle={false} style={{ backgroundColor: '#252526' }}>
8685
<SideBarPane order={1} title="Open editors" height={200}>
8786

8887
</SideBarPane>
@@ -92,8 +91,7 @@ const SideBar : React.FC<{ wide: boolean, visible: boolean }> = (props) => {
9291
<SideBarPane fill={true} title="Outline">
9392

9493
</SideBarPane>
95-
</Space.LeftResizable> :
96-
null
94+
</Space.LeftResizable>
9795
)
9896
}
9997

demo/src/ui-demo/Scrollable.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export const ScrollableDemo = () => {
77
const [ selectedKey, setSelectedKey ] = React.useState('1');
88
const [ html, setHtml ] = React.useState('');
99
const [ loading, setLoading ] = React.useState(true);
10+
const [ sidebarSize, setSidebarSize] = React.useState(250);
1011

1112
React.useEffect(() => {
1213
(async () => {
@@ -23,7 +24,7 @@ export const ScrollableDemo = () => {
2324
Header
2425
</Space.Top>
2526
<Space.Fill>
26-
<Space.LeftResizable as="aside" size="20%" handleSize={30}>
27+
<Space.LeftResizable as="aside" size={sidebarSize} onResizeEnd={(newSize) => { setSidebarSize(newSize);}} handleSize={30}>
2728
<Menu defaultSelectedKeys={[ selectedKey ]} onSelect={e => setSelectedKey(e.key)}>
2829
<Menu.Item key="1">Menu item 1</Menu.Item>
2930
<Menu.Item key="2">Menu item 2</Menu.Item>

react-spaces/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-spaces",
3-
"version": "0.1.17",
3+
"version": "0.1.18",
44
"main": "dist/index.js",
55
"module": "dist/es/index.js",
66
"types": "dist/index.d.ts",

react-spaces/src/Globals/Hooks.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export const useSpace = (props: AllProps, divElementRef: React.MutableRefObject<
1414
const setState = (stateDelta: Partial<IState>) => changeState(prev => ({...prev, ...stateDelta}));
1515

1616
const parentContext = React.useContext(SpaceContext);
17-
const currentZIndex = props.zIndex || React.useContext(SpaceLayerContext) || 0;
17+
const currentZIndex = props.zIndex || parentContext || 0;
1818

1919
// Deal with property changes to size / anchoring
2020
React.useEffect(() => {
@@ -147,7 +147,7 @@ export const useSpace = (props: AllProps, divElementRef: React.MutableRefObject<
147147
const handleSize = props.handleSize || 5;
148148
const overlayHandle = props.overlayHandle !== undefined ? props.overlayHandle : true;
149149

150-
const resize = applyResize(props, state, setState, parentContext, handleSize);
150+
const resize = applyResize(props, state, setState, parentContext, handleSize, divElementRef);
151151

152152
const innerStyle =
153153
{

react-spaces/src/Globals/Types.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,18 @@ export interface IResizableProps {
9595
handleSize?: number,
9696
overlayHandle?: boolean,
9797
minimumSize?: number,
98-
maximumSize?: number
98+
maximumSize?: number,
99+
onResizeStart?: () => void,
100+
onResizeEnd?: (newSize: number) => void
99101
}
100102

101103
export const resizableProps = {
102104
handleSize: PropTypes.number,
103105
overlayHandle: PropTypes.bool,
104106
minimumSize: PropTypes.number,
105-
maximumSize: PropTypes.number
107+
maximumSize: PropTypes.number,
108+
onResizeStart: PropTypes.func,
109+
onResizeEnd: PropTypes.func
106110
}
107111

108112
export interface IPositionedProps {

react-spaces/src/Globals/Utils.tsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,13 @@ export const createContext = (
8989
return context;
9090
}
9191

92-
export const applyResize = (props: AllProps, state: IState, setState: (stateDelta: Partial<IState>) => void, parentContext: ISpaceContext | null, handleSize: number) => {
92+
export const applyResize = (
93+
props: AllProps,
94+
state: IState,
95+
setState: (stateDelta: Partial<IState>) => void,
96+
parentContext: ISpaceContext | null,
97+
handleSize: number,
98+
divElementRef: React.MutableRefObject<HTMLElement | undefined>) => {
9399

94100
if (parentContext && props.anchor && props.resizable) {
95101
const resizeType = AnchorToResizeTypeMap[props.anchor];
@@ -108,6 +114,16 @@ export const applyResize = (props: AllProps, state: IState, setState: (stateDelt
108114
onResize={(adjustedSize) => {
109115
setState({ adjustedSize: adjustedSize });
110116
parentContext.updateSpaceTakerAdjustedSize(state.id, adjustedSize);
117+
}}
118+
onResizeStart={() => props.onResizeStart && props.onResizeStart()}
119+
onResizeEnd={() => {
120+
if (divElementRef.current)
121+
{
122+
const currentRect = divElementRef.current.getBoundingClientRect();
123+
props.onResizeEnd && props.onResizeEnd(
124+
resizeType === ResizeType.Left || resizeType === ResizeType.Right ? currentRect.width : currentRect.height
125+
);
126+
}
111127
}} />,
112128
resizeType:
113129
resizeType

react-spaces/src/Resizable.tsx

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,18 @@ interface IProps {
1111
height?: number,
1212
minimumAdjust: number,
1313
maximumAdjust?: number,
14-
onResize: (adjustedSize: number) => void
14+
onResize: (adjustedSize: number) => void,
15+
onResizeStart?: () => void,
16+
onResizeEnd?: () => void
1517
}
1618

1719
export const Resizable : React.FC<IProps> = (props) => {
1820
const resize = (originalX: number, originalY: number, x: number, y: number) => {
1921
const adjustmentX =
20-
Math.min(
21-
Math.max(props.type === ResizeType.Left ? originalX - x : x - originalX, props.minimumAdjust),
22-
props.maximumAdjust || 999999
23-
);
22+
Math.min(
23+
Math.max(props.type === ResizeType.Left ? originalX - x : x - originalX, props.minimumAdjust),
24+
props.maximumAdjust || 999999
25+
);
2426
const adjustmentY =
2527
Math.min(
2628
Math.max(props.type === ResizeType.Top ? originalY - y : y - originalY, props.minimumAdjust),
@@ -36,27 +38,45 @@ export const Resizable : React.FC<IProps> = (props) => {
3638
const startTouchResize = (e: React.TouchEvent<HTMLDivElement>) => {
3739
const originalTouchX = props.type === ResizeType.Left ? e.touches[0].pageX + props.adjustedSize : e.touches[0].pageX - props.adjustedSize;
3840
const originalTouchY = props.type === ResizeType.Top ? e.touches[0].pageY + props.adjustedSize : e.touches[0].pageY - props.adjustedSize;
41+
let resizing = true;
42+
let moved = false;
3943

40-
const touchResize = (e: TouchEvent) => resize(originalTouchX, originalTouchY, e.touches[0].pageX, e.touches[0].pageY);
44+
const touchResize = (e: TouchEvent) => resizing && resize(originalTouchX, originalTouchY, e.touches[0].pageX, e.touches[0].pageY);
4145
const debouncedTouchResize = debounce<typeof touchResize>(touchResize, 10);
42-
const withPreventDefault = (e: TouchEvent) => { e.preventDefault(); e.stopImmediatePropagation(); debouncedTouchResize(e); };
46+
const withPreventDefault = (e: TouchEvent) => { moved = true; e.preventDefault(); e.stopImmediatePropagation(); debouncedTouchResize(e); };
47+
const removeListener = () => {
48+
resizing = false;
49+
window.removeEventListener('touchmove', withPreventDefault);
50+
window.removeEventListener('touchend', removeListener);
51+
moved && props.onResizeEnd && props.onResizeEnd();
52+
};
4353
window.addEventListener('touchmove', withPreventDefault);
44-
window.addEventListener('touchend', () => window.removeEventListener('touchmove', withPreventDefault));
54+
window.addEventListener('touchend', removeListener);
4555
e.preventDefault();
4656
e.stopPropagation();
57+
props.onResizeStart && props.onResizeStart();
4758
}
4859

4960
const startResize = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
5061
const originalMouseX = props.type === ResizeType.Left ? e.pageX + props.adjustedSize : e.pageX - props.adjustedSize;
5162
const originalMouseY = props.type === ResizeType.Top ? e.pageY + props.adjustedSize : e.pageY - props.adjustedSize;
63+
let resizing = true;
64+
let moved = false;
5265

53-
const mouseResize = (e: MouseEvent) => resize(originalMouseX, originalMouseY, e.pageX, e.pageY);
66+
const mouseResize = (e: MouseEvent) => resizing && resize(originalMouseX, originalMouseY, e.pageX, e.pageY);
5467
const debouncedMouseResize = debounce<typeof mouseResize>(mouseResize, 10);
55-
const withPreventDefault = (e: MouseEvent) => { e.preventDefault(); e.stopImmediatePropagation(); debouncedMouseResize(e); };
68+
const withPreventDefault = (e: MouseEvent) => { moved = true; e.preventDefault(); e.stopImmediatePropagation(); debouncedMouseResize(e); };
69+
const removeListener = () => {
70+
resizing = false;
71+
window.removeEventListener('mousemove', withPreventDefault);
72+
window.removeEventListener('mouseup', removeListener);
73+
moved && props.onResizeEnd && props.onResizeEnd();
74+
};
5675
window.addEventListener('mousemove', withPreventDefault);
57-
window.addEventListener('mouseup', () => window.removeEventListener('mousemove', withPreventDefault));
76+
window.addEventListener('mouseup', removeListener);
5877
e.preventDefault();
5978
e.stopPropagation();
79+
props.onResizeStart && props.onResizeStart();
6080
}
6181

6282
return (

0 commit comments

Comments
 (0)