Skip to content

lightweight update button styling#304877

Draft
eli-w-king wants to merge 1 commit intomainfrom
eli/update-styling
Draft

lightweight update button styling#304877
eli-w-king wants to merge 1 commit intomainfrom
eli/update-styling

Conversation

@eli-w-king
Copy link
Contributor

No description provided.

Copilot AI review requested due to automatic review settings March 25, 2026 19:34
@eli-w-king eli-w-king self-assigned this Mar 25, 2026
@vs-code-engineering vs-code-engineering bot added this to the 1.114.0 milestone Mar 25, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR modernizes the update indicator UI by refining the title bar “Update” button presentation and restructuring the update tooltip to a more compact, action-oriented layout consistent with newer workbench UI patterns.

Changes:

  • Reworked the update tooltip layout (stepper, actions row, collapsible “Details”) and updated associated styles.
  • Enhanced the title bar update indicator label/hint behavior and updated its styling.
  • Added a dev-only hook for local update-state simulation via an ignored test contribution.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/vs/workbench/contrib/update/browser/updateTooltip.ts Refactors tooltip DOM structure (stepper, actions, details) and state rendering logic.
src/vs/workbench/contrib/update/browser/updateTitleBarEntry.ts Updates title bar update indicator text/hint behavior and state rendering conditions.
src/vs/workbench/contrib/update/browser/update.contribution.ts Adds a dev-only dynamic import hook for local test contributions.
src/vs/workbench/contrib/update/browser/media/updateTooltip.css Updates tooltip styling for new layout (stepper, buttons, details).
src/vs/workbench/contrib/update/browser/media/updateTitleBarEntry.css Tweaks indicator sizing and adds hover/flash hint styling.
.gitignore Ignores a local dev-only update test contribution source file.
Comments suppressed due to low confidence (2)

src/vs/workbench/contrib/update/browser/updateTitleBarEntry.ts:151

  • onStateChange now returns early when this.tooltipVisible or when the window didn't have last focus, which prevents this.tooltip.renderState(this.state) from running. This can leave the tooltip (and hover content) stale if the update state changes while the window is unfocused or while the tooltip is already open. Consider always rendering the new state into the tooltip, and only gating the auto-show behavior behind focus/visibility checks (similar to the previous structure).
	private async onStateChange(startup = false) {
		this.updateContext();
		if (this.mode === 'none' || this.tooltipVisible || !await this.hostService.hadLastFocus()) {
			return;
		}

		let showTooltip = startup && this.detectVersionChange();
		if (showTooltip) {
			this.tooltip.renderPostInstall();
		} else {
			this.tooltip.renderState(this.state);
			switch (this.state.type) {

src/vs/workbench/contrib/update/browser/updateTooltip.ts:525

  • showAction assigns a click handler but doesn’t provide any keyboard interaction (and preventDefault() is a no-op for non-interactive elements). Once actionButton is changed to a <button>, consider attaching the handler via a disposable listener (addDisposableListener) and relying on native button semantics for keyboard activation.
		this.actionButton.style.display = '';
		this.actionButton.onclick = e => {
			e.preventDefault();
			action();
		};

Comment on lines +362 to +366
this.hintTimer = setTimeout(() => {
dom.getWindow(this.content!).requestAnimationFrame(() => {
this.content?.classList.add('hint-visible');
});

Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

flashHintOnce schedules timeouts but the handle is only cleared on subsequent state changes. If the action view item is disposed while a hint timer is pending, the callbacks can still run and mutate detached DOM. Consider registering a disposable (or overriding dispose) to clear this.hintTimer and prevent post-dispose callbacks.

Copilot uses AI. Check for mistakes.
this.runCommandAndClose('update.showCurrentReleaseNotes', this.releaseNotesVersion);
}
}));
this.actionButton = dom.append(buttonRow, dom.$('.tooltip-action'));
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actionButton is created as a plain element (div via .tooltip-action) and wired via onclick, so it’s not keyboard-focusable and won’t be announced correctly by screen readers. Prefer a semantic <button class="tooltip-action"> (or add role="button", tabindex=0, and Enter/Space key handling) to keep the tooltip actions accessible.

This issue also appears on line 521 of the same file.

Suggested change
this.actionButton = dom.append(buttonRow, dom.$('.tooltip-action'));
this.actionButton = dom.append(buttonRow, dom.$('button.tooltip-action'));

Copilot uses AI. Check for mistakes.
// Release notes link
this.releaseNotesVersion = version ?? this.productService.version;
this.releaseNotesLink.style.display = this.releaseNotesVersion ? '' : 'none';
this.releaseDateNode.style.display = 'none';
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

releaseDateNode/.product-release-date is currently always hidden (style.display = 'none') and never set to visible anywhere, leaving an empty .product-info container that still contributes padding/spacing. Either remove the unused node/container or restore rendering a release date here so the layout reflects actual content.

Suggested change
this.releaseDateNode.style.display = 'none';
const releaseDate = this.productService.date;
if (releaseDate) {
const formattedDate = formatDate(new Date(releaseDate));
this.releaseDateNode.textContent = localize('updateTooltip.releaseDate', "Released on {0}", formattedDate);
this.releaseDateNode.style.display = '';
} else {
this.releaseDateNode.style.display = 'none';
}

Copilot uses AI. Check for mistakes.
Comment on lines +75 to +80
.update-tooltip .release-notes-link {
text-decoration: none;
font-size: var(--vscode-bodyFontSize-small);
}

.update-tooltip .release-notes-link:hover {
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .release-notes-link styles (and several .product-* rules above) appear to be leftovers from the previous DOM structure; the tooltip now renders the release-notes control as a.tooltip-action.secondary, and no element uses .release-notes-link. Consider removing/refreshing these unused selectors to keep the stylesheet aligned with the current markup.

Suggested change
.update-tooltip .release-notes-link {
text-decoration: none;
font-size: var(--vscode-bodyFontSize-small);
}
.update-tooltip .release-notes-link:hover {
.update-tooltip a.tooltip-action.secondary {
text-decoration: none;
font-size: var(--vscode-bodyFontSize-small);
}
.update-tooltip a.tooltip-action.secondary:hover {

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants