Conversation
621eced to
55a25a6
Compare
There was a problem hiding this comment.
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
onStateChangenow returns early whenthis.tooltipVisibleor when the window didn't have last focus, which preventsthis.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
showActionassigns a click handler but doesn’t provide any keyboard interaction (andpreventDefault()is a no-op for non-interactive elements). OnceactionButtonis 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();
};
| this.hintTimer = setTimeout(() => { | ||
| dom.getWindow(this.content!).requestAnimationFrame(() => { | ||
| this.content?.classList.add('hint-visible'); | ||
| }); | ||
|
|
There was a problem hiding this comment.
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.
| this.runCommandAndClose('update.showCurrentReleaseNotes', this.releaseNotesVersion); | ||
| } | ||
| })); | ||
| this.actionButton = dom.append(buttonRow, dom.$('.tooltip-action')); |
There was a problem hiding this comment.
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.
| this.actionButton = dom.append(buttonRow, dom.$('.tooltip-action')); | |
| this.actionButton = dom.append(buttonRow, dom.$('button.tooltip-action')); |
| // Release notes link | ||
| this.releaseNotesVersion = version ?? this.productService.version; | ||
| this.releaseNotesLink.style.display = this.releaseNotesVersion ? '' : 'none'; | ||
| this.releaseDateNode.style.display = 'none'; |
There was a problem hiding this comment.
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.
| 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'; | |
| } |
| .update-tooltip .release-notes-link { | ||
| text-decoration: none; | ||
| font-size: var(--vscode-bodyFontSize-small); | ||
| } | ||
|
|
||
| .update-tooltip .release-notes-link:hover { |
There was a problem hiding this comment.
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.
| .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 { |
No description provided.