dojo / widgets

:rocket: Dojo - UI widgets.
https://widgets.dojo.io
Other
89 stars 65 forks source link

Tooltip widget #92

Closed rishson closed 7 years ago

rishson commented 7 years ago

Specification

This widget provides tooltip behaviour.

Features

Value-add of the widget (e.g. why use rather than just use VDom directly) Ability to provide advanced styling and animation.

List of callback funcs that can be passed in props (if any) onHide onShow

Mouse/keyboard interactions (if any) Depends on the content of the tooltip. If the tooltip contained widgets, then would you need to be able to tab into this content - or is this horrendous UX 🤔 This affects the acceptance criteria.

Mandatory/valid/empty/wait states (if any) None

Is the widget controlled/uncontrolled Controlled

List of any icons needed

Design input required (inc responsive design) Look and feel of the tooltip, pointing arrow.

Any other considerations:

Questions

Acceptance criteria

When I perform an action that should make a tooltip appear, the tooltip appears, without obscuring the element that I was interacting with. When I perform an action that should make the tooltip disappear, then when the tooltip is no longer shown, the focus should be on the element that had focus before the tooltip was shown.

msssk commented 7 years ago

Tooltip design is more complicated than might first appear.

If the tooltip element is created in the DOM hierarchy adjacent to its target element, it is very easy to style and find within the DOM. The tooltip also scrolls along with its target. However, it becomes much more difficult to ensure that the tooltip is not clipped by the bounds of some ancestor node. A sophisticated z-index manager may become necessary.

If the tooltip element is created in the DOM hierarchy as a direct child of the document body, it becomes much easier to ensure that no ancestor node clips the tooltip, but it is no longer simple to locate the tooltip node as a sibling of its target, and styling becomes more complicated. In order for the tooltip to scroll with its target, scroll tracking is necessary.

Some sort of z-index manager is probably desirable to coordinate the various widgets that are interested in having top-level visibility, e.g. dialog, slidepane, tooltip.

We should also consider the behavior of tooltips opening tooltips opening tooltips...

bitpshr commented 7 years ago

@rishson I think the Dijit tooltip had logic to intelligently determine a position if the set position caused the tooltip content to be clipped by the window. Would this be v1 functionality, or should we even support this at all?

rishson commented 7 years ago

These are all good questions. Unfortunately, I think that preventing clipping is probably a v1 feature, to ensure that the tooltip doesn't look broken. I don't yet understand the implications (if any) of the design pattern of having a single tooltip widget attached to body and repositioned when shown, but doing so in a reactive friendly way.

msssk commented 7 years ago

I think positioning should definitely be a v1 feature - tooltips that lack robust positioning are of limited use.

As @rishson mentioned about reusing a single tooltip, that is also an important pattern to consider and work out the details. Some applications have hundreds (or more!) of tooltips, and they're already creating a lot of DOM simply by having the tooltip target elements - we should enable a tooltip to be reused for multiple elements when it will only ever be shown in relation to a single target at a time.

rishson commented 7 years ago

@msssk yeah - I've always used the single tooltip on the body element pattern before. Thinking outloud: each element having its own tooltip shouldn't be a problem in a reactive architecture, because, they won't be in the DOM unless they are being displayed (here I am assuming we would just render the tooltip if required rather than hide/show them).

I'm just trying to think through how you would add them. [if we wanted to abstract away from the DOM] In the widget, you'd have the onMouseOver and onMouseOut handlers that would call a onShowTooltip function (passed in in properties), which in turn would set at showTooltip property back on the widget, and in the widget render you would check for this showTooltip property and if true, would render the tooltip widget, which has been passed in as a child widget

The enclosing widget's onShowTooltip func would be very repetitive though (as it would nearly always just set the showTooltip property on the child widget), so we should try to help there.

I tried to also think about a more DOM-centric approach, using onElementCreated to get the widget's DOM node, but I don't think this approach is incompatible with passing in a tooltip widget as a child.

sebilasse commented 7 years ago

Just wanted to mention that my Semantic UI dojo2 Integration will also contain a Tooltip which is named Popup, posted a WIP preview here : https://github.com/dojo/widget-core/issues/559