feat: autoresize views

This commit is contained in:
mathuo 2020-12-20 20:18:48 +00:00
parent 7d21f9f19e
commit 64c24dca55
9 changed files with 120 additions and 4 deletions

View File

@ -13,9 +13,10 @@ module.exports = {
collectCoverageFrom:[
"<rootDir>/packages/splitview/src/**/*.{js,jsx,ts,tsx}",
],
setupFiles: ["<rootDir>/packages/splitview/src/__tests__/__mocks__/resizeObserver.js"],
coveragePathIgnorePatterns: [
"/node_modules/",
"<rootDir>packages/splitview/src/__tests__/",
],
modulePathIgnorePatterns: ["<rootDir>/packages/splitview/src/__tests__/__mocks__",],
coverageDirectory: "coverage"
}

View File

@ -620,6 +620,11 @@
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
"dev": true
},
"resize-observer-polyfill": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
},
"resolve": {
"version": "1.17.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",

View File

@ -59,5 +59,8 @@
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
},
"dependencies": {
"resize-observer-polyfill": "^1.5.1"
}
}

View File

@ -0,0 +1,8 @@
jest.mock('resize-observer-polyfill', () => ({
__esModule: true,
default: jest.fn().mockImplementation(() => ({
observe: jest.fn(),
unobserve: jest.fn(),
disconnect: jest.fn(),
})),
}));

View File

@ -5,6 +5,26 @@ import {
addDisposableWindowListener,
} from './events';
import { IDisposable, CompositeDisposable } from './lifecycle';
import ResizeObserver from 'resize-observer-polyfill';
export function watchElementResize(
element: HTMLElement,
cb: (entry: ResizeObserverEntry) => void
): IDisposable {
const observer = new ResizeObserver((entires) => {
const element = entires[0];
cb(element);
});
observer.observe(element);
return {
dispose: () => {
observer.unobserve(element);
observer.disconnect();
},
};
}
export function isHTMLElement(o: any): o is HTMLElement {
if (typeof HTMLElement === 'object') {

View File

@ -16,6 +16,7 @@ import { DockviewApi } from '../../api/component.api';
import { ReactWatermarkPart } from './reactWatermarkPart';
import { PanelCollection } from '../types';
import { IDisposable } from '../../lifecycle';
import { watchElementResize } from '../../dom';
export interface ActionsbarReference<P> extends IDisposable {
update(params: Partial<P>): void;
@ -56,6 +57,7 @@ export interface IDockviewReactProps {
onTabContextMenu?: (event: TabContextMenuEvent) => void;
hideBorders?: boolean;
className?: string;
disableAutoResizing?: boolean;
}
export const DockviewReact: React.FunctionComponent<IDockviewReactProps> = (
@ -63,9 +65,25 @@ export const DockviewReact: React.FunctionComponent<IDockviewReactProps> = (
) => {
const domRef = React.useRef<HTMLDivElement>(null);
const dockviewRef = React.useRef<DockviewComponent>();
const [portals, addPortal] = usePortalsLifecycle();
React.useEffect(() => {
if (props.disableAutoResizing) {
return () => {
//
};
}
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: {
@ -121,7 +139,7 @@ export const DockviewReact: React.FunctionComponent<IDockviewReactProps> = (
domRef.current?.appendChild(dockview.element);
dockview.deserializer = new ReactPanelDeserialzier(dockview);
dockview.resizeToFit();
// dockview.resizeToFit();
if (props.onReady) {
props.onReady({ api: new DockviewApi(dockview) });

View File

@ -9,6 +9,7 @@ import { ReactGridPanelView } from './view';
import { usePortalsLifecycle } from '../react';
import { GridviewApi } from '../../api/component.api';
import { PanelCollection } from '../types';
import { watchElementResize } from '../../dom';
export interface GridviewReadyEvent {
api: GridviewApi;
@ -27,6 +28,7 @@ export interface IGridviewReactProps {
hideBorders?: boolean;
className?: string;
proportionalLayout?: boolean;
disableAutoResizing?: number;
}
export const GridviewReact: React.FunctionComponent<IGridviewReactProps> = (
@ -37,7 +39,26 @@ export const GridviewReact: React.FunctionComponent<IGridviewReactProps> = (
const [portals, addPortal] = usePortalsLifecycle();
React.useEffect(() => {
const gridview = new GridviewComponent(domRef.current!, {
if (props.disableAutoResizing) {
return () => {
//
};
}
const watcher = watchElementResize(domRef.current, (entry) => {
const { width, height } = entry.contentRect;
gridviewRef.current?.layout(width, height);
});
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,
@ -53,6 +74,8 @@ export const GridviewReact: React.FunctionComponent<IGridviewReactProps> = (
: undefined,
});
domRef.current?.appendChild(gridview.element);
if (props.onReady) {
props.onReady({ api: new GridviewApi(gridview) });
}

View File

@ -8,6 +8,7 @@ import { usePortalsLifecycle } from '../react';
import { PaneviewApi } from '../../api/component.api';
import { PanelBody, PanelHeader } from './view';
import { PanelCollection } from '../types';
import { watchElementResize } from '../../dom';
export interface PaneviewReadyEvent {
api: PaneviewApi;
@ -25,6 +26,7 @@ export interface IPaneviewReactProps {
components?: PanelCollection<IPaneviewPanelProps>;
headerComponents?: PanelCollection<IPaneviewPanelProps>;
className?: string;
disableAutoResizing?: boolean;
}
export const PaneviewReact: React.FunctionComponent<IPaneviewReactProps> = (
@ -34,6 +36,23 @@ export const PaneviewReact: React.FunctionComponent<IPaneviewReactProps> = (
const paneviewRef = React.useRef<IPaneviewComponent>();
const [portals, addPortal] = usePortalsLifecycle();
React.useEffect(() => {
if (props.disableAutoResizing) {
return () => {
//
};
}
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,

View File

@ -9,6 +9,7 @@ import { Orientation } from '../../splitview/core/splitview';
import { usePortalsLifecycle } from '../react';
import { PanelCollection } from '../types';
import { ReactPanelView } from './view';
import { watchElementResize } from '../../dom';
export interface SplitviewReadyEvent {
api: SplitviewApi;
@ -27,6 +28,7 @@ export interface ISplitviewReactProps {
proportionalLayout?: boolean;
hideBorders?: boolean;
className?: string;
disableAutoResizing?: boolean;
}
export const SplitviewReact: React.FunctionComponent<ISplitviewReactProps> = (
@ -36,6 +38,23 @@ export const SplitviewReact: React.FunctionComponent<ISplitviewReactProps> = (
const splitviewRef = React.useRef<ISplitviewComponent>();
const [portals, addPortal] = usePortalsLifecycle();
React.useEffect(() => {
if (props.disableAutoResizing) {
return () => {
//
};
}
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,