mirror of
https://github.com/mathuo/dockview
synced 2025-02-16 05:15:45 +00:00
feat: forwardRef the React views
This commit is contained in:
parent
9c547f90b6
commit
62e568265e
@ -49,122 +49,132 @@ export interface IDockviewReactProps {
|
|||||||
disableAutoResizing?: boolean;
|
disableAutoResizing?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DockviewReact: React.FunctionComponent<IDockviewReactProps> = (
|
export const DockviewReact = React.forwardRef(
|
||||||
props: IDockviewReactProps
|
(props: IDockviewReactProps, ref: React.ForwardedRef<HTMLDivElement>) => {
|
||||||
) => {
|
const domRef = React.useRef<HTMLDivElement>(null);
|
||||||
const domRef = React.useRef<HTMLDivElement>(null);
|
const dockviewRef = React.useRef<DockviewComponent>();
|
||||||
const dockviewRef = React.useRef<DockviewComponent>();
|
const [portals, addPortal] = usePortalsLifecycle();
|
||||||
const [portals, addPortal] = usePortalsLifecycle();
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useImperativeHandle(ref, () => domRef.current!, []);
|
||||||
if (props.disableAutoResizing) {
|
|
||||||
return () => {
|
|
||||||
//
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const watcher = watchElementResize(domRef.current!, (entry) => {
|
React.useEffect(() => {
|
||||||
const { width, height } = entry.contentRect;
|
if (props.disableAutoResizing) {
|
||||||
dockviewRef.current?.layout(width, height);
|
return () => {
|
||||||
});
|
//
|
||||||
|
};
|
||||||
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 () => {
|
const watcher = watchElementResize(domRef.current!, (entry) => {
|
||||||
disposable.dispose();
|
const { width, height } = entry.contentRect;
|
||||||
};
|
dockviewRef.current?.layout(width, height);
|
||||||
}, [props.onTabContextMenu]);
|
});
|
||||||
|
|
||||||
return (
|
return () => {
|
||||||
<div
|
watcher.dispose();
|
||||||
className={props.className}
|
};
|
||||||
style={{ height: '100%', width: '100%' }}
|
}, [props.disableAutoResizing]);
|
||||||
ref={domRef}
|
|
||||||
>
|
React.useEffect(() => {
|
||||||
{portals}
|
const factory: GroupPanelFrameworkComponentFactory = {
|
||||||
</div>
|
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';
|
DockviewReact.displayName = 'DockviewComponent';
|
||||||
|
@ -31,70 +31,77 @@ export interface IGridviewReactProps {
|
|||||||
disableAutoResizing?: boolean;
|
disableAutoResizing?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const GridviewReact: React.FunctionComponent<IGridviewReactProps> = (
|
export const GridviewReact = React.forwardRef(
|
||||||
props: IGridviewReactProps
|
(props: IGridviewReactProps, ref: React.ForwardedRef<HTMLDivElement>) => {
|
||||||
) => {
|
const domRef = React.useRef<HTMLDivElement>(null);
|
||||||
const domRef = React.useRef<HTMLDivElement>(null);
|
const gridviewRef = React.useRef<IGridviewComponent>();
|
||||||
const gridviewRef = React.useRef<IGridviewComponent>();
|
const [portals, addPortal] = usePortalsLifecycle();
|
||||||
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 () => {
|
return () => {
|
||||||
//
|
watcher.dispose();
|
||||||
};
|
};
|
||||||
}
|
}, [props.disableAutoResizing]);
|
||||||
|
|
||||||
const watcher = watchElementResize(domRef.current!, (entry) => {
|
React.useEffect(() => {
|
||||||
const { width, height } = entry.contentRect;
|
const element = document.createElement('div');
|
||||||
gridviewRef.current?.layout(width, height);
|
|
||||||
});
|
|
||||||
|
|
||||||
return () => {
|
const gridview = new GridviewComponent(element, {
|
||||||
watcher.dispose();
|
proportionalLayout: !!props.proportionalLayout,
|
||||||
};
|
orientation: props.orientation,
|
||||||
}, [props.disableAutoResizing]);
|
frameworkComponents: props.components,
|
||||||
|
frameworkComponentFactory: {
|
||||||
React.useEffect(() => {
|
createComponent: (id: string, componentId, component) => {
|
||||||
const element = document.createElement('div');
|
return new ReactGridPanelView(
|
||||||
|
id,
|
||||||
const gridview = new GridviewComponent(element, {
|
componentId,
|
||||||
proportionalLayout: !!props.proportionalLayout,
|
component,
|
||||||
orientation: props.orientation,
|
{
|
||||||
frameworkComponents: props.components,
|
addPortal,
|
||||||
frameworkComponentFactory: {
|
}
|
||||||
createComponent: (id: string, componentId, component) => {
|
);
|
||||||
return new ReactGridPanelView(id, componentId, component, {
|
},
|
||||||
addPortal,
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
},
|
styles: props.hideBorders
|
||||||
styles: props.hideBorders
|
? { separatorBorder: 'transparent' }
|
||||||
? { separatorBorder: 'transparent' }
|
: undefined,
|
||||||
: undefined,
|
});
|
||||||
});
|
|
||||||
|
|
||||||
domRef.current?.appendChild(gridview.element);
|
domRef.current?.appendChild(gridview.element);
|
||||||
|
|
||||||
if (props.onReady) {
|
if (props.onReady) {
|
||||||
props.onReady({ api: new GridviewApi(gridview) });
|
props.onReady({ api: new GridviewApi(gridview) });
|
||||||
}
|
}
|
||||||
|
|
||||||
gridviewRef.current = gridview;
|
gridviewRef.current = gridview;
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
gridview.dispose();
|
gridview.dispose();
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={props.className}
|
className={props.className}
|
||||||
style={{ height: '100%', width: '100%' }}
|
style={{ height: '100%', width: '100%' }}
|
||||||
ref={domRef}
|
ref={domRef}
|
||||||
>
|
>
|
||||||
{portals}
|
{portals}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
);
|
||||||
GridviewReact.displayName = 'GridviewComponent';
|
GridviewReact.displayName = 'GridviewComponent';
|
||||||
|
@ -29,81 +29,83 @@ export interface IPaneviewReactProps {
|
|||||||
disableAutoResizing?: boolean;
|
disableAutoResizing?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PaneviewReact: React.FunctionComponent<IPaneviewReactProps> = (
|
export const PaneviewReact = React.forwardRef(
|
||||||
props: IPaneviewReactProps
|
(props: IPaneviewReactProps, ref: React.ForwardedRef<HTMLDivElement>) => {
|
||||||
) => {
|
const domRef = React.useRef<HTMLDivElement>(null);
|
||||||
const domRef = React.useRef<HTMLDivElement>(null);
|
const paneviewRef = React.useRef<IPaneviewComponent>();
|
||||||
const paneviewRef = React.useRef<IPaneviewComponent>();
|
const [portals, addPortal] = usePortalsLifecycle();
|
||||||
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 () => {
|
return () => {
|
||||||
//
|
watcher.dispose();
|
||||||
};
|
};
|
||||||
}
|
}, [props.disableAutoResizing]);
|
||||||
|
|
||||||
const watcher = watchElementResize(domRef.current!, (entry) => {
|
React.useEffect(() => {
|
||||||
const { width, height } = entry.contentRect;
|
const paneview = new PaneviewComponent(domRef.current!, {
|
||||||
paneviewRef.current?.layout(width, height);
|
frameworkComponents: props.components,
|
||||||
});
|
components: {},
|
||||||
|
headerComponents: {},
|
||||||
return () => {
|
headerframeworkComponents: props.headerComponents,
|
||||||
watcher.dispose();
|
frameworkWrapper: {
|
||||||
};
|
header: {
|
||||||
}, [props.disableAutoResizing]);
|
createComponent: (
|
||||||
|
id: string,
|
||||||
React.useEffect(() => {
|
componentId,
|
||||||
const paneview = new PaneviewComponent(domRef.current!, {
|
component: any
|
||||||
frameworkComponents: props.components,
|
) => {
|
||||||
components: {},
|
return new PanePanelSection(id, component, {
|
||||||
headerComponents: {},
|
addPortal,
|
||||||
headerframeworkComponents: props.headerComponents,
|
});
|
||||||
frameworkWrapper: {
|
},
|
||||||
header: {
|
},
|
||||||
createComponent: (
|
body: {
|
||||||
id: string,
|
createComponent: (
|
||||||
componentId,
|
id: string,
|
||||||
component: any
|
componentId,
|
||||||
) => {
|
component: any
|
||||||
return new PanePanelSection(id, component, {
|
) => {
|
||||||
addPortal,
|
return new PanePanelSection(id, component, {
|
||||||
});
|
addPortal,
|
||||||
|
});
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
body: {
|
});
|
||||||
createComponent: (
|
|
||||||
id: string,
|
|
||||||
componentId,
|
|
||||||
component: any
|
|
||||||
) => {
|
|
||||||
return new PanePanelSection(id, component, {
|
|
||||||
addPortal,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (props.onReady) {
|
if (props.onReady) {
|
||||||
props.onReady({ api: new PaneviewApi(paneview) });
|
props.onReady({ api: new PaneviewApi(paneview) });
|
||||||
}
|
}
|
||||||
|
|
||||||
paneviewRef.current = paneview;
|
paneviewRef.current = paneview;
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
paneview.dispose();
|
paneview.dispose();
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={props.className}
|
className={props.className}
|
||||||
style={{ height: '100%', width: '100%' }}
|
style={{ height: '100%', width: '100%' }}
|
||||||
ref={domRef}
|
ref={domRef}
|
||||||
>
|
>
|
||||||
{portals}
|
{portals}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
);
|
||||||
PaneviewReact.displayName = 'PaneviewComponent';
|
PaneviewReact.displayName = 'PaneviewComponent';
|
||||||
|
@ -31,66 +31,72 @@ export interface ISplitviewReactProps {
|
|||||||
disableAutoResizing?: boolean;
|
disableAutoResizing?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SplitviewReact: React.FunctionComponent<ISplitviewReactProps> = (
|
export const SplitviewReact = React.forwardRef(
|
||||||
props: ISplitviewReactProps
|
(props: ISplitviewReactProps, ref: React.ForwardedRef<HTMLDivElement>) => {
|
||||||
) => {
|
const domRef = React.useRef<HTMLDivElement>(null);
|
||||||
const domRef = React.useRef<HTMLDivElement>(null);
|
const splitviewRef = React.useRef<ISplitviewComponent>();
|
||||||
const splitviewRef = React.useRef<ISplitviewComponent>();
|
const [portals, addPortal] = usePortalsLifecycle();
|
||||||
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 () => {
|
return () => {
|
||||||
//
|
watcher.dispose();
|
||||||
};
|
};
|
||||||
}
|
}, [props.disableAutoResizing]);
|
||||||
|
|
||||||
const watcher = watchElementResize(domRef.current!, (entry) => {
|
React.useEffect(() => {
|
||||||
const { width, height } = entry.contentRect;
|
const splitview = new SplitviewComponent(domRef.current!, {
|
||||||
splitviewRef.current?.layout(width, height);
|
orientation: props.orientation,
|
||||||
});
|
frameworkComponents: props.components,
|
||||||
|
frameworkWrapper: {
|
||||||
return () => {
|
createComponent: (
|
||||||
watcher.dispose();
|
id: string,
|
||||||
};
|
componentId,
|
||||||
}, [props.disableAutoResizing]);
|
component: any
|
||||||
|
) => {
|
||||||
React.useEffect(() => {
|
return new ReactPanelView(id, componentId, component, {
|
||||||
const splitview = new SplitviewComponent(domRef.current!, {
|
addPortal,
|
||||||
orientation: props.orientation,
|
});
|
||||||
frameworkComponents: props.components,
|
},
|
||||||
frameworkWrapper: {
|
|
||||||
createComponent: (id: string, componentId, component: any) => {
|
|
||||||
return new ReactPanelView(id, componentId, component, {
|
|
||||||
addPortal,
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
},
|
proportionalLayout: props.proportionalLayout,
|
||||||
proportionalLayout: props.proportionalLayout,
|
styles: props.hideBorders
|
||||||
styles: props.hideBorders
|
? { separatorBorder: 'transparent' }
|
||||||
? { separatorBorder: 'transparent' }
|
: undefined,
|
||||||
: undefined,
|
});
|
||||||
});
|
|
||||||
|
|
||||||
if (props.onReady) {
|
if (props.onReady) {
|
||||||
props.onReady({ api: new SplitviewApi(splitview) });
|
props.onReady({ api: new SplitviewApi(splitview) });
|
||||||
}
|
}
|
||||||
|
|
||||||
splitviewRef.current = splitview;
|
splitviewRef.current = splitview;
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
splitview.dispose();
|
splitview.dispose();
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={props.className}
|
className={props.className}
|
||||||
style={{ height: '100%', width: '100%' }}
|
style={{ height: '100%', width: '100%' }}
|
||||||
ref={domRef}
|
ref={domRef}
|
||||||
>
|
>
|
||||||
{portals}
|
{portals}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
);
|
||||||
SplitviewReact.displayName = 'SplitviewComponent';
|
SplitviewReact.displayName = 'SplitviewComponent';
|
||||||
|
Loading…
Reference in New Issue
Block a user