caplin / FlexLayout

Docking Layout Manager for React
MIT License
919 stars 173 forks source link

Action FlexLayout_MaximizeToggle (onAction) dalayed execution #355

Open Franziskhan opened 1 year ago

Franziskhan commented 1 year ago

Describe the bug

Dear, I'm using your react FlexLayout component and work really well. Great Job!

I have a problem with the event FlexLayout_MaximizeToggle (and also minimize)

I need to trigger the redesign of the components inside pannels when any layout change are applied indeed i need to intercept any action perform by the user on the layout

At the moment i bind a my custom function resizeCharts() on FlexLayout onAction event. In my code I apply the action, force update and than i have a function to reinitialize the chart inside the panel

  function resizeCharts(action) {
    model.doAction(action);
    FLXLayout.current.forceUpdate();
    layoutUpdate();
  }

all action except FlexLayout_MaximizeToggle are commited and exectuted before my layoutUpdate while the FlexLayout_MaximizeToggle is executed later making void the layoutUpdate actions.

Is there any wait to wait for the full execution of the FlexLayout_MaximizeToggle before going ahead with the code?

Thank you Francesco

Your Example Website or App

No response

Steps to Reproduce the Bug or Issue

Just bind the action doAction to a funtion and put a breakboint after the doAction. The layout do not update even with a forceUpdate() when you click on the panel expand button

Expected behavior

the action FlexLayout_MaximizeToggle should be blocking or another event should be triggered after the FlexLayout_MaximizeToggle action

Operating System

any

Browser Type?

chrome

Browser Version

105.0.5195.102

Screenshots or Videos

no screenshot

Additional context

No response

eric-ho-github commented 1 year ago

so, you want to resize your charts whenever the contained tab is resized?

Franziskhan commented 1 year ago

Thank you for your response. You got the point: Flex Layout does that, but in the wrong order. First it executes my function, that resizes my charts, then it resize the panels, making my function call useless.

Franziskhan commented 1 year ago

I kinda solved the issue by using instead of onAction, other triggers like onRenderTab and onModelChange, it work in most cases but not always, so a solution with onAction would be perfect.

eric-ho-github commented 1 year ago

I had a similar problem to yours. My solution was listening to resize and updating the size of my components.

  <ElementResizeListener onResize={this.updateMyChart} />
import React, { useCallback, useEffect, useRef, RefObject } from 'react';

interface Props {
  onResize: (event: Event) => void;
}

export const ElementResizeListener: React.FC<Props> = ({ onResize }) => {
  const rafRef = useRef(0);
  const objectRef: RefObject<HTMLObjectElement> = useRef(null);
  const onResizeRef = useRef(onResize);

  onResizeRef.current = onResize;

  const _onResize = useCallback(
    (e: Event) => {
      if (rafRef.current) {
        cancelAnimationFrame(rafRef.current);
      }
      rafRef.current = requestAnimationFrame(() => {
        onResizeRef.current(e);
      });
    },
    []);

  const onLoad = useCallback(
    () => {
      const obj = objectRef.current;
      if (obj && obj.contentDocument && obj.contentDocument.defaultView) {
        obj.contentDocument.defaultView.addEventListener('resize', _onResize);
      }
    },
    [_onResize]);

  useEffect(
    () => {
      const obj = objectRef.current;

      return () => {
        if (obj && obj.contentDocument && obj.contentDocument.defaultView) {
          obj.contentDocument.defaultView.removeEventListener('resize', _onResize);
        }
      };
    },
    [_onResize]);

  return (
    <object
      onLoad={onLoad}
      ref={objectRef} tabIndex={-1}
      type={'text/html'}
      data={'about:blank'}
      title={' '}
      style={{
        height: '100%',
        left: 0,
        opacity: 0,
        pointerEvents: 'none',
        position: 'absolute',
        top: 0,
        width: '100%',
        zIndex: -1,
      }}
    />
  );
};

export default ElementResizeListener;