diff --git a/demo/src/ui-demo/CodeEditor.tsx b/demo/src/ui-demo/CodeEditor.tsx index 48f4bc2..3958c96 100644 --- a/demo/src/ui-demo/CodeEditor.tsx +++ b/demo/src/ui-demo/CodeEditor.tsx @@ -81,8 +81,7 @@ const IconPane = () => { const SideBar : React.FC<{ wide: boolean, visible: boolean }> = (props) => { return ( - props.visible ? - + @@ -92,8 +91,7 @@ const SideBar : React.FC<{ wide: boolean, visible: boolean }> = (props) => { - : - null + ) } diff --git a/demo/src/ui-demo/Scrollable.tsx b/demo/src/ui-demo/Scrollable.tsx index d3d5bac..5cf1a41 100644 --- a/demo/src/ui-demo/Scrollable.tsx +++ b/demo/src/ui-demo/Scrollable.tsx @@ -7,6 +7,7 @@ export const ScrollableDemo = () => { const [ selectedKey, setSelectedKey ] = React.useState('1'); const [ html, setHtml ] = React.useState(''); const [ loading, setLoading ] = React.useState(true); + const [ sidebarSize, setSidebarSize] = React.useState(250); React.useEffect(() => { (async () => { @@ -23,7 +24,7 @@ export const ScrollableDemo = () => { Header - + { setSidebarSize(newSize);}} handleSize={30}> setSelectedKey(e.key)}> Menu item 1 Menu item 2 diff --git a/react-spaces/package.json b/react-spaces/package.json index e8f355c..9669934 100644 --- a/react-spaces/package.json +++ b/react-spaces/package.json @@ -1,6 +1,6 @@ { "name": "react-spaces", - "version": "0.1.17", + "version": "0.1.18", "main": "dist/index.js", "module": "dist/es/index.js", "types": "dist/index.d.ts", diff --git a/react-spaces/src/Globals/Hooks.ts b/react-spaces/src/Globals/Hooks.ts index b3559b4..2bcab82 100644 --- a/react-spaces/src/Globals/Hooks.ts +++ b/react-spaces/src/Globals/Hooks.ts @@ -14,7 +14,7 @@ export const useSpace = (props: AllProps, divElementRef: React.MutableRefObject< const setState = (stateDelta: Partial) => changeState(prev => ({...prev, ...stateDelta})); const parentContext = React.useContext(SpaceContext); - const currentZIndex = props.zIndex || React.useContext(SpaceLayerContext) || 0; + const currentZIndex = props.zIndex || parentContext || 0; // Deal with property changes to size / anchoring React.useEffect(() => { @@ -147,7 +147,7 @@ export const useSpace = (props: AllProps, divElementRef: React.MutableRefObject< const handleSize = props.handleSize || 5; const overlayHandle = props.overlayHandle !== undefined ? props.overlayHandle : true; - const resize = applyResize(props, state, setState, parentContext, handleSize); + const resize = applyResize(props, state, setState, parentContext, handleSize, divElementRef); const innerStyle = { diff --git a/react-spaces/src/Globals/Types.ts b/react-spaces/src/Globals/Types.ts index 2b9f7c8..529e96f 100644 --- a/react-spaces/src/Globals/Types.ts +++ b/react-spaces/src/Globals/Types.ts @@ -95,14 +95,18 @@ export interface IResizableProps { handleSize?: number, overlayHandle?: boolean, minimumSize?: number, - maximumSize?: number + maximumSize?: number, + onResizeStart?: () => void, + onResizeEnd?: (newSize: number) => void } export const resizableProps = { handleSize: PropTypes.number, overlayHandle: PropTypes.bool, minimumSize: PropTypes.number, - maximumSize: PropTypes.number + maximumSize: PropTypes.number, + onResizeStart: PropTypes.func, + onResizeEnd: PropTypes.func } export interface IPositionedProps { diff --git a/react-spaces/src/Globals/Utils.tsx b/react-spaces/src/Globals/Utils.tsx index 1b59ca6..93ca2b8 100644 --- a/react-spaces/src/Globals/Utils.tsx +++ b/react-spaces/src/Globals/Utils.tsx @@ -89,7 +89,13 @@ export const createContext = ( return context; } -export const applyResize = (props: AllProps, state: IState, setState: (stateDelta: Partial) => void, parentContext: ISpaceContext | null, handleSize: number) => { +export const applyResize = ( + props: AllProps, + state: IState, + setState: (stateDelta: Partial) => void, + parentContext: ISpaceContext | null, + handleSize: number, + divElementRef: React.MutableRefObject) => { if (parentContext && props.anchor && props.resizable) { const resizeType = AnchorToResizeTypeMap[props.anchor]; @@ -108,6 +114,16 @@ export const applyResize = (props: AllProps, state: IState, setState: (stateDelt onResize={(adjustedSize) => { setState({ adjustedSize: adjustedSize }); parentContext.updateSpaceTakerAdjustedSize(state.id, adjustedSize); + }} + onResizeStart={() => props.onResizeStart && props.onResizeStart()} + onResizeEnd={() => { + if (divElementRef.current) + { + const currentRect = divElementRef.current.getBoundingClientRect(); + props.onResizeEnd && props.onResizeEnd( + resizeType === ResizeType.Left || resizeType === ResizeType.Right ? currentRect.width : currentRect.height + ); + } }} />, resizeType: resizeType diff --git a/react-spaces/src/Resizable.tsx b/react-spaces/src/Resizable.tsx index f755889..6329262 100644 --- a/react-spaces/src/Resizable.tsx +++ b/react-spaces/src/Resizable.tsx @@ -11,16 +11,18 @@ interface IProps { height?: number, minimumAdjust: number, maximumAdjust?: number, - onResize: (adjustedSize: number) => void + onResize: (adjustedSize: number) => void, + onResizeStart?: () => void, + onResizeEnd?: () => void } export const Resizable : React.FC = (props) => { const resize = (originalX: number, originalY: number, x: number, y: number) => { const adjustmentX = - Math.min( - Math.max(props.type === ResizeType.Left ? originalX - x : x - originalX, props.minimumAdjust), - props.maximumAdjust || 999999 - ); + Math.min( + Math.max(props.type === ResizeType.Left ? originalX - x : x - originalX, props.minimumAdjust), + props.maximumAdjust || 999999 + ); const adjustmentY = Math.min( Math.max(props.type === ResizeType.Top ? originalY - y : y - originalY, props.minimumAdjust), @@ -36,27 +38,45 @@ export const Resizable : React.FC = (props) => { const startTouchResize = (e: React.TouchEvent) => { const originalTouchX = props.type === ResizeType.Left ? e.touches[0].pageX + props.adjustedSize : e.touches[0].pageX - props.adjustedSize; const originalTouchY = props.type === ResizeType.Top ? e.touches[0].pageY + props.adjustedSize : e.touches[0].pageY - props.adjustedSize; + let resizing = true; + let moved = false; - const touchResize = (e: TouchEvent) => resize(originalTouchX, originalTouchY, e.touches[0].pageX, e.touches[0].pageY); + const touchResize = (e: TouchEvent) => resizing && resize(originalTouchX, originalTouchY, e.touches[0].pageX, e.touches[0].pageY); const debouncedTouchResize = debounce(touchResize, 10); - const withPreventDefault = (e: TouchEvent) => { e.preventDefault(); e.stopImmediatePropagation(); debouncedTouchResize(e); }; + const withPreventDefault = (e: TouchEvent) => { moved = true; e.preventDefault(); e.stopImmediatePropagation(); debouncedTouchResize(e); }; + const removeListener = () => { + resizing = false; + window.removeEventListener('touchmove', withPreventDefault); + window.removeEventListener('touchend', removeListener); + moved && props.onResizeEnd && props.onResizeEnd(); + }; window.addEventListener('touchmove', withPreventDefault); - window.addEventListener('touchend', () => window.removeEventListener('touchmove', withPreventDefault)); + window.addEventListener('touchend', removeListener); e.preventDefault(); e.stopPropagation(); + props.onResizeStart && props.onResizeStart(); } const startResize = (e: React.MouseEvent) => { const originalMouseX = props.type === ResizeType.Left ? e.pageX + props.adjustedSize : e.pageX - props.adjustedSize; const originalMouseY = props.type === ResizeType.Top ? e.pageY + props.adjustedSize : e.pageY - props.adjustedSize; + let resizing = true; + let moved = false; - const mouseResize = (e: MouseEvent) => resize(originalMouseX, originalMouseY, e.pageX, e.pageY); + const mouseResize = (e: MouseEvent) => resizing && resize(originalMouseX, originalMouseY, e.pageX, e.pageY); const debouncedMouseResize = debounce(mouseResize, 10); - const withPreventDefault = (e: MouseEvent) => { e.preventDefault(); e.stopImmediatePropagation(); debouncedMouseResize(e); }; + const withPreventDefault = (e: MouseEvent) => { moved = true; e.preventDefault(); e.stopImmediatePropagation(); debouncedMouseResize(e); }; + const removeListener = () => { + resizing = false; + window.removeEventListener('mousemove', withPreventDefault); + window.removeEventListener('mouseup', removeListener); + moved && props.onResizeEnd && props.onResizeEnd(); + }; window.addEventListener('mousemove', withPreventDefault); - window.addEventListener('mouseup', () => window.removeEventListener('mousemove', withPreventDefault)); + window.addEventListener('mouseup', removeListener); e.preventDefault(); e.stopPropagation(); + props.onResizeStart && props.onResizeStart(); } return (