Add section to UX guidelines for hover
What to include
- Different hover styles
- When to use each one
- Examples
To do
- [ ] Research existing hover documentation
- [ ] Determine what applies to our use cases
- [ ] Determine what needs to be written from scratch
- [ ] Create decision tree/flow diagram to help people make the right choice
fyi @Tyriar
Here are my notes I presented and action items at the end:
Hover consistency
Background
- Rich content
- Better looking than standard
- More control
Custom vs native
The custom hover is mostly spread throughout the workbench but there are some cases where title is still used:
Default setupDelayedHover
setupDelayedHover(target, { content })
Shows above the target element, aligned to the top-left.
This top-left behavior originated from monaco.
Default setupDelayedHoverAtMouse
setupDelayedHoverAtMouse({ content })
Shows just below and to the right of the cursor.
This aligns closest with the native title hover.
Locking
Normally you can only mouse over the hover if it contains a link or action in the status bar.
Holding alt will "lock" the hover, adding a 2px border and making the hover not go away when the mouse is moved, regardless of the specific options used. This is an accessibility feature useful to all to select text or when we explicitly hideOnHover.
Options
There are many options that allow devs a lot of control on how these hovers are shown. The biggest one being showPointer which centers the hover and adds a pointer.
Some examples:
Activity bar
this._register(this.hoverService.setupDelayedHover(this.container, () => ({
content: this.computeTitle(),
position: {
hoverPosition: this.options.hoverOptions.position(),
},
persistence: {
hideOnKeyDown: true,
},
appearance: {
showPointer: true,
compact: true,
}
}), { groupId: 'composite-bar-actions' }));
Terminal tab
return this._hoverService.showDelayedHover({
...options,
actions: context.hoverActions,
target: element,
appearance: {
showPointer: true
},
position: {
hoverPosition: this._terminalConfigurationService.config.tabs.location === 'left' ? HoverPosition.RIGHT : HoverPosition.LEFT
}
}, { groupId: 'terminal-tabs-list' });
Extension view item
This uses the simpler API meaning it must manage the groupId and delay logic itself:
return this.hoverService.showHover({
...options,
additionalClasses: ['extension-hover'],
position: {
hoverPosition: this.options.position(),
forcePosition: true,
},
persistence: {
hideOnKeyDown: true,
}
}, focus);
Questions
- When should we use the 3 main types?
- At mouse (no pointer)
- Aligned with element/text (no pointer)
- With pointer and centered
- Should this be the default for
showDelayedHover? Should we have ashowDelayedHoverWithPointer? - Naming could be "PointerHover" and "MouseHover"?
- TextHover vs Regular (pointer)?
- Should this be the default for
- Should
hideOnKeyDown: truebe the default?- Probably flip default, understand why
compactis used inconsistently. When should we use this?- Could we get rid of
forcePositionif we handled the small space case better?- A lot of times this is used to force a horizontal only position.
- If we marked a hover as horizontally (sidebar) or vertically (status bar) positioned, maybe we could avoid being explicit about the exact position and avoid the need for
forcePositionas it's implied?
Internal API for the VS Code devs: https://github.com/microsoft/vscode/blob/d81f6ad5b8fe26ed793a47e6911d75bafee7b3de/src/vs/base/browser/ui/hover/hover.ts#L12-L376
Action items
- UX to dig up MS guidelines, we should read those and come up with our own guidelines
hideOnKeyDown: trueshould be the default? Maybe we don't need it at all?compact: trueis a special case, we need clear guidelines to follow- Add
hoverPosition: 'horizontal' | 'vertical'which should renderforcePositionmaybe obsolete completely and simplify usage - Aligning with text should be a special case not the default
- Change
showHovertoshowInstantHover, andshowDelayedHover*toshowHover*?showDelayedHover->showHoverAtTextshowDelayedHoverAtMouse->showHoverAtMouseshowDelayedHoverwill defaultshowPointer: true?