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
});
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', () => {
// beforeEach(() => {
// window.open = () => fromPartial<Window>({

View File

@ -32,6 +32,21 @@ describe('gridview', () => {
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', () => {
const gridview = new GridviewComponent(container, {
proportionalLayout: false,

View File

@ -537,4 +537,20 @@ describe('componentPaneview', () => {
expect(panel1.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(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 {
AddComponentOptions,
GridviewComponentUpdateOptions,
IGridviewComponent,
SerializedGridviewComponent,
} from '../gridview/gridviewComponent';
@ -31,7 +30,6 @@ import {
AddSplitviewComponentOptions,
ISplitviewComponent,
SerializedSplitview,
SplitviewComponentUpdateOptions,
} from '../splitview/splitviewComponent';
import { IView, Orientation, Sizing } from '../splitview/splitview';
import { ISplitviewPanel } from '../splitview/splitviewPanel';
@ -46,13 +44,15 @@ import {
GroupDragEvent,
TabDragEvent,
} from '../dockview/components/titlebar/tabsContainer';
import { AnchoredBox, Box } from '../types';
import { Box } from '../types';
import {
DockviewDidDropEvent,
DockviewWillDropEvent,
WillShowOverlayLocationEvent,
} from '../dockview/dockviewGroupPanelModel';
import { PaneviewComponentOptions } from '../paneview/options';
import { SplitviewComponentOptions } from '../splitview/options';
import { GridviewComponentOptions } from '../gridview/options';
export interface CommonApi<T = any> {
readonly height: number;
@ -214,7 +214,7 @@ export class SplitviewApi implements CommonApi<SerializedSplitview> {
/**
* Update configuratable options.
*/
updateOptions(options: Partial<SplitviewComponentUpdateOptions>): void {
updateOptions(options: Partial<SplitviewComponentOptions>): void {
this.component.updateOptions(options);
}
@ -556,7 +556,7 @@ export class GridviewApi implements CommonApi<SerializedGridviewComponent> {
this.component.clear();
}
updateOptions(options: Partial<GridviewComponentUpdateOptions>) {
updateOptions(options: Partial<GridviewComponentOptions>) {
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 =
'floatingGroupBounds' in options &&
options.floatingGroupBounds !== this.options.floatingGroupBounds;
@ -1106,7 +1108,7 @@ export class DockviewComponent
if (!this.activeGroup) {
return;
}
options.group = this.activeGroup;
options.group = this.activeGroup;
}
if (options.includePanel && options.group) {

View File

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

View File

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

View File

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

View File

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