paragon icon indicating copy to clipboard operation
paragon copied to clipboard

z-index revamp (z-index hooks)

Open brian-smith-tcril opened this issue 1 year ago • 1 comments

from @bradenmacdonald on slack

Hey folks, does Paragon have a philosophy for handling z-index conflicts? For example, we are trying to use a Form.Autosuggest inside a modal, and the autosuggest dropdown is appearing behind parts of the modal (screenshot). I couldn't see any docs about this, and could only find these pre-defined z-index classes. If that's all that Paragon has right now, it's too simplistic. Because obviously a modal should normally be higher than a dropdown, but a dropdown in a modal should be higher than a modal. I would also argue that if you had a proper layer system, you could put popover and tooltip lower than modal as well.

One approach I know of for solving this is using utility classes (Tailwind style). Currently, the Form.Autosuggest has some code like .pgn__form-autosuggest__dropdown { ... z-index: $zindex-dropdown; ... } . Adding CSS rules to give such components a higher z-index conditionally (when they're in a modal) is problematic, because either the Autosuggest component has to be aware of all the possible layers like modals and account for them (.modal-layer & { z-index: $zindex-modal + $zindex-dropdown }) or the Modal component has to be aware of all the possible components and account for them (& .dropdown { z-index: $zindex-modal + $zindex-dropdown). => But if you use a small set of predefined classes like .zindex-dropdown so that the autosuggest has that extra utility class, then it's a bit easier to plan for the interactions like .zindex-modal .zindex-dropdown .zindex-tooltip { z-index: $zindex-modal + $zindex-dropdown + $zindex-tooltip } (a tooltip over a dropdown in a modal), and your components don't have to otherwise be aware of each other.

But as you can see from the example of "a tooltip in a dropdown in a modal", managing those rules can still get complex. So I have found that a simple zindex hook provides the cleanest solution for this problem, by using the React tree to determine the z-index of each component by using the z-index of its parent (from context) and adding some fixed amount based on the type of component. (example of use in a Modal)

brian-smith-tcril avatar Jan 10 '24 19:01 brian-smith-tcril

Apparently, using CSS isolation: isolate may be an even simpler way to solve this issue :)

Ref: https://x.com/adamwathan/status/1798704643222212683

bradenmacdonald avatar Jun 06 '24 17:06 bradenmacdonald