Tooltip v4#1812
Open
bendansby wants to merge 2 commits into
Open
Conversation
Clean-break rewrite of Tooltip.V3 with a much smaller surface area: - Single positioning attribute family: above/below/before/after, plus align Start/Middle/End. Replaces 16 V3 functions (4 directions × 4 breakpoints) and 12 align functions (3 alignments × 4 breakpoints). - forBreakpoint Mobile/QuizEngineMobile/NarrowMobile [ ... ] replaces the *ForMobile / *ForQuizEngineMobile / *ForNarrowMobile variants. - Auto-flipping is the default: the tooltip moves to the opposite side only if the preferred side would clip the viewport. Opt out with noFlip. - Padding and width are single sum-typed attributes rather than three separate functions each. Auto-flipping is powered by a new <nri-tooltip-auto> custom element that observes the trigger (ResizeObserver + scroll/resize) and writes data-position / data-align attributes on the tooltip element. The tooltip's position/align CSS is keyed off those attributes so the flip happens without an Elm re-render. V3 is left untouched. Consumers migrate at their own pace. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ound. - Render the V4 tooltip tail with attribute-keyed `::before`/`::after` pseudo-elements so the JS auto-flip moves the tail with the bubble without an Elm re-render. Honors `withoutTail` via a `data-tail` attribute the global rule responds to. - Switch the custom element's update strategy to a continuous `requestAnimationFrame` loop while connected so dragging the trigger updates the orientation in real time (ResizeObserver alone misses position-only changes via ancestor `left`/`top`). - Reset `transform`/`left`/`right` on each align so the JS swap from `middle` -> `start`/`end` correctly clears the centering transform. - Bump default offset from 8px to 12px, normal padding to 16px, small padding to 8px 12px, font size to 15px, and add Shadows.high. - Catalog: add an interactive auto-flip playground that takes over the page with a draggable trigger, inheriting the customizable example's attributes so users can experiment with `noFlip`/`withoutTail`/etc. - Catalog body: set `Fonts.baseFont` + `Css.color gray20` + `line-height: 1.5` globally so unstyled text inherits Muli rather than Times New Roman. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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.
Context
Nri.Ui.Tooltip.V3had grown a large surface area — 16 directional functions (4 sides × 4 breakpoints), 12 alignment functions (3 alignments × 4 breakpoints), four*Cssbreakpoint helpers, three padding functions, two width functions — and still required callers to pre-decide which side the tooltip should appear on. When tooltips appeared near a viewport edge, they clipped instead of flipping.V4 is a clean-break rewrite. Same a11y semantics, much smaller API, and tooltips auto-flip when they would otherwise clip the viewport.
V3 is untouched. Existing consumers keep working.
🔧 What changes
New module:
Nri.Ui.Tooltip.V4above/below/before/after(logical, RTL-friendly). Auto-flipping is on by default — these are preferred sides, and the tooltip moves to the opposite side only if it would clip.align Start | Middle | End. (Plus convenience wrappersalignStart/alignMiddle/alignEnd.) The pixel-offset arg is gone.forBreakpoint Tooltip.mobile [ Tooltip.below, Tooltip.alignStart ]replaces all 28 of V3's*ForMobile/*ForQuizEngineMobile/*ForNarrowMobiledirection and alignment variants and the per-breakpoint*Csshelpers.padding (Padding)withSmall/Normal/Custom Float,width IntorfitToContent.flip/noFlipto opt out of auto-flipping.offset Floatto tune the gap between trigger and tooltip (default 12px, was hardcoded in V3).primaryLabel,auxiliaryDescription,helpfullyDisabled,disclosure.onToggle,onTriggerKeyDown,open.css,custom,nriDescription,testId.Auto-flipping engine
Powered by a new
<nri-tooltip-auto>custom element (lib/Tooltip/V4.js):flipis enabled (default).requestAnimationFrameloop while connected; on each frame, reads the trigger's bounding rect and only rewritesdata-position/data-alignwhen the rect changed. This is the same approach Floating UI uses forautoUpdate, and catches every kind of position change including ancestor-driven movement (e.g. drag).[data-position="…"]/[data-align="…"]attributes viaCss.Globalrules, so the flip happens without an Elm re-render.Catalog
Examples/Tooltip.elmmigrated to V4 (version bumped to 4). Direction/alignment controls flattened from 8 to 2; per-breakpoint multipliers gone.noFlip/withoutTail/ padding / etc. while dragging.Fonts.baseFont,gray20color, andline-height: 1.5set globally so unstyled text on example pages inherits Muli rather than Times New Roman.Migration
onTopaboveonBottombelowonLeftbeforeonRightafteralignStart 10alignStart(offset removed)alignMiddlealignMiddle(or omit — default)alignEnd 10alignEndonTopForMobileforBreakpoint Tooltip.mobile [ above ]alignMiddleForMobileforBreakpoint Tooltip.mobile [ alignMiddle ]mobileCss [...]forBreakpoint Tooltip.mobile [ css [...] ]exactWidth 320exactWidth 320(kept)fitToContentfitToContent(kept)smallPadding/normalPadding/customPadding xsmallPadding/normalPadding/customPadding x(kept) orpadding Small/ etc.Most of the migration is mechanical find-and-replace. The biggest win is callers that today need 6+ attributes to express different behavior at three breakpoints — those collapse to three
forBreakpointcalls.Component completion checklist
@docs-edNotes for reviewers
lib/Tooltip/V4.js, which is required bylib/index.jsand so loads automatically wherever the noredink-ui JS is bundled (catalog included). Apps that bundle Elm withoutnoredink-ui/libwould lose auto-flip and fall back to whatever side was passed (no flip), which is graceful but worth flagging.viewToggleTipyet. The "?" icon helper is V3-only for now; consumers using it should stay on V3 until we port it.Css.Global.globalinside the tooltip), and the JS just toggles attributes. Slightly more CSS in the page than V3, but simpler to reason about and cheaper at flip-time (no re-render).primaryLabelis still the default — keep usingauxiliaryDescription/helpfullyDisabled/disclosureconsciously.