feat: forwardRef the React views

This commit is contained in:
mathuo 2021-03-25 21:42:54 +00:00
parent 9c547f90b6
commit 62e568265e
4 changed files with 313 additions and 288 deletions

View File

@ -49,122 +49,132 @@ export interface IDockviewReactProps {
disableAutoResizing?: boolean;
}
export const DockviewReact: React.FunctionComponent<IDockviewReactProps> = (
props: IDockviewReactProps
) => {
const domRef = React.useRef<HTMLDivElement>(null);
const dockviewRef = React.useRef<DockviewComponent>();
const [portals, addPortal] = usePortalsLifecycle();
export const DockviewReact = React.forwardRef(
(props: IDockviewReactProps, ref: React.ForwardedRef<HTMLDivElement>) => {
const domRef = React.useRef<HTMLDivElement>(null);
const dockviewRef = React.useRef<DockviewComponent>();
const [portals, addPortal] = usePortalsLifecycle();
React.useEffect(() => {
if (props.disableAutoResizing) {
return () => {
//
};
}
React.useImperativeHandle(ref, () => domRef.current!, []);
const watcher = watchElementResize(domRef.current!, (entry) => {
const { width, height } = entry.contentRect;
dockviewRef.current?.layout(width, height);
});
return () => {
watcher.dispose();
};
}, [props.disableAutoResizing]);
React.useEffect(() => {
const factory: GroupPanelFrameworkComponentFactory = {
content: {
createComponent: (
id: string,
componentId: string,
component: React.FunctionComponent<IGroupPanelBaseProps>
): IContentRenderer => {
return new ReactPanelContentPart(componentId, component, {
addPortal,
});
},
},
tab: {
createComponent: (
id: string,
componentId: string,
component: React.FunctionComponent<IGroupPanelBaseProps>
): ITabRenderer => {
return new ReactPanelHeaderPart(componentId, component, {
addPortal,
});
},
},
watermark: {
createComponent: (
id: string,
componentId: string,
component: React.FunctionComponent<{}>
) => {
return new ReactWatermarkPart(componentId, component, {
addPortal,
});
},
},
};
const element = document.createElement('div');
const dockview = new DockviewComponent(element, {
frameworkComponentFactory: factory,
frameworkComponents: props.components,
frameworkTabComponents: props.tabComponents,
tabHeight: props.tabHeight,
debug: props.debug,
enableExternalDragEvents: props.enableExternalDragEvents,
watermarkFrameworkComponent: props.watermarkComponent,
styles: props.hideBorders
? { separatorBorder: 'transparent' }
: undefined,
});
domRef.current?.appendChild(dockview.element);
dockview.deserializer = new ReactPanelDeserialzier(dockview);
if (props.onReady) {
props.onReady({ api: new DockviewApi(dockview) });
}
dockviewRef.current = dockview;
return () => {
dockview.dispose();
};
}, []);
React.useEffect(() => {
if (!props.onTabContextMenu || !dockviewRef.current) {
return () => {
//noop
};
}
const disposable = dockviewRef.current.onTabContextMenu((event) => {
if (props.onTabContextMenu) {
props.onTabContextMenu(event);
React.useEffect(() => {
if (props.disableAutoResizing) {
return () => {
//
};
}
});
return () => {
disposable.dispose();
};
}, [props.onTabContextMenu]);
const watcher = watchElementResize(domRef.current!, (entry) => {
const { width, height } = entry.contentRect;
dockviewRef.current?.layout(width, height);
});
return (
<div
className={props.className}
style={{ height: '100%', width: '100%' }}
ref={domRef}
>
{portals}
</div>
);
};
return () => {
watcher.dispose();
};
}, [props.disableAutoResizing]);
React.useEffect(() => {
const factory: GroupPanelFrameworkComponentFactory = {
content: {
createComponent: (
id: string,
componentId: string,
component: React.FunctionComponent<IGroupPanelBaseProps>
): IContentRenderer => {
return new ReactPanelContentPart(
componentId,
component,
{
addPortal,
}
);
},
},
tab: {
createComponent: (
id: string,
componentId: string,
component: React.FunctionComponent<IGroupPanelBaseProps>
): ITabRenderer => {
return new ReactPanelHeaderPart(
componentId,
component,
{
addPortal,
}
);
},
},
watermark: {
createComponent: (
id: string,
componentId: string,
component: React.FunctionComponent<{}>
) => {
return new ReactWatermarkPart(componentId, component, {
addPortal,
});
},
},
};
const element = document.createElement('div');
const dockview = new DockviewComponent(element, {
frameworkComponentFactory: factory,
frameworkComponents: props.components,
frameworkTabComponents: props.tabComponents,
tabHeight: props.tabHeight,
debug: props.debug,
enableExternalDragEvents: props.enableExternalDragEvents,
watermarkFrameworkComponent: props.watermarkComponent,
styles: props.hideBorders
? { separatorBorder: 'transparent' }
: undefined,
});
domRef.current?.appendChild(dockview.element);
dockview.deserializer = new ReactPanelDeserialzier(dockview);
if (props.onReady) {
props.onReady({ api: new DockviewApi(dockview) });
}
dockviewRef.current = dockview;
return () => {
dockview.dispose();
};
}, []);
React.useEffect(() => {
if (!props.onTabContextMenu || !dockviewRef.current) {
return () => {
//noop
};
}
const disposable = dockviewRef.current.onTabContextMenu((event) => {
if (props.onTabContextMenu) {
props.onTabContextMenu(event);
}
});
return () => {
disposable.dispose();
};
}, [props.onTabContextMenu]);
return (
<div
className={props.className}
style={{ height: '100%', width: '100%' }}
ref={domRef}
>
{portals}
</div>
);
}
);
DockviewReact.displayName = 'DockviewComponent';

View File

@ -31,70 +31,77 @@ export interface IGridviewReactProps {
disableAutoResizing?: boolean;
}
export const GridviewReact: React.FunctionComponent<IGridviewReactProps> = (
props: IGridviewReactProps
) => {
const domRef = React.useRef<HTMLDivElement>(null);
const gridviewRef = React.useRef<IGridviewComponent>();
const [portals, addPortal] = usePortalsLifecycle();
export const GridviewReact = React.forwardRef(
(props: IGridviewReactProps, ref: React.ForwardedRef<HTMLDivElement>) => {
const domRef = React.useRef<HTMLDivElement>(null);
const gridviewRef = React.useRef<IGridviewComponent>();
const [portals, addPortal] = usePortalsLifecycle();
React.useImperativeHandle(ref, () => domRef.current!, []);
React.useEffect(() => {
if (props.disableAutoResizing) {
return () => {
//
};
}
const watcher = watchElementResize(domRef.current!, (entry) => {
const { width, height } = entry.contentRect;
gridviewRef.current?.layout(width, height);
});
React.useEffect(() => {
if (props.disableAutoResizing) {
return () => {
//
watcher.dispose();
};
}
}, [props.disableAutoResizing]);
const watcher = watchElementResize(domRef.current!, (entry) => {
const { width, height } = entry.contentRect;
gridviewRef.current?.layout(width, height);
});
React.useEffect(() => {
const element = document.createElement('div');
return () => {
watcher.dispose();
};
}, [props.disableAutoResizing]);
React.useEffect(() => {
const element = document.createElement('div');
const gridview = new GridviewComponent(element, {
proportionalLayout: !!props.proportionalLayout,
orientation: props.orientation,
frameworkComponents: props.components,
frameworkComponentFactory: {
createComponent: (id: string, componentId, component) => {
return new ReactGridPanelView(id, componentId, component, {
addPortal,
});
const gridview = new GridviewComponent(element, {
proportionalLayout: !!props.proportionalLayout,
orientation: props.orientation,
frameworkComponents: props.components,
frameworkComponentFactory: {
createComponent: (id: string, componentId, component) => {
return new ReactGridPanelView(
id,
componentId,
component,
{
addPortal,
}
);
},
},
},
styles: props.hideBorders
? { separatorBorder: 'transparent' }
: undefined,
});
styles: props.hideBorders
? { separatorBorder: 'transparent' }
: undefined,
});
domRef.current?.appendChild(gridview.element);
domRef.current?.appendChild(gridview.element);
if (props.onReady) {
props.onReady({ api: new GridviewApi(gridview) });
}
if (props.onReady) {
props.onReady({ api: new GridviewApi(gridview) });
}
gridviewRef.current = gridview;
gridviewRef.current = gridview;
return () => {
gridview.dispose();
};
}, []);
return () => {
gridview.dispose();
};
}, []);
return (
<div
className={props.className}
style={{ height: '100%', width: '100%' }}
ref={domRef}
>
{portals}
</div>
);
};
return (
<div
className={props.className}
style={{ height: '100%', width: '100%' }}
ref={domRef}
>
{portals}
</div>
);
}
);
GridviewReact.displayName = 'GridviewComponent';

View File

@ -29,81 +29,83 @@ export interface IPaneviewReactProps {
disableAutoResizing?: boolean;
}
export const PaneviewReact: React.FunctionComponent<IPaneviewReactProps> = (
props: IPaneviewReactProps
) => {
const domRef = React.useRef<HTMLDivElement>(null);
const paneviewRef = React.useRef<IPaneviewComponent>();
const [portals, addPortal] = usePortalsLifecycle();
export const PaneviewReact = React.forwardRef(
(props: IPaneviewReactProps, ref: React.ForwardedRef<HTMLDivElement>) => {
const domRef = React.useRef<HTMLDivElement>(null);
const paneviewRef = React.useRef<IPaneviewComponent>();
const [portals, addPortal] = usePortalsLifecycle();
React.useImperativeHandle(ref, () => domRef.current!, []);
React.useEffect(() => {
if (props.disableAutoResizing) {
return () => {
//
};
}
const watcher = watchElementResize(domRef.current!, (entry) => {
const { width, height } = entry.contentRect;
paneviewRef.current?.layout(width, height);
});
React.useEffect(() => {
if (props.disableAutoResizing) {
return () => {
//
watcher.dispose();
};
}
}, [props.disableAutoResizing]);
const watcher = watchElementResize(domRef.current!, (entry) => {
const { width, height } = entry.contentRect;
paneviewRef.current?.layout(width, height);
});
return () => {
watcher.dispose();
};
}, [props.disableAutoResizing]);
React.useEffect(() => {
const paneview = new PaneviewComponent(domRef.current!, {
frameworkComponents: props.components,
components: {},
headerComponents: {},
headerframeworkComponents: props.headerComponents,
frameworkWrapper: {
header: {
createComponent: (
id: string,
componentId,
component: any
) => {
return new PanePanelSection(id, component, {
addPortal,
});
React.useEffect(() => {
const paneview = new PaneviewComponent(domRef.current!, {
frameworkComponents: props.components,
components: {},
headerComponents: {},
headerframeworkComponents: props.headerComponents,
frameworkWrapper: {
header: {
createComponent: (
id: string,
componentId,
component: any
) => {
return new PanePanelSection(id, component, {
addPortal,
});
},
},
body: {
createComponent: (
id: string,
componentId,
component: any
) => {
return new PanePanelSection(id, component, {
addPortal,
});
},
},
},
body: {
createComponent: (
id: string,
componentId,
component: any
) => {
return new PanePanelSection(id, component, {
addPortal,
});
},
},
},
});
});
if (props.onReady) {
props.onReady({ api: new PaneviewApi(paneview) });
}
if (props.onReady) {
props.onReady({ api: new PaneviewApi(paneview) });
}
paneviewRef.current = paneview;
paneviewRef.current = paneview;
return () => {
paneview.dispose();
};
}, []);
return () => {
paneview.dispose();
};
}, []);
return (
<div
className={props.className}
style={{ height: '100%', width: '100%' }}
ref={domRef}
>
{portals}
</div>
);
};
return (
<div
className={props.className}
style={{ height: '100%', width: '100%' }}
ref={domRef}
>
{portals}
</div>
);
}
);
PaneviewReact.displayName = 'PaneviewComponent';

View File

@ -31,66 +31,72 @@ export interface ISplitviewReactProps {
disableAutoResizing?: boolean;
}
export const SplitviewReact: React.FunctionComponent<ISplitviewReactProps> = (
props: ISplitviewReactProps
) => {
const domRef = React.useRef<HTMLDivElement>(null);
const splitviewRef = React.useRef<ISplitviewComponent>();
const [portals, addPortal] = usePortalsLifecycle();
export const SplitviewReact = React.forwardRef(
(props: ISplitviewReactProps, ref: React.ForwardedRef<HTMLDivElement>) => {
const domRef = React.useRef<HTMLDivElement>(null);
const splitviewRef = React.useRef<ISplitviewComponent>();
const [portals, addPortal] = usePortalsLifecycle();
React.useImperativeHandle(ref, () => domRef.current!, []);
React.useEffect(() => {
if (props.disableAutoResizing) {
return () => {
//
};
}
const watcher = watchElementResize(domRef.current!, (entry) => {
const { width, height } = entry.contentRect;
splitviewRef.current?.layout(width, height);
});
React.useEffect(() => {
if (props.disableAutoResizing) {
return () => {
//
watcher.dispose();
};
}
}, [props.disableAutoResizing]);
const watcher = watchElementResize(domRef.current!, (entry) => {
const { width, height } = entry.contentRect;
splitviewRef.current?.layout(width, height);
});
return () => {
watcher.dispose();
};
}, [props.disableAutoResizing]);
React.useEffect(() => {
const splitview = new SplitviewComponent(domRef.current!, {
orientation: props.orientation,
frameworkComponents: props.components,
frameworkWrapper: {
createComponent: (id: string, componentId, component: any) => {
return new ReactPanelView(id, componentId, component, {
addPortal,
});
React.useEffect(() => {
const splitview = new SplitviewComponent(domRef.current!, {
orientation: props.orientation,
frameworkComponents: props.components,
frameworkWrapper: {
createComponent: (
id: string,
componentId,
component: any
) => {
return new ReactPanelView(id, componentId, component, {
addPortal,
});
},
},
},
proportionalLayout: props.proportionalLayout,
styles: props.hideBorders
? { separatorBorder: 'transparent' }
: undefined,
});
proportionalLayout: props.proportionalLayout,
styles: props.hideBorders
? { separatorBorder: 'transparent' }
: undefined,
});
if (props.onReady) {
props.onReady({ api: new SplitviewApi(splitview) });
}
if (props.onReady) {
props.onReady({ api: new SplitviewApi(splitview) });
}
splitviewRef.current = splitview;
splitviewRef.current = splitview;
return () => {
splitview.dispose();
};
}, []);
return () => {
splitview.dispose();
};
}, []);
return (
<div
className={props.className}
style={{ height: '100%', width: '100%' }}
ref={domRef}
>
{portals}
</div>
);
};
return (
<div
className={props.className}
style={{ height: '100%', width: '100%' }}
ref={domRef}
>
{portals}
</div>
);
}
);
SplitviewReact.displayName = 'SplitviewComponent';