mirror of
https://github.com/mathuo/dockview
synced 2025-05-08 20:48:28 +00:00
feat: autoresize views
This commit is contained in:
parent
7d21f9f19e
commit
64c24dca55
@ -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"
|
||||
}
|
||||
|
5
packages/splitview/package-lock.json
generated
5
packages/splitview/package-lock.json
generated
@ -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",
|
||||
|
@ -59,5 +59,8 @@
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"resize-observer-polyfill": "^1.5.1"
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
jest.mock('resize-observer-polyfill', () => ({
|
||||
__esModule: true,
|
||||
default: jest.fn().mockImplementation(() => ({
|
||||
observe: jest.fn(),
|
||||
unobserve: jest.fn(),
|
||||
disconnect: jest.fn(),
|
||||
})),
|
||||
}));
|
@ -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') {
|
||||
|
@ -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) });
|
||||
|
@ -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) });
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user