Skip to content

Commit 0e81392

Browse files
authored
Merge pull request #685 from mathuo/684-multiple-classes-on-dockviewreact-element-doesnt-work-in-1160
bug: multiple classnames
2 parents 56182aa + 1876511 commit 0e81392

File tree

10 files changed

+140
-29
lines changed

10 files changed

+140
-29
lines changed

packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,28 @@ describe('dockviewComponent', () => {
118118
window.open = jest.fn(); // not implemented by jest
119119
});
120120

121+
test('update className', () => {
122+
dockview = new DockviewComponent(container, {
123+
createComponent(options) {
124+
switch (options.name) {
125+
case 'default':
126+
return new PanelContentPartTest(
127+
options.id,
128+
options.name
129+
);
130+
default:
131+
throw new Error(`unsupported`);
132+
}
133+
},
134+
className: 'test-a test-b',
135+
});
136+
expect(dockview.element.className).toBe('test-a test-b');
137+
138+
dockview.updateOptions({ className: 'test-b test-c' });
139+
140+
expect(dockview.element.className).toBe('test-b test-c');
141+
});
142+
121143
// describe('memory leakage', () => {
122144
// beforeEach(() => {
123145
// window.open = () => fromPartial<Window>({

packages/dockview-core/src/__tests__/gridview/gridviewComponent.spec.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,21 @@ describe('gridview', () => {
3232
container = document.createElement('div');
3333
});
3434

35+
test('update className', () => {
36+
const gridview = new GridviewComponent(container, {
37+
proportionalLayout: false,
38+
orientation: Orientation.VERTICAL,
39+
components: { default: TestGridview },
40+
className: 'test-a test-b',
41+
});
42+
43+
expect(gridview.element.className).toBe('test-a test-b');
44+
45+
gridview.updateOptions({ className: 'test-b test-c' });
46+
47+
expect(gridview.element.className).toBe('test-b test-c');
48+
});
49+
3550
test('added views are visible by default', () => {
3651
const gridview = new GridviewComponent(container, {
3752
proportionalLayout: false,

packages/dockview-core/src/__tests__/paneview/paneviewComponent.spec.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,4 +537,20 @@ describe('componentPaneview', () => {
537537
expect(panel1.api.isVisible).toBeTruthy();
538538
expect(panel2.api.isVisible).toBeTruthy();
539539
});
540+
541+
test('update className', () => {
542+
const paneview = new PaneviewComponent(container, {
543+
components: {
544+
default: TestPanel,
545+
},
546+
disableAutoResizing: true,
547+
className: 'test-a test-b',
548+
});
549+
550+
expect(paneview.element.className).toBe('container test-a test-b');
551+
552+
paneview.updateOptions({ className: 'test-b test-c' });
553+
554+
expect(paneview.element.className).toBe('container test-b test-c');
555+
});
540556
});

packages/dockview-core/src/__tests__/splitview/splitviewComponent.spec.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,4 +631,20 @@ describe('componentSplitview', () => {
631631
expect(panel1.api.isVisible).toBeTruthy();
632632
expect(panel2.api.isVisible).toBeTruthy();
633633
});
634+
635+
test('update className', () => {
636+
const splitview = new SplitviewComponent(container, {
637+
orientation: Orientation.HORIZONTAL,
638+
components: {
639+
default: TestPanel,
640+
},
641+
className: 'test-a test-b',
642+
});
643+
644+
expect(splitview.element.className).toBe('container test-a test-b');
645+
646+
splitview.updateOptions({ className: 'test-b test-c' });
647+
648+
expect(splitview.element.className).toBe('container test-b test-c');
649+
});
634650
});

packages/dockview-core/src/api/component.api.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import { Parameters } from '../panel/types';
1515
import { Direction } from '../gridview/baseComponentGridview';
1616
import {
1717
AddComponentOptions,
18-
GridviewComponentUpdateOptions,
1918
IGridviewComponent,
2019
SerializedGridviewComponent,
2120
} from '../gridview/gridviewComponent';
@@ -31,7 +30,6 @@ import {
3130
AddSplitviewComponentOptions,
3231
ISplitviewComponent,
3332
SerializedSplitview,
34-
SplitviewComponentUpdateOptions,
3533
} from '../splitview/splitviewComponent';
3634
import { IView, Orientation, Sizing } from '../splitview/splitview';
3735
import { ISplitviewPanel } from '../splitview/splitviewPanel';
@@ -46,13 +44,15 @@ import {
4644
GroupDragEvent,
4745
TabDragEvent,
4846
} from '../dockview/components/titlebar/tabsContainer';
49-
import { AnchoredBox, Box } from '../types';
47+
import { Box } from '../types';
5048
import {
5149
DockviewDidDropEvent,
5250
DockviewWillDropEvent,
5351
WillShowOverlayLocationEvent,
5452
} from '../dockview/dockviewGroupPanelModel';
5553
import { PaneviewComponentOptions } from '../paneview/options';
54+
import { SplitviewComponentOptions } from '../splitview/options';
55+
import { GridviewComponentOptions } from '../gridview/options';
5656

5757
export interface CommonApi<T = any> {
5858
readonly height: number;
@@ -214,7 +214,7 @@ export class SplitviewApi implements CommonApi<SerializedSplitview> {
214214
/**
215215
* Update configuratable options.
216216
*/
217-
updateOptions(options: Partial<SplitviewComponentUpdateOptions>): void {
217+
updateOptions(options: Partial<SplitviewComponentOptions>): void {
218218
this.component.updateOptions(options);
219219
}
220220

@@ -556,7 +556,7 @@ export class GridviewApi implements CommonApi<SerializedGridviewComponent> {
556556
this.component.clear();
557557
}
558558

559-
updateOptions(options: Partial<GridviewComponentUpdateOptions>) {
559+
updateOptions(options: Partial<GridviewComponentOptions>) {
560560
this.component.updateOptions(options);
561561
}
562562

packages/dockview-core/src/dockview/dockviewComponent.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,7 +1019,9 @@ export class DockviewComponent
10191019
}
10201020
}
10211021

1022-
updateOptions(options: Partial<DockviewComponentOptions>): void {
1022+
override updateOptions(options: Partial<DockviewComponentOptions>): void {
1023+
super.updateOptions(options);
1024+
10231025
const changed_floatingGroupBounds =
10241026
'floatingGroupBounds' in options &&
10251027
options.floatingGroupBounds !== this.options.floatingGroupBounds;
@@ -1106,7 +1108,7 @@ export class DockviewComponent
11061108
if (!this.activeGroup) {
11071109
return;
11081110
}
1109-
options.group = this.activeGroup;
1111+
options.group = this.activeGroup;
11101112
}
11111113

11121114
if (options.includePanel && options.group) {

packages/dockview-core/src/gridview/baseComponentGridview.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { ISplitviewStyles, Orientation, Sizing } from '../splitview/splitview';
77
import { IPanel } from '../panel/types';
88
import { MovementOptions2 } from '../dockview/options';
99
import { Resizable } from '../resizable';
10+
import { toggleClass } from '../dom';
1011

1112
const nextLayoutId = sequentialNumberGenerator();
1213

@@ -99,6 +100,8 @@ export abstract class BaseGrid<T extends IGridPanelView>
99100
readonly onDidViewVisibilityChangeMicroTaskQueue =
100101
this._onDidViewVisibilityChangeMicroTaskQueue.onEvent;
101102

103+
private classNames: string[] = [];
104+
102105
get id(): string {
103106
return this._id;
104107
}
@@ -149,8 +152,10 @@ export abstract class BaseGrid<T extends IGridPanelView>
149152
this.element.style.height = '100%';
150153
this.element.style.width = '100%';
151154

152-
if (typeof options.className === 'string') {
153-
this.element.classList.add(options.className);
155+
this.classNames = options.className?.split(' ') ?? [];
156+
157+
for (const className of this.classNames) {
158+
toggleClass(this.element, className, true);
154159
}
155160

156161
options.parentElement.appendChild(this.element);
@@ -208,6 +213,18 @@ export abstract class BaseGrid<T extends IGridPanelView>
208213
return this.gridview.isViewVisible(getGridLocation(panel.element));
209214
}
210215

216+
updateOptions(options: Partial<BaseGridOptions>) {
217+
if ('className' in options) {
218+
for (const className of this.classNames) {
219+
toggleClass(this.element, className, false);
220+
}
221+
this.classNames = options.className?.split(' ') ?? [];
222+
for (const className of this.classNames) {
223+
toggleClass(this.element, className, true);
224+
}
225+
}
226+
}
227+
211228
maximizeGroup(panel: T): void {
212229
this.gridview.maximizeView(panel);
213230
this.doSetGroupActive(panel);

packages/dockview-core/src/gridview/gridviewComponent.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,10 @@ export interface IGridPanelComponentView extends IGridPanelView {
4949
init: (params: GridviewInitParameters) => void;
5050
}
5151

52-
export type GridviewComponentUpdateOptions = Pick<
53-
GridviewComponentOptions,
54-
'orientation' | 'components' | 'frameworkComponents'
55-
>;
56-
5752
export interface IGridviewComponent extends IBaseGrid<GridviewPanel> {
5853
readonly orientation: Orientation;
5954
readonly onDidLayoutFromJSON: Event<void>;
60-
updateOptions(options: Partial<GridviewComponentUpdateOptions>): void;
55+
updateOptions(options: Partial<GridviewComponentOptions>): void;
6156
addPanel<T extends object = Parameters>(
6257
options: AddComponentOptions<T>
6358
): IGridviewPanel;
@@ -154,7 +149,9 @@ export class GridviewComponent
154149
}
155150
}
156151

157-
updateOptions(options: Partial<GridviewComponentUpdateOptions>): void {
152+
override updateOptions(options: Partial<GridviewComponentOptions>): void {
153+
super.updateOptions(options);
154+
158155
const hasOrientationChanged =
159156
typeof options.orientation === 'string' &&
160157
this.gridview.orientation !== options.orientation;

packages/dockview-core/src/paneview/paneviewComponent.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { sequentialNumberGenerator } from '../math';
2424
import { PaneTransfer } from '../dnd/dataTransfer';
2525
import { Resizable } from '../resizable';
2626
import { Parameters } from '../panel/types';
27+
import { toggleClass } from '../dom';
2728

2829
const nextLayoutId = sequentialNumberGenerator();
2930

@@ -151,6 +152,8 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent {
151152
private readonly _onDidRemoveView = new Emitter<PaneviewPanel>();
152153
readonly onDidRemoveView = this._onDidRemoveView.event;
153154

155+
private classNames: string[] = [];
156+
154157
get id(): string {
155158
return this._id;
156159
}
@@ -202,10 +205,6 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent {
202205
constructor(parentElement: HTMLElement, options: PaneviewComponentOptions) {
203206
super(parentElement, options.disableAutoResizing);
204207

205-
if (typeof options.className === 'string') {
206-
this.element.classList.add(options.className);
207-
}
208-
209208
this.addDisposables(
210209
this._onDidLayoutChange,
211210
this._onDidLayoutfromJSON,
@@ -214,6 +213,12 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent {
214213
this._onDidRemoveView
215214
);
216215

216+
this.classNames = options.className?.split(' ') ?? [];
217+
218+
for (const className of this.classNames) {
219+
toggleClass(this.element, className, true);
220+
}
221+
217222
this._options = options;
218223

219224
if (!options.components) {
@@ -241,6 +246,16 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent {
241246
}
242247

243248
updateOptions(options: Partial<PaneviewComponentOptions>): void {
249+
if ('className' in options) {
250+
for (const className of this.classNames) {
251+
toggleClass(this.element, className, false);
252+
}
253+
this.classNames = options.className?.split(' ') ?? [];
254+
for (const className of this.classNames) {
255+
toggleClass(this.element, className, true);
256+
}
257+
}
258+
244259
this._options = { ...this.options, ...options };
245260
}
246261

packages/dockview-core/src/splitview/splitviewComponent.ts

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@ import {
99
Orientation,
1010
Sizing,
1111
Splitview,
12+
SplitViewOptions,
1213
} from './splitview';
1314
import { SplitviewComponentOptions } from './options';
1415
import { BaseComponentOptions, Parameters } from '../panel/types';
1516
import { Emitter, Event } from '../events';
1617
import { SplitviewPanel, ISplitviewPanel } from './splitviewPanel';
1718
import { createComponent } from '../panel/componentFactory';
1819
import { Resizable } from '../resizable';
20+
import { toggleClass } from '../dom';
1921

2022
export interface SerializedSplitviewPanelData {
2123
id: string;
@@ -46,11 +48,6 @@ export interface AddSplitviewComponentOptions<T extends Parameters = Parameters>
4648
maximumSize?: number;
4749
}
4850

49-
export type SplitviewComponentUpdateOptions = Pick<
50-
SplitviewComponentOptions,
51-
'orientation' | 'components' | 'frameworkComponents'
52-
>;
53-
5451
export interface ISplitviewComponent extends IDisposable {
5552
readonly minimumSize: number;
5653
readonly maximumSize: number;
@@ -62,7 +59,7 @@ export interface ISplitviewComponent extends IDisposable {
6259
readonly onDidRemoveView: Event<IView>;
6360
readonly onDidLayoutFromJSON: Event<void>;
6461
readonly panels: SplitviewPanel[];
65-
updateOptions(options: Partial<SplitviewComponentUpdateOptions>): void;
62+
updateOptions(options: Partial<SplitViewOptions>): void;
6663
addPanel<T extends object = Parameters>(
6764
options: AddSplitviewComponentOptions<T>
6865
): ISplitviewPanel;
@@ -103,6 +100,8 @@ export class SplitviewComponent
103100
private readonly _onDidLayoutChange = new Emitter<void>();
104101
readonly onDidLayoutChange: Event<void> = this._onDidLayoutChange.event;
105102

103+
private classNames: string[] = [];
104+
106105
get panels(): SplitviewPanel[] {
107106
return this.splitview.getViews();
108107
}
@@ -163,8 +162,10 @@ export class SplitviewComponent
163162
) {
164163
super(parentElement, options.disableAutoResizing);
165164

166-
if (typeof options.className === 'string') {
167-
this.element.classList.add(options.className);
165+
this.classNames = options.className?.split(' ') ?? [];
166+
167+
for (const className of this.classNames) {
168+
toggleClass(this.element, className, true);
168169
}
169170

170171
this._options = options;
@@ -186,7 +187,17 @@ export class SplitviewComponent
186187
);
187188
}
188189

189-
updateOptions(options: Partial<SplitviewComponentUpdateOptions>): void {
190+
updateOptions(options: Partial<SplitviewComponentOptions>): void {
191+
if ('className' in options) {
192+
for (const className of this.classNames) {
193+
toggleClass(this.element, className, false);
194+
}
195+
this.classNames = options.className?.split(' ') ?? [];
196+
for (const className of this.classNames) {
197+
toggleClass(this.element, className, true);
198+
}
199+
}
200+
190201
const hasOrientationChanged =
191202
typeof options.orientation === 'string' &&
192203
this.options.orientation !== options.orientation;

0 commit comments

Comments
 (0)