mirror of
https://github.com/microsoft/vscode.git
synced 2026-02-15 07:28:05 +00:00
Merge pull request #294881 from microsoft/mrleemurray/psychological-pink-finch
Add compact layout support for Activity Bar
This commit is contained in:
@@ -903,6 +903,9 @@
|
||||
"--vscode-window-inactiveBorder"
|
||||
],
|
||||
"others": [
|
||||
"--activity-bar-action-height",
|
||||
"--activity-bar-icon-size",
|
||||
"--activity-bar-width",
|
||||
"--editor-font-size",
|
||||
"--background-dark",
|
||||
"--background-light",
|
||||
|
||||
@@ -41,7 +41,14 @@ import { SwitchCompositeViewAction } from '../compositeBarActions.js';
|
||||
|
||||
export class ActivitybarPart extends Part {
|
||||
|
||||
static readonly ACTION_HEIGHT = 32;
|
||||
static readonly ACTION_HEIGHT = 48;
|
||||
static readonly COMPACT_ACTION_HEIGHT = 32;
|
||||
|
||||
static readonly ACTIVITYBAR_WIDTH = 48;
|
||||
static readonly COMPACT_ACTIVITYBAR_WIDTH = 36;
|
||||
|
||||
static readonly ICON_SIZE = 24;
|
||||
static readonly COMPACT_ICON_SIZE = 16;
|
||||
|
||||
static readonly pinnedViewContainersKey = 'workbench.activity.pinnedViewlets2';
|
||||
static readonly placeholderViewContainersKey = 'workbench.activity.placeholderViewlets';
|
||||
@@ -49,8 +56,8 @@ export class ActivitybarPart extends Part {
|
||||
|
||||
//#region IView
|
||||
|
||||
readonly minimumWidth: number = 36;
|
||||
readonly maximumWidth: number = 36;
|
||||
get minimumWidth(): number { return this._isCompact ? ActivitybarPart.COMPACT_ACTIVITYBAR_WIDTH : ActivitybarPart.ACTIVITYBAR_WIDTH; }
|
||||
get maximumWidth(): number { return this._isCompact ? ActivitybarPart.COMPACT_ACTIVITYBAR_WIDTH : ActivitybarPart.ACTIVITYBAR_WIDTH; }
|
||||
readonly minimumHeight: number = 0;
|
||||
readonly maximumHeight: number = Number.POSITIVE_INFINITY;
|
||||
|
||||
@@ -58,6 +65,7 @@ export class ActivitybarPart extends Part {
|
||||
|
||||
private readonly compositeBar = this._register(new MutableDisposable<PaneCompositeBar>());
|
||||
private content: HTMLElement | undefined;
|
||||
private _isCompact: boolean;
|
||||
|
||||
constructor(
|
||||
private readonly paneCompositePart: IPaneCompositePart,
|
||||
@@ -65,11 +73,50 @@ export class ActivitybarPart extends Part {
|
||||
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IStorageService storageService: IStorageService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
) {
|
||||
super(Parts.ACTIVITYBAR_PART, { hasTitle: false }, themeService, storageService, layoutService);
|
||||
|
||||
this._isCompact = this.configurationService.getValue<boolean>(LayoutSettings.ACTIVITY_BAR_COMPACT) ?? false;
|
||||
|
||||
this._register(this.configurationService.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration(LayoutSettings.ACTIVITY_BAR_COMPACT)) {
|
||||
this._isCompact = this.configurationService.getValue<boolean>(LayoutSettings.ACTIVITY_BAR_COMPACT) ?? false;
|
||||
this.updateCompactStyle();
|
||||
this.recreateCompositeBar();
|
||||
this._onDidChange.fire(undefined); // Signal grid that size constraints changed
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private updateCompactStyle(): void {
|
||||
if (this.element) {
|
||||
this.element.classList.toggle('compact', this._isCompact);
|
||||
this.element.style.setProperty('--activity-bar-width', `${this.minimumWidth}px`);
|
||||
this.element.style.setProperty('--activity-bar-action-height', `${this._isCompact ? ActivitybarPart.COMPACT_ACTION_HEIGHT : ActivitybarPart.ACTION_HEIGHT}px`);
|
||||
this.element.style.setProperty('--activity-bar-icon-size', `${this._isCompact ? ActivitybarPart.COMPACT_ICON_SIZE : ActivitybarPart.ICON_SIZE}px`);
|
||||
}
|
||||
}
|
||||
|
||||
private recreateCompositeBar(): void {
|
||||
if (!this.content || !this.compositeBar.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.compositeBar.clear();
|
||||
clearNode(this.content);
|
||||
this.compositeBar.value = this.createCompositeBar();
|
||||
this.compositeBar.value.create(this.content);
|
||||
|
||||
if (this.dimension) {
|
||||
this.layout(this.dimension.width, this.dimension.height);
|
||||
}
|
||||
}
|
||||
|
||||
private createCompositeBar(): PaneCompositeBar {
|
||||
const actionHeight = this._isCompact ? ActivitybarPart.COMPACT_ACTION_HEIGHT : ActivitybarPart.ACTION_HEIGHT;
|
||||
const iconSize = this._isCompact ? ActivitybarPart.COMPACT_ICON_SIZE : ActivitybarPart.ICON_SIZE;
|
||||
|
||||
return this.instantiationService.createInstance(ActivityBarCompositeBar, {
|
||||
partContainerClass: 'activitybar',
|
||||
pinnedViewContainersKey: ActivitybarPart.pinnedViewContainersKey,
|
||||
@@ -77,7 +124,7 @@ export class ActivitybarPart extends Part {
|
||||
viewContainersWorkspaceStateKey: ActivitybarPart.viewContainersWorkspaceStateKey,
|
||||
orientation: ActionsOrientation.VERTICAL,
|
||||
icon: true,
|
||||
iconSize: 16,
|
||||
iconSize,
|
||||
activityHoverOptions: {
|
||||
position: () => this.layoutService.getSideBarPosition() === Position.LEFT ? HoverPosition.RIGHT : HoverPosition.LEFT,
|
||||
},
|
||||
@@ -95,7 +142,7 @@ export class ActivitybarPart extends Part {
|
||||
dragAndDropBorder: theme.getColor(ACTIVITY_BAR_DRAG_AND_DROP_BORDER),
|
||||
activeBackgroundColor: undefined, inactiveBackgroundColor: undefined, activeBorderBottomColor: undefined,
|
||||
}),
|
||||
overflowActionSize: ActivitybarPart.ACTION_HEIGHT,
|
||||
overflowActionSize: actionHeight,
|
||||
}, Parts.ACTIVITYBAR_PART, this.paneCompositePart, true);
|
||||
}
|
||||
|
||||
@@ -103,6 +150,8 @@ export class ActivitybarPart extends Part {
|
||||
this.element = parent;
|
||||
this.content = append(this.element, $('.content'));
|
||||
|
||||
this.updateCompactStyle();
|
||||
|
||||
if (this.layoutService.isVisible(Parts.ACTIVITYBAR_PART)) {
|
||||
this.show();
|
||||
}
|
||||
@@ -358,7 +407,7 @@ export class ActivityBarCompositeBar extends PaneCompositeBar {
|
||||
}
|
||||
if (this.globalCompositeBar) {
|
||||
if (this.options.orientation === ActionsOrientation.VERTICAL) {
|
||||
height -= (this.globalCompositeBar.size() * ActivitybarPart.ACTION_HEIGHT);
|
||||
height -= (this.globalCompositeBar.size() * this.options.overflowActionSize);
|
||||
} else {
|
||||
width -= this.globalCompositeBar.element.clientWidth;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
.monaco-workbench .activitybar > .content .composite-bar > .monaco-action-bar .action-item::after {
|
||||
position: absolute;
|
||||
content: '';
|
||||
width: 36px;
|
||||
width: var(--activity-bar-width, 48px);
|
||||
height: 2px;
|
||||
display: none;
|
||||
background-color: transparent;
|
||||
@@ -46,8 +46,8 @@
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
width: 36px;
|
||||
height: 32px;
|
||||
width: var(--activity-bar-width, 48px);
|
||||
height: var(--activity-bar-action-height, 48px);
|
||||
margin-right: 0;
|
||||
box-sizing: border-box;
|
||||
|
||||
@@ -55,12 +55,12 @@
|
||||
|
||||
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-label:not(.codicon) {
|
||||
font-size: 15px;
|
||||
line-height: 32px;
|
||||
padding: 0 0 0 36px;
|
||||
line-height: var(--activity-bar-action-height, 48px);
|
||||
padding: 0 0 0 var(--activity-bar-width, 48px);
|
||||
}
|
||||
|
||||
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-label.codicon {
|
||||
font-size: 16px;
|
||||
font-size: var(--activity-bar-icon-size, 24px);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
@@ -157,31 +157,50 @@
|
||||
|
||||
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .badge .badge-content {
|
||||
position: absolute;
|
||||
top: 17px;
|
||||
right: 6px;
|
||||
top: 24px;
|
||||
right: 8px;
|
||||
font-size: 9px;
|
||||
font-weight: 600;
|
||||
min-width: 8px;
|
||||
height: 16px;
|
||||
line-height: 16px;
|
||||
padding: 0 4px;
|
||||
border-radius: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.monaco-workbench .activitybar.compact > .content :not(.monaco-menu) > .monaco-action-bar .badge .badge-content {
|
||||
top: 17px;
|
||||
right: 6px;
|
||||
min-width: 9px;
|
||||
height: 13px;
|
||||
line-height: 13px;
|
||||
padding: 0 2px;
|
||||
border-radius: 13px;
|
||||
text-align: center;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .profile-badge .profile-text-overlay {
|
||||
position: absolute;
|
||||
font-weight: 600;
|
||||
font-size: 9px;
|
||||
line-height: 10px;
|
||||
top: 24px;
|
||||
right: 6px;
|
||||
padding: 2px 3px;
|
||||
border-radius: 7px;
|
||||
background-color: var(--vscode-profileBadge-background);
|
||||
color: var(--vscode-profileBadge-foreground);
|
||||
border: 2px solid var(--vscode-activityBar-background);
|
||||
}
|
||||
|
||||
.monaco-workbench .activitybar.compact > .content :not(.monaco-menu) > .monaco-action-bar .profile-badge .profile-text-overlay {
|
||||
font-size: 8px;
|
||||
line-height: 8px;
|
||||
top: 14px;
|
||||
right: 2px;
|
||||
padding: 2px 2px;
|
||||
border-radius: 6px;
|
||||
background-color: var(--vscode-profileBadge-background);
|
||||
color: var(--vscode-profileBadge-foreground);
|
||||
border: 2px solid var(--vscode-activityBar-background);
|
||||
}
|
||||
|
||||
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item:active .profile-text-overlay,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.monaco-workbench .part.activitybar {
|
||||
width: 36px;
|
||||
width: var(--activity-bar-width, 48px);
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
|
||||
@@ -403,9 +403,9 @@ export class PaneCompositeBar extends Disposable {
|
||||
classNames = [iconId, 'uri-icon'];
|
||||
createCSSRule(iconClass, `
|
||||
mask: ${cssUrl} no-repeat 50% 50%;
|
||||
mask-size: ${this.options.iconSize}px;
|
||||
mask-size: var(--activity-bar-icon-size, ${this.options.iconSize}px);
|
||||
-webkit-mask: ${cssUrl} no-repeat 50% 50%;
|
||||
-webkit-mask-size: ${this.options.iconSize}px;
|
||||
-webkit-mask-size: var(--activity-bar-icon-size, ${this.options.iconSize}px);
|
||||
mask-origin: padding;
|
||||
-webkit-mask-origin: padding;
|
||||
`);
|
||||
|
||||
@@ -627,6 +627,11 @@ const registry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Con
|
||||
'default': false,
|
||||
'markdownDescription': localize({ comment: ['This is the description for a setting'], key: 'activityBarAutoHide' }, "Controls whether the Activity Bar is automatically hidden when there is only one view container to show. This applies to the Primary and Secondary Side Bars when {0} is set to {1} or {2}.", '`#workbench.activityBar.location#`', '`top`', '`bottom`'),
|
||||
},
|
||||
[LayoutSettings.ACTIVITY_BAR_COMPACT]: {
|
||||
'type': 'boolean',
|
||||
'default': false,
|
||||
'markdownDescription': localize({ comment: ['This is the description for a setting'], key: 'activityBarCompact' }, "Controls whether the Activity Bar uses a compact layout with smaller icons and reduced width. This setting only applies when {0} is set to {1}.", '`#workbench.activityBar.location#`', '`default`'),
|
||||
},
|
||||
'workbench.activityBar.iconClickBehavior': {
|
||||
'type': 'string',
|
||||
'enum': ['toggle', 'focus'],
|
||||
|
||||
@@ -43,6 +43,7 @@ export const enum ZenModeSettings {
|
||||
export const enum LayoutSettings {
|
||||
ACTIVITY_BAR_LOCATION = 'workbench.activityBar.location',
|
||||
ACTIVITY_BAR_AUTO_HIDE = 'workbench.activityBar.autoHide',
|
||||
ACTIVITY_BAR_COMPACT = 'workbench.activityBar.compact',
|
||||
EDITOR_TABS_MODE = 'workbench.editor.showTabs',
|
||||
EDITOR_ACTIONS_LOCATION = 'workbench.editor.editorActionsLocation',
|
||||
COMMAND_CENTER = 'window.commandCenter',
|
||||
|
||||
@@ -214,7 +214,7 @@ suite('KeybindingsEditorModel', () => {
|
||||
});
|
||||
|
||||
test('filter by command id', async () => {
|
||||
const id = 'workbench.action.increaseViewSize';
|
||||
const id = 'workbench.action.view.size.' + uuid.generateUuid();
|
||||
registerCommandWithTitle(id, 'some title');
|
||||
prepareKeybindingService();
|
||||
|
||||
|
||||
@@ -0,0 +1,284 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import assert from 'assert';
|
||||
import { DisposableStore } from '../../../../../base/common/lifecycle.js';
|
||||
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';
|
||||
import { TestConfigurationService } from '../../../../../platform/configuration/test/common/testConfigurationService.js';
|
||||
import { TestThemeService } from '../../../../../platform/theme/test/common/testThemeService.js';
|
||||
import { TestStorageService } from '../../../common/workbenchTestServices.js';
|
||||
import { TestLayoutService } from '../../workbenchTestServices.js';
|
||||
import { ActivitybarPart } from '../../../../browser/parts/activitybar/activitybarPart.js';
|
||||
import { IViewSize } from '../../../../../base/browser/ui/grid/grid.js';
|
||||
import { LayoutSettings, Parts } from '../../../../services/layout/browser/layoutService.js';
|
||||
import { mainWindow } from '../../../../../base/browser/window.js';
|
||||
import { IConfigurationChangeEvent } from '../../../../../platform/configuration/common/configuration.js';
|
||||
import { IPaneCompositePart } from '../../../../browser/parts/paneCompositePart.js';
|
||||
import { Event, Emitter } from '../../../../../base/common/event.js';
|
||||
import { IPaneComposite } from '../../../../common/panecomposite.js';
|
||||
import { PaneCompositeDescriptor } from '../../../../browser/panecomposite.js';
|
||||
import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js';
|
||||
|
||||
class StubPaneCompositePart implements IPaneCompositePart {
|
||||
declare readonly _serviceBrand: undefined;
|
||||
readonly partId = Parts.SIDEBAR_PART;
|
||||
element: HTMLElement = undefined!;
|
||||
minimumWidth = 0;
|
||||
maximumWidth = 0;
|
||||
minimumHeight = 0;
|
||||
maximumHeight = 0;
|
||||
onDidChange = Event.None;
|
||||
onDidPaneCompositeOpen = new Emitter<IPaneComposite>().event;
|
||||
onDidPaneCompositeClose = new Emitter<IPaneComposite>().event;
|
||||
openPaneComposite(): Promise<IPaneComposite | undefined> { return Promise.resolve(undefined); }
|
||||
getPaneComposites(): PaneCompositeDescriptor[] { return []; }
|
||||
getPaneComposite(): PaneCompositeDescriptor | undefined { return undefined; }
|
||||
getActivePaneComposite(): IPaneComposite | undefined { return undefined; }
|
||||
getProgressIndicator() { return undefined; }
|
||||
hideActivePaneComposite(): void { }
|
||||
getLastActivePaneCompositeId(): string { return ''; }
|
||||
getPinnedPaneCompositeIds(): string[] { return []; }
|
||||
getVisiblePaneCompositeIds(): string[] { return []; }
|
||||
getPaneCompositeIds(): string[] { return []; }
|
||||
layout(): void { }
|
||||
dispose(): void { }
|
||||
}
|
||||
|
||||
suite('ActivitybarPart', () => {
|
||||
|
||||
const disposables = new DisposableStore();
|
||||
|
||||
let fixture: HTMLElement;
|
||||
const fixtureId = 'activitybar-part-fixture';
|
||||
|
||||
setup(() => {
|
||||
fixture = document.createElement('div');
|
||||
fixture.id = fixtureId;
|
||||
mainWindow.document.body.appendChild(fixture);
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
fixture.remove();
|
||||
disposables.clear();
|
||||
});
|
||||
|
||||
function createActivitybarPart(compact: boolean): { part: ActivitybarPart; configService: TestConfigurationService } {
|
||||
const configService = new TestConfigurationService({
|
||||
[LayoutSettings.ACTIVITY_BAR_COMPACT]: compact,
|
||||
});
|
||||
const storageService = disposables.add(new TestStorageService());
|
||||
const themeService = new TestThemeService();
|
||||
const layoutService = new TestLayoutService();
|
||||
|
||||
// Override isVisible to return false so that create() does not call show()
|
||||
// and attempt to instantiate the composite bar (which requires a full DI setup).
|
||||
layoutService.isVisible = (_part: Parts) => false;
|
||||
|
||||
// Stub instantiation service—createCompositeBar is only called in show(),
|
||||
// which we skip in unit tests focused on dimensions / style behaviour.
|
||||
const stubInstantiationService = { createInstance: () => { throw new Error('not expected'); } } as unknown as IInstantiationService;
|
||||
|
||||
const part = disposables.add(new ActivitybarPart(
|
||||
new StubPaneCompositePart(),
|
||||
stubInstantiationService,
|
||||
layoutService,
|
||||
themeService,
|
||||
storageService,
|
||||
configService,
|
||||
));
|
||||
|
||||
return { part, configService };
|
||||
}
|
||||
|
||||
function fireConfigChange(configService: TestConfigurationService, key: string): void {
|
||||
configService.onDidChangeConfigurationEmitter.fire({
|
||||
affectsConfiguration: (k: string) => k === key,
|
||||
} satisfies Partial<IConfigurationChangeEvent> as unknown as IConfigurationChangeEvent);
|
||||
}
|
||||
|
||||
// --- Static constants ---------------------------------------------------
|
||||
|
||||
test('default constants match original (pre-compact) dimensions', () => {
|
||||
assert.deepStrictEqual(
|
||||
{
|
||||
width: ActivitybarPart.ACTIVITYBAR_WIDTH,
|
||||
actionHeight: ActivitybarPart.ACTION_HEIGHT,
|
||||
iconSize: ActivitybarPart.ICON_SIZE,
|
||||
},
|
||||
{
|
||||
width: 48,
|
||||
actionHeight: 48,
|
||||
iconSize: 24,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test('compact constants match reduced dimensions', () => {
|
||||
assert.deepStrictEqual(
|
||||
{
|
||||
width: ActivitybarPart.COMPACT_ACTIVITYBAR_WIDTH,
|
||||
actionHeight: ActivitybarPart.COMPACT_ACTION_HEIGHT,
|
||||
iconSize: ActivitybarPart.COMPACT_ICON_SIZE,
|
||||
},
|
||||
{
|
||||
width: 36,
|
||||
actionHeight: 32,
|
||||
iconSize: 16,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// --- Dimension getters --------------------------------------------------
|
||||
|
||||
test('default mode returns default width constraints', () => {
|
||||
const { part } = createActivitybarPart(false);
|
||||
assert.deepStrictEqual(
|
||||
{ min: part.minimumWidth, max: part.maximumWidth },
|
||||
{ min: ActivitybarPart.ACTIVITYBAR_WIDTH, max: ActivitybarPart.ACTIVITYBAR_WIDTH }
|
||||
);
|
||||
});
|
||||
|
||||
test('compact mode returns compact width constraints', () => {
|
||||
const { part } = createActivitybarPart(true);
|
||||
assert.deepStrictEqual(
|
||||
{ min: part.minimumWidth, max: part.maximumWidth },
|
||||
{ min: ActivitybarPart.COMPACT_ACTIVITYBAR_WIDTH, max: ActivitybarPart.COMPACT_ACTIVITYBAR_WIDTH }
|
||||
);
|
||||
});
|
||||
|
||||
test('height constraints are unbounded', () => {
|
||||
const { part } = createActivitybarPart(false);
|
||||
assert.strictEqual(part.minimumHeight, 0);
|
||||
assert.strictEqual(part.maximumHeight, Number.POSITIVE_INFINITY);
|
||||
});
|
||||
|
||||
// --- Configuration change: dimension update ----------------------------
|
||||
|
||||
test('toggling compact via config changes width constraints', () => {
|
||||
const { part, configService } = createActivitybarPart(false);
|
||||
|
||||
// Initially default
|
||||
assert.strictEqual(part.minimumWidth, ActivitybarPart.ACTIVITYBAR_WIDTH);
|
||||
|
||||
// Switch to compact
|
||||
configService.setUserConfiguration(LayoutSettings.ACTIVITY_BAR_COMPACT, true);
|
||||
fireConfigChange(configService, LayoutSettings.ACTIVITY_BAR_COMPACT);
|
||||
|
||||
assert.deepStrictEqual(
|
||||
{ min: part.minimumWidth, max: part.maximumWidth },
|
||||
{ min: ActivitybarPart.COMPACT_ACTIVITYBAR_WIDTH, max: ActivitybarPart.COMPACT_ACTIVITYBAR_WIDTH }
|
||||
);
|
||||
|
||||
// Switch back to default
|
||||
configService.setUserConfiguration(LayoutSettings.ACTIVITY_BAR_COMPACT, false);
|
||||
fireConfigChange(configService, LayoutSettings.ACTIVITY_BAR_COMPACT);
|
||||
|
||||
assert.deepStrictEqual(
|
||||
{ min: part.minimumWidth, max: part.maximumWidth },
|
||||
{ min: ActivitybarPart.ACTIVITYBAR_WIDTH, max: ActivitybarPart.ACTIVITYBAR_WIDTH }
|
||||
);
|
||||
});
|
||||
|
||||
// --- onDidChange fires for grid ----------------------------------------
|
||||
|
||||
test('fires onDidChange(undefined) when compact setting changes', () => {
|
||||
const { part, configService } = createActivitybarPart(false);
|
||||
|
||||
const events: (IViewSize | undefined)[] = [];
|
||||
disposables.add(part.onDidChange(e => events.push(e)));
|
||||
|
||||
// Toggle to compact
|
||||
configService.setUserConfiguration(LayoutSettings.ACTIVITY_BAR_COMPACT, true);
|
||||
fireConfigChange(configService, LayoutSettings.ACTIVITY_BAR_COMPACT);
|
||||
|
||||
assert.strictEqual(events.length, 1);
|
||||
assert.strictEqual(events[0], undefined, 'should fire undefined to signal constraint change');
|
||||
|
||||
// Toggle back
|
||||
configService.setUserConfiguration(LayoutSettings.ACTIVITY_BAR_COMPACT, false);
|
||||
fireConfigChange(configService, LayoutSettings.ACTIVITY_BAR_COMPACT);
|
||||
|
||||
assert.strictEqual(events.length, 2);
|
||||
assert.strictEqual(events[1], undefined);
|
||||
});
|
||||
|
||||
test('does not fire onDidChange for unrelated config changes', () => {
|
||||
const { part, configService } = createActivitybarPart(false);
|
||||
|
||||
const events: (IViewSize | undefined)[] = [];
|
||||
disposables.add(part.onDidChange(e => events.push(e)));
|
||||
|
||||
fireConfigChange(configService, 'editor.fontSize');
|
||||
|
||||
assert.strictEqual(events.length, 0);
|
||||
});
|
||||
|
||||
// --- CSS custom properties on element -----------------------------------
|
||||
|
||||
test('updateCompactStyle sets correct CSS custom properties in default mode', () => {
|
||||
const { part } = createActivitybarPart(false);
|
||||
|
||||
const el = document.createElement('div');
|
||||
fixture.appendChild(el);
|
||||
part.create(el);
|
||||
|
||||
assert.strictEqual(el.style.getPropertyValue('--activity-bar-width'), `${ActivitybarPart.ACTIVITYBAR_WIDTH}px`);
|
||||
assert.strictEqual(el.style.getPropertyValue('--activity-bar-action-height'), `${ActivitybarPart.ACTION_HEIGHT}px`);
|
||||
assert.strictEqual(el.style.getPropertyValue('--activity-bar-icon-size'), `${ActivitybarPart.ICON_SIZE}px`);
|
||||
assert.strictEqual(el.classList.contains('compact'), false);
|
||||
});
|
||||
|
||||
test('updateCompactStyle sets correct CSS custom properties in compact mode', () => {
|
||||
const { part } = createActivitybarPart(true);
|
||||
|
||||
const el = document.createElement('div');
|
||||
fixture.appendChild(el);
|
||||
part.create(el);
|
||||
|
||||
assert.strictEqual(el.style.getPropertyValue('--activity-bar-width'), `${ActivitybarPart.COMPACT_ACTIVITYBAR_WIDTH}px`);
|
||||
assert.strictEqual(el.style.getPropertyValue('--activity-bar-action-height'), `${ActivitybarPart.COMPACT_ACTION_HEIGHT}px`);
|
||||
assert.strictEqual(el.style.getPropertyValue('--activity-bar-icon-size'), `${ActivitybarPart.COMPACT_ICON_SIZE}px`);
|
||||
assert.strictEqual(el.classList.contains('compact'), true);
|
||||
});
|
||||
|
||||
test('toggling compact updates CSS custom properties on element', () => {
|
||||
const { part, configService } = createActivitybarPart(false);
|
||||
|
||||
const el = document.createElement('div');
|
||||
fixture.appendChild(el);
|
||||
part.create(el);
|
||||
|
||||
// Default state
|
||||
assert.strictEqual(el.style.getPropertyValue('--activity-bar-width'), `${ActivitybarPart.ACTIVITYBAR_WIDTH}px`);
|
||||
assert.strictEqual(el.classList.contains('compact'), false);
|
||||
|
||||
// Switch to compact
|
||||
configService.setUserConfiguration(LayoutSettings.ACTIVITY_BAR_COMPACT, true);
|
||||
fireConfigChange(configService, LayoutSettings.ACTIVITY_BAR_COMPACT);
|
||||
|
||||
assert.strictEqual(el.style.getPropertyValue('--activity-bar-width'), `${ActivitybarPart.COMPACT_ACTIVITYBAR_WIDTH}px`);
|
||||
assert.strictEqual(el.style.getPropertyValue('--activity-bar-action-height'), `${ActivitybarPart.COMPACT_ACTION_HEIGHT}px`);
|
||||
assert.strictEqual(el.style.getPropertyValue('--activity-bar-icon-size'), `${ActivitybarPart.COMPACT_ICON_SIZE}px`);
|
||||
assert.strictEqual(el.classList.contains('compact'), true);
|
||||
|
||||
// Switch back
|
||||
configService.setUserConfiguration(LayoutSettings.ACTIVITY_BAR_COMPACT, false);
|
||||
fireConfigChange(configService, LayoutSettings.ACTIVITY_BAR_COMPACT);
|
||||
|
||||
assert.strictEqual(el.style.getPropertyValue('--activity-bar-width'), `${ActivitybarPart.ACTIVITYBAR_WIDTH}px`);
|
||||
assert.strictEqual(el.style.getPropertyValue('--activity-bar-action-height'), `${ActivitybarPart.ACTION_HEIGHT}px`);
|
||||
assert.strictEqual(el.style.getPropertyValue('--activity-bar-icon-size'), `${ActivitybarPart.ICON_SIZE}px`);
|
||||
assert.strictEqual(el.classList.contains('compact'), false);
|
||||
});
|
||||
|
||||
// --- toJSON ------------------------------------------------------------
|
||||
|
||||
test('toJSON returns correct part type', () => {
|
||||
const { part } = createActivitybarPart(false);
|
||||
assert.deepStrictEqual(part.toJSON(), { type: Parts.ACTIVITYBAR_PART });
|
||||
});
|
||||
|
||||
ensureNoDisposablesAreLeakedInTestSuite();
|
||||
});
|
||||
Reference in New Issue
Block a user