react

"mulling over state management stuff"
lilactown 2021-03-26T01:04:40.015Z

I would use a custom hook

lilactown 2021-03-26T01:06:36.016500Z

(let [[ref show hide] (use-tooltip {:msg "My tooltip"})]
  (ui/ButtonIcon
   {:ref ref
    :on-mouse-enter show
    :on-mouse-leave hide}
   "Click here"))

lilactown 2021-03-26T01:15:25.019Z

if you wanted to add the tooltip to the react tree as well rather than do some mutable DOM ops (not sure what kind of library you're using), you could return the element:

(let [[ref Tooltip show hide] (use-tooltip)]
  (div
   (ui/ButtonIcon
    {:ref ref
     :on-mouse-enter show
     :on-mouse-leave hide}
    "Click here")
   (Tooltip {:msg "My Tooltip"})))

2021-03-26T07:44:07.023200Z

One thing about tooltips to keep in mind, that most likely you'll want to move them to the end of the DOM into a separate layer that sits above application root, so that tooltips are displayed above everything else, similar to popups. While it's not as frequently needed as for popups, tooltips could be cut off when displayed in elements with overflow: hidden, thus moving them to a separate layer would help.

2021-03-26T07:46:02.025500Z

In case of a separate layer a custom hook makes more sense. But since tooltip live in a diff part of the UI tree you'll need some kind of shared state (context or global state, etc)

raspasov 2021-03-26T08:22:58.033300Z

This is a very good point about the separate layer. What trick do you use to position them relative to the “originating” element that triggered the tooltip? Somehow measure the absolute positioning of the “originating” element and position the tooltip relative to that?

2021-03-26T08:36:26.033700Z

Correct. Layout effect hook is a good fit for measuring position of an element.

👍 1
orestis 2021-03-26T08:49:26.034600Z

We are using popper.js and its React integration with good results. A bit fiddly to setup initially but works like a charm.

orestis 2021-03-26T08:51:04.035400Z

This, plus a Portal to deal with adding the popups to their own div at the end of the body -- actually we have an OverlayContext so that nested popups work as expected.

martinklepsch 2021-03-26T09:03:09.036500Z

Also using popper.js and it’s userPopper hook. Currently we don’t use portals yet, so far I’ve been able to fix overflow hidden issues with the different positioning strategy https://popper.js.org/docs/v2/constructors/#strategy

martinklepsch 2021-03-26T09:05:22.037100Z

The Portal approach sounds nice in a way because it would mean the consumer does not need to place the popover element inside the DOM. EDIT: actually it seems like calls to createPortal should go into render so I think the Portal approach would still require that.

martinklepsch 2021-03-26T09:06:15.038200Z

@orestis I’m not quite sure what the OverlayContext helps you with, do you mind expanding on that a bit?

orestis 2021-03-26T09:38:59.040Z

Imagine you have a scrollable modal. You want the popup to be attached as the last child of that, so that it would naturally scroll when the content scrolls (otherwise it can be janky). Similar if you have a modal and a popup inside the modal, you want to use the same dom hierarchy so you can easily implement things like "on-click-outside, close the popup".

2021-03-26T11:33:17.042200Z

In case of scrolling, that depends. I think a common behaviour in OSs is to close tooltips when scrolling and block scrolling when a context menu is open

orestis 2021-03-26T11:39:59.044200Z

I was investigating native select components the other day. Native popups can even breakout of the browser chrome. Shame we have to reimplement a worse version :(

orestis 2021-03-26T11:40:12.044600Z

Worse in the ui integration sense I mean.