Merge pull request #685 from mathuo/684-multiple-classes-on-dockviewreact-element-doesnt-work-in-1160

bug: multiple classnames
This commit is contained in:
mathuo 2024-08-13 19:43:29 +01:00 committed by GitHub
commit 0e8139217b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 140 additions and 29 deletions

View File

@ -118,6 +118,28 @@ describe('dockviewComponent', () => {
window.open = jest.fn(); // not implemented by jest window.open = jest.fn(); // not implemented by jest
}); });
test('update className', () => {
dockview = new DockviewComponent(container, {
createComponent(options) {
switch (options.name) {
case 'default':
return new PanelContentPartTest(
options.id,
options.name
);
default:
throw new Error(`unsupported`);
}
},
className: 'test-a test-b',
});
expect(dockview.element.className).toBe('test-a test-b');
dockview.updateOptions({ className: 'test-b test-c' });
expect(dockview.element.className).toBe('test-b test-c');
});
// describe('memory leakage', () => { // describe('memory leakage', () => {
// beforeEach(() => { // beforeEach(() => {
// window.open = () => fromPartial<Window>({ // window.open = () => fromPartial<Window>({

View File

@ -32,6 +32,21 @@ describe('gridview', () => {
container = document.createElement('div'); container = document.createElement('div');
}); });
test('update className', () => {
const gridview = new GridviewComponent(container, {
proportionalLayout: false,
orientation: Orientation.VERTICAL,
components: { default: TestGridview },
className: 'test-a test-b',
});
expect(gridview.element.className).toBe('test-a test-b');
gridview.updateOptions({ className: 'test-b test-c' });
expect(gridview.element.className).toBe('test-b test-c');
});
test('added views are visible by default', () => { test('added views are visible by default', () => {
const gridview = new GridviewComponent(container, { const gridview = new GridviewComponent(container, {
proportionalLayout: false, proportionalLayout: false,

View File

@ -537,4 +537,20 @@ describe('componentPaneview', () => {
expect(panel1.api.isVisible).toBeTruthy(); expect(panel1.api.isVisible).toBeTruthy();
expect(panel2.api.isVisible).toBeTruthy(); expect(panel2.api.isVisible).toBeTruthy();
}); });
test('update className', () => {
const paneview = new PaneviewComponent(container, {
components: {
default: TestPanel,
},
disableAutoResizing: true,
className: 'test-a test-b',
});
expect(paneview.element.className).toBe('container test-a test-b');
paneview.updateOptions({ className: 'test-b test-c' });
expect(paneview.element.className).toBe('container test-b test-c');
});
}); });

View File

@ -631,4 +631,20 @@ describe('componentSplitview', () => {
expect(panel1.api.isVisible).toBeTruthy(); expect(panel1.api.isVisible).toBeTruthy();
expect(panel2.api.isVisible).toBeTruthy(); expect(panel2.api.isVisible).toBeTruthy();
}); });
test('update className', () => {
const splitview = new SplitviewComponent(container, {
orientation: Orientation.HORIZONTAL,
components: {
default: TestPanel,
},
className: 'test-a test-b',
});
expect(splitview.element.className).toBe('container test-a test-b');
splitview.updateOptions({ className: 'test-b test-c' });
expect(splitview.element.className).toBe('container test-b test-c');
});
}); });

View File

@ -15,7 +15,6 @@ import { Parameters } from '../panel/types';
import { Direction } from '../gridview/baseComponentGridview'; import { Direction } from '../gridview/baseComponentGridview';
import { import {
AddComponentOptions, AddComponentOptions,
GridviewComponentUpdateOptions,
IGridviewComponent, IGridviewComponent,
SerializedGridviewComponent, SerializedGridviewComponent,
} from '../gridview/gridviewComponent'; } from '../gridview/gridviewComponent';
@ -31,7 +30,6 @@ import {
AddSplitviewComponentOptions, AddSplitviewComponentOptions,
ISplitviewComponent, ISplitviewComponent,
SerializedSplitview, SerializedSplitview,
SplitviewComponentUpdateOptions,
} from '../splitview/splitviewComponent'; } from '../splitview/splitviewComponent';
import { IView, Orientation, Sizing } from '../splitview/splitview'; import { IView, Orientation, Sizing } from '../splitview/splitview';
import { ISplitviewPanel } from '../splitview/splitviewPanel'; import { ISplitviewPanel } from '../splitview/splitviewPanel';
@ -46,13 +44,15 @@ import {
GroupDragEvent, GroupDragEvent,
TabDragEvent, TabDragEvent,
} from '../dockview/components/titlebar/tabsContainer'; } from '../dockview/components/titlebar/tabsContainer';
import { AnchoredBox, Box } from '../types'; import { Box } from '../types';
import { import {
DockviewDidDropEvent, DockviewDidDropEvent,
DockviewWillDropEvent, DockviewWillDropEvent,
WillShowOverlayLocationEvent, WillShowOverlayLocationEvent,
} from '../dockview/dockviewGroupPanelModel'; } from '../dockview/dockviewGroupPanelModel';
import { PaneviewComponentOptions } from '../paneview/options'; import { PaneviewComponentOptions } from '../paneview/options';
import { SplitviewComponentOptions } from '../splitview/options';
import { GridviewComponentOptions } from '../gridview/options';
export interface CommonApi<T = any> { export interface CommonApi<T = any> {
readonly height: number; readonly height: number;
@ -214,7 +214,7 @@ export class SplitviewApi implements CommonApi<SerializedSplitview> {
/** /**
* Update configuratable options. * Update configuratable options.
*/ */
updateOptions(options: Partial<SplitviewComponentUpdateOptions>): void { updateOptions(options: Partial<SplitviewComponentOptions>): void {
this.component.updateOptions(options); this.component.updateOptions(options);
} }
@ -556,7 +556,7 @@ export class GridviewApi implements CommonApi<SerializedGridviewComponent> {
this.component.clear(); this.component.clear();
} }
updateOptions(options: Partial<GridviewComponentUpdateOptions>) { updateOptions(options: Partial<GridviewComponentOptions>) {
this.component.updateOptions(options); this.component.updateOptions(options);
} }

View File

@ -1019,7 +1019,9 @@ export class DockviewComponent
} }
} }
updateOptions(options: Partial<DockviewComponentOptions>): void { override updateOptions(options: Partial<DockviewComponentOptions>): void {
super.updateOptions(options);
const changed_floatingGroupBounds = const changed_floatingGroupBounds =
'floatingGroupBounds' in options && 'floatingGroupBounds' in options &&
options.floatingGroupBounds !== this.options.floatingGroupBounds; options.floatingGroupBounds !== this.options.floatingGroupBounds;

View File

@ -7,6 +7,7 @@ import { ISplitviewStyles, Orientation, Sizing } from '../splitview/splitview';
import { IPanel } from '../panel/types'; import { IPanel } from '../panel/types';
import { MovementOptions2 } from '../dockview/options'; import { MovementOptions2 } from '../dockview/options';
import { Resizable } from '../resizable'; import { Resizable } from '../resizable';
import { toggleClass } from '../dom';
const nextLayoutId = sequentialNumberGenerator(); const nextLayoutId = sequentialNumberGenerator();
@ -99,6 +100,8 @@ export abstract class BaseGrid<T extends IGridPanelView>
readonly onDidViewVisibilityChangeMicroTaskQueue = readonly onDidViewVisibilityChangeMicroTaskQueue =
this._onDidViewVisibilityChangeMicroTaskQueue.onEvent; this._onDidViewVisibilityChangeMicroTaskQueue.onEvent;
private classNames: string[] = [];
get id(): string { get id(): string {
return this._id; return this._id;
} }
@ -149,8 +152,10 @@ export abstract class BaseGrid<T extends IGridPanelView>
this.element.style.height = '100%'; this.element.style.height = '100%';
this.element.style.width = '100%'; this.element.style.width = '100%';
if (typeof options.className === 'string') { this.classNames = options.className?.split(' ') ?? [];
this.element.classList.add(options.className);
for (const className of this.classNames) {
toggleClass(this.element, className, true);
} }
options.parentElement.appendChild(this.element); options.parentElement.appendChild(this.element);
@ -208,6 +213,18 @@ export abstract class BaseGrid<T extends IGridPanelView>
return this.gridview.isViewVisible(getGridLocation(panel.element)); return this.gridview.isViewVisible(getGridLocation(panel.element));
} }
updateOptions(options: Partial<BaseGridOptions>) {
if ('className' in options) {
for (const className of this.classNames) {
toggleClass(this.element, className, false);
}
this.classNames = options.className?.split(' ') ?? [];
for (const className of this.classNames) {
toggleClass(this.element, className, true);
}
}
}
maximizeGroup(panel: T): void { maximizeGroup(panel: T): void {
this.gridview.maximizeView(panel); this.gridview.maximizeView(panel);
this.doSetGroupActive(panel); this.doSetGroupActive(panel);

View File

@ -49,15 +49,10 @@ export interface IGridPanelComponentView extends IGridPanelView {
init: (params: GridviewInitParameters) => void; init: (params: GridviewInitParameters) => void;
} }
export type GridviewComponentUpdateOptions = Pick<
GridviewComponentOptions,
'orientation' | 'components' | 'frameworkComponents'
>;
export interface IGridviewComponent extends IBaseGrid<GridviewPanel> { export interface IGridviewComponent extends IBaseGrid<GridviewPanel> {
readonly orientation: Orientation; readonly orientation: Orientation;
readonly onDidLayoutFromJSON: Event<void>; readonly onDidLayoutFromJSON: Event<void>;
updateOptions(options: Partial<GridviewComponentUpdateOptions>): void; updateOptions(options: Partial<GridviewComponentOptions>): void;
addPanel<T extends object = Parameters>( addPanel<T extends object = Parameters>(
options: AddComponentOptions<T> options: AddComponentOptions<T>
): IGridviewPanel; ): IGridviewPanel;
@ -154,7 +149,9 @@ export class GridviewComponent
} }
} }
updateOptions(options: Partial<GridviewComponentUpdateOptions>): void { override updateOptions(options: Partial<GridviewComponentOptions>): void {
super.updateOptions(options);
const hasOrientationChanged = const hasOrientationChanged =
typeof options.orientation === 'string' && typeof options.orientation === 'string' &&
this.gridview.orientation !== options.orientation; this.gridview.orientation !== options.orientation;

View File

@ -24,6 +24,7 @@ import { sequentialNumberGenerator } from '../math';
import { PaneTransfer } from '../dnd/dataTransfer'; import { PaneTransfer } from '../dnd/dataTransfer';
import { Resizable } from '../resizable'; import { Resizable } from '../resizable';
import { Parameters } from '../panel/types'; import { Parameters } from '../panel/types';
import { toggleClass } from '../dom';
const nextLayoutId = sequentialNumberGenerator(); const nextLayoutId = sequentialNumberGenerator();
@ -151,6 +152,8 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent {
private readonly _onDidRemoveView = new Emitter<PaneviewPanel>(); private readonly _onDidRemoveView = new Emitter<PaneviewPanel>();
readonly onDidRemoveView = this._onDidRemoveView.event; readonly onDidRemoveView = this._onDidRemoveView.event;
private classNames: string[] = [];
get id(): string { get id(): string {
return this._id; return this._id;
} }
@ -202,10 +205,6 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent {
constructor(parentElement: HTMLElement, options: PaneviewComponentOptions) { constructor(parentElement: HTMLElement, options: PaneviewComponentOptions) {
super(parentElement, options.disableAutoResizing); super(parentElement, options.disableAutoResizing);
if (typeof options.className === 'string') {
this.element.classList.add(options.className);
}
this.addDisposables( this.addDisposables(
this._onDidLayoutChange, this._onDidLayoutChange,
this._onDidLayoutfromJSON, this._onDidLayoutfromJSON,
@ -214,6 +213,12 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent {
this._onDidRemoveView this._onDidRemoveView
); );
this.classNames = options.className?.split(' ') ?? [];
for (const className of this.classNames) {
toggleClass(this.element, className, true);
}
this._options = options; this._options = options;
if (!options.components) { if (!options.components) {
@ -241,6 +246,16 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent {
} }
updateOptions(options: Partial<PaneviewComponentOptions>): void { updateOptions(options: Partial<PaneviewComponentOptions>): void {
if ('className' in options) {
for (const className of this.classNames) {
toggleClass(this.element, className, false);
}
this.classNames = options.className?.split(' ') ?? [];
for (const className of this.classNames) {
toggleClass(this.element, className, true);
}
}
this._options = { ...this.options, ...options }; this._options = { ...this.options, ...options };
} }

View File

@ -9,6 +9,7 @@ import {
Orientation, Orientation,
Sizing, Sizing,
Splitview, Splitview,
SplitViewOptions,
} from './splitview'; } from './splitview';
import { SplitviewComponentOptions } from './options'; import { SplitviewComponentOptions } from './options';
import { BaseComponentOptions, Parameters } from '../panel/types'; import { BaseComponentOptions, Parameters } from '../panel/types';
@ -16,6 +17,7 @@ import { Emitter, Event } from '../events';
import { SplitviewPanel, ISplitviewPanel } from './splitviewPanel'; import { SplitviewPanel, ISplitviewPanel } from './splitviewPanel';
import { createComponent } from '../panel/componentFactory'; import { createComponent } from '../panel/componentFactory';
import { Resizable } from '../resizable'; import { Resizable } from '../resizable';
import { toggleClass } from '../dom';
export interface SerializedSplitviewPanelData { export interface SerializedSplitviewPanelData {
id: string; id: string;
@ -46,11 +48,6 @@ export interface AddSplitviewComponentOptions<T extends Parameters = Parameters>
maximumSize?: number; maximumSize?: number;
} }
export type SplitviewComponentUpdateOptions = Pick<
SplitviewComponentOptions,
'orientation' | 'components' | 'frameworkComponents'
>;
export interface ISplitviewComponent extends IDisposable { export interface ISplitviewComponent extends IDisposable {
readonly minimumSize: number; readonly minimumSize: number;
readonly maximumSize: number; readonly maximumSize: number;
@ -62,7 +59,7 @@ export interface ISplitviewComponent extends IDisposable {
readonly onDidRemoveView: Event<IView>; readonly onDidRemoveView: Event<IView>;
readonly onDidLayoutFromJSON: Event<void>; readonly onDidLayoutFromJSON: Event<void>;
readonly panels: SplitviewPanel[]; readonly panels: SplitviewPanel[];
updateOptions(options: Partial<SplitviewComponentUpdateOptions>): void; updateOptions(options: Partial<SplitViewOptions>): void;
addPanel<T extends object = Parameters>( addPanel<T extends object = Parameters>(
options: AddSplitviewComponentOptions<T> options: AddSplitviewComponentOptions<T>
): ISplitviewPanel; ): ISplitviewPanel;
@ -103,6 +100,8 @@ export class SplitviewComponent
private readonly _onDidLayoutChange = new Emitter<void>(); private readonly _onDidLayoutChange = new Emitter<void>();
readonly onDidLayoutChange: Event<void> = this._onDidLayoutChange.event; readonly onDidLayoutChange: Event<void> = this._onDidLayoutChange.event;
private classNames: string[] = [];
get panels(): SplitviewPanel[] { get panels(): SplitviewPanel[] {
return this.splitview.getViews(); return this.splitview.getViews();
} }
@ -163,8 +162,10 @@ export class SplitviewComponent
) { ) {
super(parentElement, options.disableAutoResizing); super(parentElement, options.disableAutoResizing);
if (typeof options.className === 'string') { this.classNames = options.className?.split(' ') ?? [];
this.element.classList.add(options.className);
for (const className of this.classNames) {
toggleClass(this.element, className, true);
} }
this._options = options; this._options = options;
@ -186,7 +187,17 @@ export class SplitviewComponent
); );
} }
updateOptions(options: Partial<SplitviewComponentUpdateOptions>): void { updateOptions(options: Partial<SplitviewComponentOptions>): void {
if ('className' in options) {
for (const className of this.classNames) {
toggleClass(this.element, className, false);
}
this.classNames = options.className?.split(' ') ?? [];
for (const className of this.classNames) {
toggleClass(this.element, className, true);
}
}
const hasOrientationChanged = const hasOrientationChanged =
typeof options.orientation === 'string' && typeof options.orientation === 'string' &&
this.options.orientation !== options.orientation; this.options.orientation !== options.orientation;