feat(tooltip): modernize Tooltip to Material Design 3#4994
Open
burczu wants to merge 8 commits into
Open
Conversation
Container now uses inverseSurface and text uses inverseOnSurface per the MD3 tooltip spec (previously onSurface/surface). Text variant changes from labelLarge to bodySmall (12sp). Tokens are extracted into a new tokens.ts following the FAB pattern; the rich and motion token sets land here too and are consumed in later commits.
The plain tooltip now fades in on show and out on hide using Reanimated, per the MD3 motion spec (enter short3/standardDecelerate, exit short2/standardAccelerate). Show/hide intent (visible) is split from mount state (rendered) so the tooltip stays mounted through the exit fade before unmounting. Honors reduce-motion via useReduceMotion.
Adds Tooltip.Rich, a persistent, interactive rich tooltip per the MD3 spec: an optional subhead title, supporting body text (string or element) and a row of action buttons on a surfaceContainer surface at elevation level 2 with a 12dp corner. Exposed as a compound component (Object.assign) so the plain Tooltip stays untouched. Uncontrolled tap-to-toggle: tapping the trigger toggles it, tapping the Portal backdrop or selecting an action dismisses it. On web it opens on hover and bridges the trigger-to-tooltip gap before hiding. Reuses the plain tooltip's Reanimated fade and reduce-motion handling.
Adds a 'Rich tooltips' section to the example app (full title/content/actions variant plus a body-only one), registers the RichTooltip page in the docs component map so the generated docs cover Tooltip.Rich, and cross-references the rich variant from the plain Tooltip JSDoc.
The fade lifecycle (mount-through-exit, opacity, measurement, motion configs, reduce-motion) was duplicated between Tooltip and Tooltip.Rich. Extract it into a useTooltipFade hook so both variants share one implementation. No behavior change.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
The
Tooltipcomponent had drifted from the current Material Design 3 tooltip spec, and only supported the plain (text-only) variant. As part of the v6 MD3 modernization effort (alongside TextInput, Switch, Checkbox, FAB), this brings the tooltip up to spec and adds the missing rich variant:onSurface/surface) and type style (labelLarge), and had no show/hide transition.title: stringprop can't express them.Related issue
Closes #4980.
What changed
onSurface→inverseSurface, textsurface→inverseOnSurface, type stylelabelLarge→bodySmall(12sp). Public API unchanged.short3/standardDeceleratein,short2/standardAccelerateout), and honor reduce-motion.Tooltip.Rich(compound component): an optionaltitlesubhead,content(string →bodyMedium, or a custom element for inline links), andactions(button row). Rendered on asurfaceContainerSurfaceat elevation level 2 with a 12dp corner and 312dp max-width. Uncontrolled tap-to-toggle; dismisses on outside tap, action press, or re-tap; on web it opens on hover and bridges the trigger→tooltip gap.Tooltip/tokens.ts; shared fade lifecycle extracted to auseTooltipFadehook used by both variants.RichTooltipregistered in the docs component map; JSDoc usage for both variants.Test plan
yarn test— 743 passing / 170 snapshots (extendedTooltip.test.tsxwith MD3 color/typography, fade mount-through-exit, and aTooltip.Richsuite: toggle, custom content, color roles, backdrop/action dismiss, web hover open + gap-bridge).yarn typescript,yarn lint— clean.inverseSurfacecontainer, smallerbodySmalltext, fades in/out.+on the new "Rich tooltips" row →surfaceContainercard with title/body/actions; dismisses on outside-tap, action press, or re-tap; info icon shows a body-only variant.