These are the problems most likely to burn time after a component choice already looks correct on paper. Review them before wiring production overlays, keyboard navigation, or mixed controlled/uncontrolled state.
PortalProvider is not optional in serious overlay trees
What breaks
Dialog, Popover, Select, Combobox, Menu, Tooltip, and Toast can all render without a shared app-level portal target, but layering becomes harder to reason about immediately.
What to do
Mount one PortalProvider near the app root with a stable
PlayerGui container, then let overlay packages inherit it.
Overlay stacking failures usually come from split ownership
What breaks
Two overlays can both look correct in isolation but fight once one trigger lives under a different provider or display-order base.
What to do
Keep one stacking model per app shell. If you need custom layering, do it through the shared layer primitives instead of ad hoc ScreenGui trees.
Layering, portals, and presence need one lifecycle
What breaks
Portal content can unmount as soon as open flips false, while
presence or exit motion still expects the subtree to exist. The result is
a flash, missing exit transition, or stale dismissable layer.
What to do
Let Layer own mounting and stacking, then let Motion own the animated phase while the content remains mounted through exit completion.
Motion should not fight Popper placement
What breaks
Anchored surfaces drift or measure incorrectly when custom animation code changes the same position, anchor, or size properties that Popper uses for placement.
What to do
Keep Popper responsible for anchor geometry. Animate an isolated appearance or offset wrapper through Motion so placement can update without being treated as animation state.
Dialog overlay and panel motion are separate concerns
What breaks
A dialog feels wrong when one transition tries to own backdrop opacity, panel reveal, focus trapping, and dismissal at the same time.
What to do
Keep Dialog.Overlay and Dialog.Content visually
independent. Dialog owns interaction semantics; Motion owns the overlay
fade and panel transition without changing the focus contract.
forceMount is not an exit-motion switch by itself
What breaks
forceMount keeps a subtree in the React tree, but it does not
automatically define which phase is visible, exiting, or inert.
What to do
Use forceMount for measurement or retained state, then pair it
with presence-aware behavior when users should see an exit transition.
Closed content still needs correct visibility and interaction state.
Focus contracts matter more than visuals
What breaks
Dialogs and trapped scopes feel flaky when they open from triggers that cannot receive focus again or when restore paths are implicit.
What to do
Treat the trigger as part of the focus contract. Use
restoreFocus intentionally and keep trigger ownership stable
when possible.
Keyboard flow must survive open, exit, and restore
What breaks
Trapped scopes can restore to a missing trigger, move focus into exiting content, or let keyboard selection escape while an overlay is still visually present.
What to do
Treat open state, presence state, and focus scope state as one interaction contract. Keep triggers stable, restore focus intentionally, and validate keyboard flow in Roblox after preview iteration.
Disabled items still need deliberate product behavior
What breaks
Disabled items disappear from interaction, but product state often still assumes they can be selected, focused, or announced like normal options.
What to do
Model disabled items as truly unavailable. In selection controls, expect keyboard and directional movement to skip them and keep labels explicit in the rendered host.
Controlled/uncontrolled transitions should be treated as a design choice
What breaks
Moving a component between defaultValue and
value modes mid-flow creates hard-to-debug state handoff
issues, especially when the control also owns open or
inputValue.
What to do
Pick ownership up front. If app state should be the source of truth, control the component from the start; otherwise keep it fully uncontrolled and mirror only committed changes outward.
Preview is useful, but Roblox runtime is authoritative
What breaks
Loom preview can make an overlay, motion recipe, or focus path look done even though Roblox Studio input, selection, timing, or rendering behaves differently.
What to do
Use preview for fast iteration and screenshots, then manually verify final behavior in the Roblox runtime. Preview is not the source of truth for shipping keyboard, focus, layering, or motion correctness.
Cross-check pages
- Read Layer when the issue is where overlays mount or why display order feels unstable.
- Read Motion when the issue is presence, exit timing, reduced motion, or response/feedback behavior.
- Read Focus when the issue is trapped selection, restore behavior, or nested focus regions.
- Read Select and Combobox when the issue is mixed value, input, and open ownership.
- Read Dialog and Popover when the issue is interaction ownership rather than styling.