microsoft / fluentui

Fluent UI web represents a collection of utilities, React components, and web components for building web applications.
https://react.fluentui.dev
Other
18.36k stars 2.72k forks source link

Tooltip: refactor to minimize bundle impact and use consistently. #5541

Closed dzearing closed 3 years ago

dzearing commented 6 years ago

Currently, the custom Tooltip ends up being quite heavy on the page. Just using it pulls in Layer, positioning, Callout, etc. and adds a number of individual mouseover/out events to manage each individual scenario. It also add an element to host those events.

I'd like Tooltip to use the same pattern we used for managing Keytips. I'd like a way to annotate elements with tooltip data, and then lazy load a single TooltipManage component on the page to contain the "hover and show this ui" code. This should reduce PLT1 bundle sizes, but also help us to make tooltips render consistently.

Proposal:

We need some sort of non-html annotation to contain the tooltip:

Preferred option (this is best because we can have TooltipData cache props in a singleton dictionary and output a key in the data attribute. The dictionary can be cleaned on unmount. This lets us support more than just string literals, such as custom tooltips):

<TooltipData text='hello, world'>{ tooltip => 
  <button {...tooltip}>I am a button</button>
</TooltipData>

Alternative #1 (This is just to illustrate what the TooltipData helper would inject. Downside of literal strings: no type safety, no way to do custom tooltips):

<button data-tooltip='hello, world'>I am a button</button>

Alternative #2 (downside: tooltip data can't be easily serialized if it has more than just strings, e.g. custom tooltips)

<button { ...tooltipData({ text: 'hello, world' }) }> I am a button</button>

Side note: for Fabric components which pass in title as a prop, we would need to internally translate all of those instances to use this. That would enforce we don't render the default title prop, but rather, the custom Tooltip.

Then, lazily the consumer renders the TooltipHost, which would watch for mouseover/out events and data-tooltip attributes, and render the appropriate thing at the appropriate time. This is a little more frictiony for consumers (they have to render a TooltipHost manually in their app somewhere. It also means library authors dependent on Fabric have to have that as a requirement for app developers, which is also frictiony.)

We could address the library dependency issue by allowing for multiple tooltip hosts to be rendered, and then only having one of them actively rendering tooltips.

msft-fluent-ui-bot commented 3 years ago

Because this issue has not had activity for over 150 days, we're automatically closing it for house-keeping purposes.

Still require assistance? Please, create a new issue with up-to date details.