Skip to content

fix(Tooltip): remove the unreleased triggerBehavior prop before 0.7.7 - #9711

Merged
cixzhang merged 8 commits into
mainfrom
lane4/remove-trigger-behavior
Nov 3, 2026
Merged

cixzhang merged 8 commits into
mainfrom
lane4/remove-trigger-behavior

Conversation

@cixzhang

@cixzhang cixzhang commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Removes the unreleased triggerBehavior prop before 0.7.7.

User impact

triggerBehavior and its type TooltipTriggerBehavior landed on main today in #9232, and no release has shipped them. Removing them now means 0.7.7 ships no prop that the next release would have to deprecate.

  • Tooltip and useTooltip callers: they keep the released API. touchTrigger still decides what a tap does, exactly as it did in 0.7.6.
  • InfoTip users: nothing changes. InfoTip's press still pins its help, and its public props stay the same.

What changes

  • Public API: Tooltip and useTooltip no longer take triggerBehavior, and the package no longer exports TooltipTriggerBehavior. The core API report is regenerated: four lines removed, nothing added.
  • InfoTip: it renders TooltipWithTriggerBehavior with the toggle behavior. That's a module-only component in Tooltip/Tooltip.tsx, backed by the module-only useTooltipWithTriggerBehavior, and no barrel exports either.
  • Kept: the press-to-pin fixes from feat(Tooltip): triggerBehavior="toggle" pins the tooltip on a press #9232 and fix(Tooltip): Space on keyup and a press outside in another document, with triggerBehavior evidence #9406 stay for InfoTip. Space pins on keyup without a pin-then-unpin, and a press outside closes a pin whose trigger is in another document.
  • Internal tidy-ups:
    • usePressPin's internal behavior type drops the hover value, which nothing uses now.
    • Its development warning no longer names the prop.
  • Docs and changesets:
    • Tooltip.doc.mjs and useTooltip.doc.mjs return to their released text.
    • InfoTip's docs, its story and its changeset stop naming the prop.
    • trigger-behavior-toggle.md is removed, so the 0.7.7 notes don't announce the prop.
  • Browser evidence: the press-to-pin a11y story and its Chromium cases now use InfoTip, the public press-to-pin trigger. The anchored-trigger and focusTrigger="never" cases are removed with the prop.

Expected behavior and authority

Owner direction for 0.7.7: remove triggerBehavior before the release, and keep touchTrigger. Specs & Decisions wrote the record commit included here (cherry-picked with its author). CodeBunny's rounds then removed the remaining pinned-HoverCard lines from AST-003, AST-090 and overlay-dismissal.

Evidence

  • pnpm vitest run for Tooltip, InfoTip, Layer, HoverCard, the announce adopters and the doc-prop tests: 1028 passed. That includes every press-to-pin case, now through the internal path.
  • pnpm api:report --package core: the only change is the four removed lines.
  • check:changesets passes, and so do the CLI docs-drift and prop-docs tests.
  • The InfoTip, Tooltip and TouchTrigger Chromium contracts run in CI's touched-components leg.

Scope

  • One defect is restored: no unreleased public prop ships.
  • Separable contradictory or unsettled tagalongs were removed or split.
  • No new public API, visual representation, default, or interaction model is hidden under the bug-fix label.
  • Public text and artifacts contain no internal Meta context.

Writing rubric results

The rubric in docs/contributing/spec-writing.md was run over all ten changed records: component:Tooltip, component:HoverCard, component:InfoTip, component:StatusDot, spec:AST-082, spec:AST-003, spec:AST-090, family:overlay-dismissal, architecture:interaction-modality and architecture:public-component-api.

  • R1, state the system: each edited line describes the system as it is: touchTrigger decides taps, a Tooltip pin goes only through the internal press-to-pin path InfoTip uses, and a HoverCard has no press pin. No line narrates the removal.
  • R2, research: none added.
  • R3, evidence cites facts: verification rows name tests and stories that exist at this head (the press-to-pin cases in TouchTrigger.a11y.chromium.spec.ts now run on InfoTip).
  • R4, rejected alternatives: none added. The withdrawn DEP-0016 and CLN-0024 removal leave no alternative prose behind.
  • R5, no pull request or issue references: no #NNNN was added to any record.
  • R6, open questions: one narrow Tooltip open question on the toggle design and one on InfoTip adopting show()/hide(), both written by Specs.

cixzhang and others added 2 commits November 2, 2026 21:09
…s through an internal path

triggerBehavior and TooltipTriggerBehavior landed on main in #9232 and were
never released. Tooltip and useTooltip drop them, and touchTrigger keeps
deciding taps as released. InfoTip keeps its press-to-pin through the
module-only TooltipWithTriggerBehavior, so its behavior and public props do
not change. The Space-on-keyup pin and the other-document outside press stay.

- usePressPin's internal behavior type drops the unused hover value, and its
  development warning no longer names the prop.
- Tests use the internal path where they test press-to-pin; the hover cases
  go.
- The a11y story and its Chromium cases use InfoTip, the public press-to-pin
  trigger; the anchored and focusTrigger=never cases go with the prop.
- Tooltip and useTooltip docs return to their released text; InfoTip docs, its
  story and its changeset stop naming the prop; the trigger-behavior
  changeset goes; the core API report is regenerated.
@vercel

vercel Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
astryx Ready Ready Preview Nov 3, 2026 8:15am UTC

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Nov 3, 2026
@astracat-bot

astracat-bot Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

AI review status for this pull request.

Review status Updated
🟢 Reviewed (for maintainers only) Nov 3, 2026, 8:26 AM UTC

@github-actions github-actions Bot added the needs:spec-owner-review Current knowledge records await owner approval label Nov 3, 2026
@cixzhang

cixzhang commented Nov 3, 2026

Copy link
Copy Markdown
Contributor Author

/approve-spec 3c06013

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes requested: removing the unreleased prop is owner-approved and InfoTip keeps its press-to-pin, but two fixes are needed first.

  • Tooltip and useTooltip still forward a spread or untyped triggerBehavior to the press-to-pin path at runtime (Tooltip.tsx:198, useTooltip.tsx:270), so the removed prop stays reachable without a type error; pin both wrappers to triggerBehavior="adaptive" and add a regression test.
  • docs/specs/AST-003/spec.md FR4 and its Current-state impact, and the Tooltip, HoverCard adoption row of docs/families/overlay-dismissal.md, still cite component:HoverCard FR9, which this pull request deletes; drop those citations here.

Optional: Tooltip's best practice and touchTrigger docs still steer info-icon triggers to touchTrigger="tap" rather than InfoTip.

[Automated review]

Comment thread packages/core/src/Tooltip/Tooltip.tsx Outdated
*/
export function Tooltip({
export function Tooltip(props: TooltipProps): ReactElement {
return <TooltipWithTriggerBehavior {...props} />;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This spread forwards an untyped triggerBehavior to the internal component, so <Tooltip {...props}> with triggerBehavior: 'toggle' in props still pins on a press and compiles without a cast. Pinning the public wrapper keeps the press-to-pin internal:

return <TooltipWithTriggerBehavior {...props} triggerBehavior="adaptive" />;

*/

export function useTooltip(options: TooltipOptions = {}): TooltipReturn {
return useTooltipWithTriggerBehavior(options);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here: an options object held in a variable can carry triggerBehavior: 'toggle' past the type check, and this call passes it through. Suggest:

return useTooltipWithTriggerBehavior({...options, triggerBehavior: 'adaptive'});

…stop citing HoverCard FR9

CodeBunny on #9711: Tooltip and useTooltip passed a spread or untyped
triggerBehavior through to the press-to-pin path at runtime. Both now pin
triggerBehavior to adaptive, with a regression test each. AST-003 FR4, its
current-state list and the overlay-dismissal Tooltip/HoverCard row no longer
cite component:HoverCard FR9, which the records commit removes; a Tooltip pin
cites Tooltip FR9 and a HoverCard has no press pin. Tooltip's tap guidance
points an info icon at InfoTip.
@cixzhang

cixzhang commented Nov 3, 2026

Copy link
Copy Markdown
Contributor Author

/approve-spec e03cf00

@github-actions

github-actions Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

PR Analysis Report

🔎 Preview · 956848e

Storybook · Sandbox · built from this PR's head

Modified components

Component Size LoC Visual · A11y · RTL
LayerProvider 62.7 kB (+22 B) · 10.5 kB CSS (0) — ✓ · ✓ · ✗
InfoTip · Storybook 37.8 kB (+15 B) · 6.2 kB CSS (0) 113 (0) — · ✓ · ✗
lab/CommentThread 227.0 kB (+54 B) · 2.4 kB CSS (0) — — · — · —
110 more components
Component Size LoC Visual · A11y · RTL
lab/CommentComposer 102.4 kB (+53 B) · 1.9 kB CSS (0) — — · — · —
lab/Comments 232.3 kB (+51 B) · 2.5 kB CSS (0) — — · — · —
Tokenizer 70.2 kB (+48 B) · 17.1 kB CSS (0) — — · — · —
lab/CommentPin 47.2 kB (+46 B) · 1.2 kB CSS (0) — — · — · —
PowerSearch 184.2 kB (+44 B) · 20.6 kB CSS (0) — — · — · —
lab/MobilePowerSearch 168.9 kB (+41 B) · 1.2 kB CSS (0) — — · — · —
richtext/RichTextEditor 277.7 kB (+41 B) · 2.6 kB CSS (0) — — · — · —
richtext/RichTextView 258.2 kB (+41 B) · 2.3 kB CSS (0) — — · — · —
RadioList 42.9 kB (+37 B) · 8.3 kB CSS (0) — — · — · —
Thumbnail 49.5 kB (+37 B) · 11.3 kB CSS (0) — — · — · —
NumberInput 55.0 kB (+34 B) · 11.2 kB CSS (0) — — · — · —
Pagination 86.0 kB (+34 B) · 16.0 kB CSS (0) — — · — · —
SideNavHeading 58.9 kB (+34 B) · 10.6 kB CSS (0) — — · — · —
Table 84.4 kB (+34 B) · 16.0 kB CSS (0) — — · — · —
Switch 86.8 kB (+33 B) · 10.5 kB CSS (0) — — · — · —
TopNavHeading 58.3 kB (+33 B) · 10.4 kB CSS (0) — — · — · —
Slider 88.6 kB (+32 B) · 9.4 kB CSS (0) — — · — · —
CheckboxListItem 53.4 kB (+31 B) · 11.0 kB CSS (0) — — · — · —
MultiSelector 72.7 kB (+31 B) · 15.2 kB CSS (0) — — · — · —
RadioListItem 51.3 kB (+31 B) · 10.1 kB CSS (0) — — · — · —
Selector 77.0 kB (+31 B) · 15.7 kB CSS (0) — — · — · —
Typeahead 62.9 kB (+31 B) · 11.8 kB CSS (0) — — · — · —
lab/EmojiPicker 70.2 kB (+31 B) · 722 B CSS (0) — — · — · —
ListItem 52.7 kB (+30 B) · 11.0 kB CSS (0) — — · — · —
lab/MobileTokenizer 100.9 kB (+30 B) · 880 B CSS (0) — — · — · —
richtext/RichTextEditorToolbar 221.8 kB (+30 B) · 454 B CSS (0) — — · — · —
DateTimeInput 115.1 kB (+29 B) · 15.8 kB CSS (0) — — · — · —
DateRangeInput 69.9 kB (+28 B) · 11.8 kB CSS (0) — — · — · —
Markdown 145.1 kB (+28 B) · 18.3 kB CSS (0) — — · — · —
lab/ListInput 81.5 kB (+28 B) · 1.6 kB CSS (0) — — · — · —
lab/TourStep 55.4 kB (+28 B) · 590 B CSS (0) — — · — · —
lab/TransferListSelector 80.8 kB (+28 B) · 1.9 kB CSS (0) — — · — · —
CheckboxList 43.3 kB (+27 B) · 8.6 kB CSS (0) — — · — · —
ContextMenu 75.1 kB (+27 B) · 15.3 kB CSS (0) — — · — · —
lab/ChatReactionBar 65.6 kB (+27 B) · 1.1 kB CSS (0) — — · — · —
DateInput 103.3 kB (+26 B) · 15.3 kB CSS (0) — — · — · —
SideNavItem 54.7 kB (+26 B) · 10.4 kB CSS (0) — — · — · —
TopNavMenu 58.4 kB (+26 B) · 10.5 kB CSS (0) — — · — · —
lab/ChatEmojiPicker 65.1 kB (+26 B) · 773 B CSS (0) — — · — · —
ChatComposer 61.0 kB (+25 B) · 11.2 kB CSS (0) — — · — · —
Lightbox 50.4 kB (+25 B) · 10.1 kB CSS (0) — — · — · —
Popover 50.1 kB (+25 B) · 12.4 kB CSS (0) — — · — · —
TableHeaderCell 75.9 kB (+25 B) · 15.5 kB CSS (0) — — · — · —
TimeInput 90.1 kB (+25 B) · 14.3 kB CSS (0) — — · — · —
ChatComposerInput 56.2 kB (+24 B) · 10.4 kB CSS (0) — — · — · —
ChatComposerTokenElement 56.2 kB (+24 B) · 10.4 kB CSS (0) — — · — · —
ComplexSelector 55.6 kB (+24 B) · 11.1 kB CSS (0) — — · — · —
DropdownMenu 73.1 kB (+24 B) · 15.4 kB CSS (0) — — · — · —
TableCell 76.3 kB (+24 B) · 15.8 kB CSS (0) — — · — · —
TableSelectionToolbar 52.3 kB (+24 B) · 11.5 kB CSS (0) — — · — · —
TabMenu 55.4 kB (+24 B) · 10.4 kB CSS (0) — — · — · —
lab/Schedule 61.4 kB (+24 B) · 3.9 kB CSS (0) — — · — · —
charts/ChartLegend 52.4 kB (+23 B) · 20 B CSS (0) — — · — · —
AlertDialog 56.2 kB (+23 B) · 12.7 kB CSS (0) — — · — · —
BreadcrumbItem 67.2 kB (+23 B) · 11.4 kB CSS (0) — — · — · —
Carousel 50.7 kB (+23 B) · 10.5 kB CSS (0) — — · — · —
CheckboxInput 48.8 kB (+23 B) · 9.7 kB CSS (0) — — · — · —
TextArea 47.2 kB (+23 B) · 9.8 kB CSS (0) — — · — · —
TopNavMegaMenu 54.4 kB (+23 B) · 11.2 kB CSS (0) — — · — · —
charts/Chart 62.9 kB (+22 B) · 20 B CSS (0) — — · — · —
DialogHeader 48.4 kB (+22 B) · 10.2 kB CSS (0) — — · — · —
Field 41.5 kB (+22 B) · 8.3 kB CSS (0) — — · — · —
Link 42.9 kB (+22 B) · 7.9 kB CSS (0) — — · — · —
MoreMenu 73.4 kB (+22 B) · 15.4 kB CSS (0) — — · — · —
SideNav 65.7 kB (+22 B) · 10.9 kB CSS (0) — — · — · —
lab/TransferList 74.4 kB (+22 B) · 1.7 kB CSS (0) — — · — · —
AppShell 68.5 kB (+21 B) · 12.2 kB CSS (0) — — · — · —
Banner 47.3 kB (+21 B) · 10.3 kB CSS (0) — — · — · —
BaseTypeahead 55.2 kB (+21 B) · 10.2 kB CSS (0) — — · — · —
Button 42.4 kB (+21 B) · 9.5 kB CSS (0) — — · — · —
Calendar 54.3 kB (+21 B) · 10.3 kB CSS (0) — — · — · —
ChatDictationButton 46.0 kB (+21 B) · 9.8 kB CSS (0) — — · — · —
ChatLayoutScrollButton 45.8 kB (+21 B) · 9.9 kB CSS (0) — — · — · —
CodeBlock 59.1 kB (+21 B) · 11.1 kB CSS (0) — — · — · —
FileInput 53.7 kB (+21 B) · 10.7 kB CSS (0) — — · — · —
IconButton 42.4 kB (+21 B) · 9.5 kB CSS (0) — — · — · —
InputGroup 42.0 kB (+21 B) · 8.4 kB CSS (0) — — · — · —
MobileNav 50.2 kB (+21 B) · 10.4 kB CSS (0) — — · — · —
SideNavCollapseButton 46.1 kB (+21 B) · 9.8 kB CSS (0) — — · — · —
lab/DiffViewer 70.8 kB (+21 B) · 2.1 kB CSS (0) — — · — · —
ChatSendButton 45.2 kB (+20 B) · 9.5 kB CSS (0) — — · — · —
DrawerHeader 48.5 kB (+20 B) · 11.6 kB CSS (0) — — · — · —
MobileNavToggle 45.8 kB (+20 B) · 9.7 kB CSS (0) — — · — · —
Stepper 47.0 kB (+20 B) · 9.9 kB CSS (0) — — · — · —
TextInput 52.9 kB (+20 B) · 10.9 kB CSS (0) — — · — · —
Toast 59.5 kB (+20 B) · 10.1 kB CSS (0) — — · — · —
ToggleButton 43.3 kB (+20 B) · 9.6 kB CSS (0) — — · — · —
ChatLayout 48.5 kB (+19 B) · 10.3 kB CSS (0) — — · — · —
SegmentedControl 36.8 kB (+19 B) · 6.5 kB CSS (0) — — · — · —
Tooltip · Storybook 21.0 kB (+19 B) · 5.0 kB CSS (0) 655 (+11) ✓ · ✓ · ✓
StatusDot 23.2 kB (+18 B) · 6.3 kB CSS (0) — — · — · —
Avatar 35.0 kB (+17 B) · 6.5 kB CSS (0) — — · — · —
FieldLabel 36.0 kB (+16 B) · 5.9 kB CSS (0) — — · — · —
TopNav 51.8 kB (+16 B) · 10.7 kB CSS (0) — — · — · —
charts/ChartTooltip 52.4 kB (+15 B) · 20 B CSS (0) — — · — · —
AvatarGroup 37.7 kB (+15 B) · 6.6 kB CSS (0) — — · — · —
AvatarGroupOverflow 38.9 kB (+7 B) · 6.5 kB CSS (0) — — · — · —
ChatMessageList 22.8 kB (0) · 7.9 kB CSS (0) — — · — · —
ChatToolCalls 25.8 kB (0) · 9.3 kB CSS (0) — — · — · —
CommandPalette 48.6 kB (0) · 12.2 kB CSS (0) — — · — · —
DropdownMenuSubMenu 56.0 kB (0) · 9.9 kB CSS (0) — — · — · —
ProgressBar 10.8 kB (0) · 7.3 kB CSS (0) — — · — · —
Spinner 18.5 kB (0) · 6.7 kB CSS (0) — — · — · —
Text 7.4 kB (0) · 6.0 kB CSS (0) — — · — · —
CommandPaletteInput 26.8 kB (−1 B) · 8.5 kB CSS (0) — — · — · —
Timer 9.6 kB (−1 B) · 7.0 kB CSS (0) — — · — · —
Heading 7.9 kB (−2 B) · 6.0 kB CSS (0) — — · — · —
Timestamp 21.3 kB (−2 B) · 9.9 kB CSS (0) — — · — · —
layer — — — · ✓ · —
Layer — — ✓ · ✓ · —

Package size: @astryxdesign/core 6.04 MB packed (−1.6 kB); no new dependencies.

API changes: core +0 · ~0 · −4

4 API changes (advisory)
Package Where Signature Usage
− core . · Components · component Tooltip prop triggerBehavior?: TooltipTriggerBehavior = 'adaptive' <Tooltip triggerBehavior="adaptive" />
− core . · Types · interface TooltipOptions triggerBehavior?: TooltipTriggerBehavior = 'adaptive' import type {TooltipOptions} from '@astryxdesign/core'; const x: TooltipOptions = {triggerBehavior: …}
− core . · Types · type TooltipTriggerBehavior type TooltipTriggerBehavior = 'adaptive' | 'hover' | 'toggle' import type {TooltipTriggerBehavior} from '@astryxdesign/core'
− core ./Tooltip · Also exported from an earlier entry point · TooltipTriggerBehavior TooltipTriggerBehavior (.) import {TooltipTriggerBehavior} from '@astryxdesign/core/Tooltip'

Touched components checked; add ci:run-visual, ci:run-a11y or ci:run-rtl to run the full suites.


Generated by PR Enrichment workflow | View full report

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes requested: the code is ready (the public Tooltip and useTooltip now ignore triggerBehavior at runtime, InfoTip keeps its press-to-pin, and the record changes carry an engineering owner's approval), but two record items remain.

  • docs/specs/AST-003/spec.md still lists "no HoverCard pins open on a press" as unmet (line 193) and verifies a "pinned Tooltip and HoverCard over a Dialog" (line 242), although this pull request removes HoverCard's press pin; drop the HoverCard part there and in the completion criterion (line 255) and DEC-6 (line 343).
  • The description has no ## Writing rubric results section, which architecture:knowledge-contracts requires of a pull request that changes records; add it, covering all nine changed records.

Optional: Tooltip's touchTrigger prop docs still recommend tap for an info icon, where the Tooltip record and the rewritten best practice point to InfoTip.

[Automated review]

Comment thread docs/specs/AST-003/spec.md Outdated
consumes Escape ahead of associated owners;
- no Tooltip or HoverCard pins open on a press yet (`component:Tooltip` FR9,
`component:HoverCard` FR9);
- no HoverCard pins open on a press;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pull request removes HoverCard's press pin (HoverCard DEC-1: "HoverCard has no public toggle prop"), so a HoverCard that does not pin is no longer a gap against this spec. Suggest deleting this line, and dropping "and HoverCard" / "or HoverCard" from the FR1–FR6 verification row, the completion criterion and DEC-6.

type: "'auto' | 'tap' | 'none'",
description:
'What a tap does where there is no hover. auto opens on tap unless the trigger performs an action of its own (a button, link, or form control), whose tap belongs to the control; an aria-disabled control performs none, so a tap on it opens its reason. tap always opens. none never opens on touch. It decides only under triggerBehavior="adaptive", the default.',
'What a tap does where there is no hover. auto opens on tap unless the trigger performs an action of its own (a button, link, or form control), whose tap belongs to the control; an aria-disabled control performs none, so a tap on it opens its reason. tap always opens; use it for an info icon rendered as a button, whose only job is to reveal the tooltip. none never opens on touch.',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking: "use it for an info icon rendered as a button" still steers info icons to a hand-rolled Tooltip, while the Tooltip record says help behind an info icon uses InfoTip and the best practice below now says so. Consider naming InfoTip here, and in the Chinese, dense and useTooltip texts.

…er tap docs point info icons at InfoTip

CodeBunny on #9711: AST-003's current-state list, its FR1–FR6 verification
row, its completion criterion and DEC-6 still named a HoverCard press pin,
which the records commit removes. They now name only the Tooltip pin. The
touchTrigger prop docs say tap is for a button whose only job is the
tooltip, and point an info icon at InfoTip.
@cixzhang

cixzhang commented Nov 3, 2026

Copy link
Copy Markdown
Contributor Author

/approve-spec 885f895

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes requested: the code is ready (Tooltip and useTooltip no longer take triggerBehavior, in types or at runtime, InfoTip keeps its press-to-pin, and the record changes carry an engineering owner's approval for this head), but one record leftover remains.

  • docs/families/overlay-dismissal.md FR8 (line 207) and docs/specs/AST-090-exit-motion/spec.md FR5 (lines 129–136, 209, 217, 222, and its verification row at line 262) still give a press-pinned HoverCard its own Escape rule, citing spec:AST-003 FR4 and DEC-6, which this pull request narrows to a pinned Tooltip; drop "or HoverCard" in those lines.

Optional: the Chinese touchTrigger text in Tooltip.doc.mjs (line 241) still recommends tap for an info icon where the English text now points to InfoTip, and StatusDot FR5 could cite Tooltip DEC-1 instead of FR9.

[Automated review]

| Components or surface | Adoption | Current deviation or limitation |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Dialog, AlertDialog, Popover, MobileNav, Drawer, CommandPalette | shared owner; CommandPalette composes Dialog | none |
| Tooltip, HoverCard | shared owner with DOM presence reporting | Neither provides nesting depth to descendant layers. Implementation gap: a Tooltip consumes Escape when it is the topmost layer, so the layer beneath it stays open for that press, and a Tooltip in another document is never closed by Escape (`component:Tooltip` FR6); FR8 gives that press to the layer beneath and closes a lone Tooltip in its own document. A Tooltip pinned open by a press takes Escape first (`spec:AST-003` FR4, DEC-6; `component:Tooltip` FR9); a HoverCard has no press pin. HoverCard reads its presence from the page's document, so in another document it takes no request (FR8) and returns no focus there (FR9) |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This row now says a HoverCard has no press pin, but FR8 above (line 207) still says "a Tooltip or HoverCard pinned open by a press takes Escape first (spec:AST-003 FR4, DEC-6)", and spec:AST-090 FR5 (lines 129–136, 209, 217, 222, and its verification row at line 262) still gives a closing pinned HoverCard its own rule on the same citation. This pull request narrows AST-003 FR4 and DEC-6 to a pinned Tooltip, so those lines describe a state no HoverCard can reach. Suggest dropping "or HoverCard" there.

type: "'auto' | 'tap' | 'none'",
description:
'在没有悬停的触摸设备上,轻点的行为。auto:轻点即打开,除非触发元素本身会执行操作(按钮、链接、表单控件),此时轻点归该控件所有;设置了 aria-disabled 的控件不执行操作,因此轻点它会显示其原因。tap:始终轻点打开。none:触摸永不打开。仅在 triggerBehavior 为 adaptive(默认)时生效。',
'在没有悬停的触摸设备上,轻点的行为。auto:轻点即打开,除非触发元素本身会执行操作(按钮、链接、表单控件),此时轻点归该控件所有;设置了 aria-disabled 的控件不执行操作,因此轻点它会显示其原因。tap:始终轻点打开——适用于以按钮形式呈现、唯一作用就是显示工具提示的信息图标。none:触摸永不打开。',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking: the English (line 108) and dense (line 360) text now send an info icon to InfoTip, but this Chinese text still recommends tap for one. Suggested:

'在没有悬停的触摸设备上,轻点的行为。auto:轻点即打开,除非触发元素本身会执行操作(按钮、链接、表单控件),此时轻点归该控件所有;设置了 aria-disabled 的控件不执行操作,因此轻点它会显示其原因。tap:始终轻点打开,适用于唯一作用是显示工具提示的按钮;信息图标请使用 InfoTip。none:触摸永不打开。',

| FR2 | `success`, `warning`, and `error` are strong status fills: under `architecture:theme-tokens` INV11 each paints `--color-<status>` with `--color-on-<status>` ink and keeps a visible `CanvasText` border in forced-colors mode. `accent` paints `--color-accent` with `--color-on-accent` ink, and `neutral` paints `--color-icon-secondary` with the surface color as ink; these two are not INV11 status roles, and no current record sets their forced-colors treatment (OQ1). The target reflects `variant` for every value, and an extensible tone has a safe theme-independent baseline (`architecture:component-theming-surface` INV14). Implementation gap: a theme-added value the active theme does not paint receives no component plate or ink, leaving a transparent 8px box (Current-state impact). | Current source and tests |
| FR3 | `isPulsing` animates the dot's opacity from 1 to 0.5 and back over 2 seconds, ease-in-out, indefinitely; under `prefers-reduced-motion: reduce` the animation is removed and the dot rests. | Current source and tests |
| FR4 | A renderable `icon` renders in a wrapper centered inside the dot and filling its 8px field; it paints from `currentColor`, the variant's ink. A non-renderable value leaves the dot childless. | Current source and tests |
| FR5 | A non-empty `tooltip` renders by placement; without one, no tooltip renders. A standalone dot is wrapped in Tooltip with that text and is a button trigger whose press pins it, named by `label`, so hover and keyboard focus preview the tooltip and a tap, click, Enter, or Space pins it (`component:Tooltip` FR9), and keyboard users reach it (WCAG 2.2 2.1.1). StatusDot adopts the pin once `useTooltip`'s `show()` and `hide()` (`component:Tooltip` DEC-1) ship, so a standalone dot's tooltip stays reachable on touch. A dot inside an interactive element (a button, link, menu item, or option) is a non-interactive image wrapped in Tooltip without the pin, because a control cannot nest another control: its tooltip previews on hover only, and its tooltip text joins the host's accessible name, so the host carries the status for screen readers (`architecture:interaction-modality` INV4). A host named by `aria-label` takes no name from its content, so its caller includes the status in that label. Implementation gap: the dot has no tab stop and uses Tooltip's default touch trigger, so the tooltip opens on hover and touch only (Current-state impact). | Current source and tests; `component:Tooltip` DEC-1 |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking: this row cites component:Tooltip FR9 for the standalone dot's pin, but Tooltip FR9 and its Public contract make InfoTip the press-to-pin path's only caller, and this same row says StatusDot adopts the pin through useTooltip's show() and hide(). Citing Tooltip DEC-1 there would match.

Comment thread packages/core/src/Tooltip/Tooltip.tsx Outdated
*/
export function Tooltip({
export function Tooltip(props: TooltipProps): ReactElement {
// Pinned, so a spread object that carries the internal option at runtime

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking (INV29, one meaning per word): "Pinned" here means the option value is fixed, while everywhere else in these files a pin is the press-to-pin. Suggested, here and at useTooltip.tsx:270:

// The option is fixed to `adaptive`, so a spread object that carries it at
// runtime cannot reach the press-to-pin path.

…ltip zh tap text points at InfoTip

CodeBunny on #9711: overlay-dismissal FR8 and AST-090 FR5, its impact
lines and its verification row still gave a press-pinned HoverCard an
Escape rule. AST-003 FR4 and DEC-6 now name only a pinned Tooltip, so
these lines do too. StatusDot FR5 cites Tooltip DEC-1 for its pin. The
Chinese touchTrigger text matches the English. The wrapper comments say
the option is fixed, not pinned.
@cixzhang

cixzhang commented Nov 3, 2026

Copy link
Copy Markdown
Contributor Author

/approve-spec 956848e

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes requested: the code is ready (Tooltip and useTooltip no longer take triggerBehavior, in types or at runtime, InfoTip keeps its press-to-pin, and the record changes carry an engineering owner's approval for this head), but one record leftover remains.

  • docs/families/overlay-dismissal.md still names a pinned HoverCard in the iframe example row (line 247: "a pinned Tooltip or HoverCard takes it first (spec:AST-003 FR4, DEC-6)") and in the FR8, FR9 verification row (line 282), while this pull request makes only a pinned Tooltip an active owner and says a HoverCard has no press pin; drop "or HoverCard" from both lines.

The earlier items (overlay-dismissal FR8, spec:AST-090 FR5, the Chinese touchTrigger text, the StatusDot citation and the wrapper comments) are fixed at this head.

[Automated review]

| Components or surface | Adoption | Current deviation or limitation |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Dialog, AlertDialog, Popover, MobileNav, Drawer, CommandPalette | shared owner; CommandPalette composes Dialog | none |
| Tooltip, HoverCard | shared owner with DOM presence reporting | Neither provides nesting depth to descendant layers. Implementation gap: a Tooltip consumes Escape when it is the topmost layer, so the layer beneath it stays open for that press, and a Tooltip in another document is never closed by Escape (`component:Tooltip` FR6); FR8 gives that press to the layer beneath and closes a lone Tooltip in its own document. A Tooltip pinned open by a press takes Escape first (`spec:AST-003` FR4, DEC-6; `component:Tooltip` FR9); a HoverCard has no press pin. HoverCard reads its presence from the page's document, so in another document it takes no request (FR8) and returns no focus there (FR9) |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This row now says a HoverCard has no press pin, and FR8 (line 207) now names only a pinned Tooltip, but two lines of this record still describe a pinned HoverCard on the same citation: the iframe example row's basis (line 247: "a pinned Tooltip or HoverCard takes it first (spec:AST-003 FR4, DEC-6)") and the FR8, FR9 verification row (line 282: "a pinned Tooltip or HoverCard before the member beneath it"). Dropping "or HoverCard" from both keeps the record consistent with the rewritten AST-003 FR4 and DEC-6.

… rows name only a pinned Tooltip

CodeBunny on #9711: two table rows still gave a pinned HoverCard Escape
first. A HoverCard has no press pin, so they name only a pinned Tooltip.
@cixzhang

cixzhang commented Nov 3, 2026

Copy link
Copy Markdown
Contributor Author

/approve-spec c8f7e88

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes requested: the removal itself is ready (Tooltip and useTooltip no longer take triggerBehavior, in types or at runtime, InfoTip keeps its press-to-pin, and the record changes carry an engineering owner's approval for this head), but the required lint check fails.

  • docs/families/overlay-dismissal.md is not Prettier-formatted: shortening the cells at lines 247 and 282 left both tables unpadded, so run pnpm exec prettier --write docs/families/overlay-dismissal.md (whitespace only) and push.

The earlier pinned-HoverCard leftovers in that record are fixed at this head.

[Automated review]

| Popover in an iframe, Dialog in the page | Request goes to its own document's top member | The app renders into the second document through a portal |
| Popover inside Dialog in an iframe | Popover handles the iframe's first request | Both register their own elements, so they rank in the iframe's order |
| Tooltip or HoverCard inside Dialog, in iframe | An open HoverCard handles the first Escape there; over an unpinned Tooltip, the Dialog takes it; a pinned Tooltip takes it first | An unpinned Tooltip never wins or blocks Escape against another member; a pinned Tooltip or HoverCard takes it first (`spec:AST-003` FR4, DEC-6) |
| Tooltip or HoverCard inside Dialog, in iframe | An open HoverCard handles the first Escape there; over an unpinned Tooltip, the Dialog takes it; a pinned Tooltip takes it first | An unpinned Tooltip never wins or blocks Escape against another member; a pinned Tooltip takes it first (`spec:AST-003` FR4, DEC-6) |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shortening this cell (and the one at line 282) left both tables unpadded, so the required lint check fails at its Prettier step. pnpm exec prettier --write docs/families/overlay-dismissal.md re-pads them; it changes whitespace only.

Prettier formatting only, so the lint check passes.
@github-actions github-actions Bot added the needs:spec-owner-review Current knowledge records await owner approval label Nov 3, 2026
@cixzhang

cixzhang commented Nov 3, 2026

Copy link
Copy Markdown
Contributor Author

/approve-spec 71fad14

@github-actions github-actions Bot removed the needs:spec-owner-review Current knowledge records await owner approval label Nov 3, 2026

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes requested: the removal itself is ready (Tooltip and useTooltip no longer take triggerBehavior, in types or at runtime, InfoTip keeps its press-to-pin, and the record changes carry an engineering owner's approval for this head), but the branch no longer merges into main.

  • docs/families/overlay-dismissal.md conflicts with main: re-padding the whole Verification map overlaps the FR10 row main has since added to that table, so GitHub cannot merge the branch and no lint, typecheck or test check has run on this head; rebase on main, keep its FR10 row beside the narrowed FR8, FR9 row, run pnpm exec prettier --write docs/families/overlay-dismissal.md, and push.

The Prettier failure from the previous round is fixed at this head.

[Automated review]

| FR9 | `DialogSecondDocument.a11y.browser.spec.ts` | a Dialog in an iframe and in a Picture-in-Picture window, closed by Escape or a control inside it, and a Dialog in an iframe opened from the page | Focus lands outside the opener's document, or its ring does not follow the closing input |
| FR8, FR9 | Real-browser second-document checks; implementation gap: only Dialog and Popover have them | Dialog, Popover, DropdownMenu, MoreMenu, ContextMenu, Selector, MultiSelector, TopNavHeading, TopNavMenu, TopNavMegaMenu, SideNavHeading, SideNavItem, Tooltip and HoverCard, each in a same-origin iframe and in a Picture-in-Picture window: opens and takes Escape in the document it renders in (an unpinned Tooltip only when no other member is present; a pinned Tooltip before the member beneath it), and returns focus in the opener's document | The member opens or ranks in another document, a pinned Tooltip lets Escape reach the member beneath it, or focus lands on the frame element, the page, or the body |
| FR8, FR9 | Real-browser second-document checks; implementation gap: none has them | BottomSheet, BottomSheetSwitcher, and Lightbox in a Picture-in-Picture window: opens, takes Escape, and returns focus to its return target there | The surface ranks in the page, or focus lands on the page or the body |
| FR8 | Source check over Drawer and MobileNav | Drawer and MobileNav rendered from a control in a second document | A page-level surface moves into the second document |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

main has added an FR10 row after this one (useBackdropPress.test.tsx; BackdropPress.a11y.chromium.spec.ts), and re-padding every row of this table now conflicts with it, so the branch cannot merge and CI has not run. Rebase on main, keep that row beside the narrowed FR8, FR9 row, and run pnpm exec prettier --write docs/families/overlay-dismissal.md.

…ve-trigger-behavior

# Conflicts:
#	docs/families/overlay-dismissal.md
@cixzhang

cixzhang commented Nov 3, 2026

Copy link
Copy Markdown
Contributor Author

/approve-spec 92354fb

@github-actions github-actions Bot added needs:spec-owner-review Current knowledge records await owner approval and removed needs:spec-owner-review Current knowledge records await owner approval labels Nov 3, 2026

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval recommended. Removing the never-released triggerBehavior prop and TooltipTriggerBehavior type keeps the 0.7.6 Tooltip and useTooltip API, InfoTip still pins its help on a press, and every record change carries an engineering owner's approval for this head. The merge with main keeps its FR10 row in the overlay-dismissal Verification map, so the earlier conflict is resolved.

[Automated review]

@cixzhang
cixzhang merged commit 1821fb3 into main Nov 3, 2026
94 of 97 checks passed

This branch was successfully deployed

1 active deployment
Preview — 92354fb4 Deployed Nov 3, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant