Skip to content

[Component Audit] InfoTip: the docs page gets worked examples, and hover, focus, pin, and Escape are proven in a browser - #9940

Merged
cixzhang merged 4 commits into
mainfrom
night-watch-component-audit/InfoTip/2026-11-04
Nov 4, 2026
Merged

cixzhang merged 4 commits into
mainfrom
night-watch-component-audit/InfoTip/2026-11-04

Conversation

@cixzhang

@cixzhang cixzhang commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

User impact

Builders now see InfoTip in use. The InfoTip docs page, astryx component InfoTip --showcase, and astryx component InfoTip --blocks had no showcase and no examples, so a builder or a code assistant had only the prop table to learn from. They now show a metric label with an InfoTip, a row of metric definitions, and read-only settings whose labels say who can change each value. The docs now list InfoTip's anatomy (trigger button, info icon, help surface) and say that it follows the toggletip pattern: the button reports aria-expanded="true" while the help is pinned, and a screen reader hears the help once when it pins.

People who use InfoTip get the same control as before, now proven in a real browser: one named native button per InfoTip, in the tab order, with a decorative info icon centered in a round box at 12, 16, 20, and 24 px per size; hover and keyboard focus show the help and describe the button; a click or Enter pins it with aria-expanded="true"; Escape closes it and keeps the focus outline. The component's runtime, DOM, styles, and public API do not change.

Audit result

  • Package/component: core/InfoTip (released in @astryxdesign/core under ./InfoTip)
  • Mode: Night Watch whole-component audit, rubric 1.16.6
  • Base: 2951a3ac323b463b428a6a28c30c30a8c0b35330
  • Exact head: 572d85d260404aa29fd8e0398a1e4ee0c42c380c
  • Component contract: existing InfoTip.spec.md (authority: current), unchanged. No observational backfill was needed.
  • Runtime/API changes: none (CLI block templates and their route lock, docs, one unit test, a browser spec, an RTL verified-N/A entry, a changeset, and one SYNC: header line)
Before After
Score 88.8, capped at C by 1 open BLOCK 97.1 / A (0 open BLOCKs)
Distinct defects 1 BLOCK, 5 FIX 0 BLOCK, 1 FIX
Sensitivity fix the 1 open BLOCK and change nothing else: projected 92.3 —
Section W Before After State
§1 Accessibility 16 5 5 scored; named native button, toggletip with aria-expanded and aria-controls, keyboard pin and close, focus outline, coarse-pointer hit area (existing touch spec); the fine-pointer target is measured in Needs Review 2
§2 Theming 14 4 4 scored; every value is a token. One open FIX: no theming target or anatomy disposition (Needs Review 1)
§3 Public API 14 5 5 scored
§4 Behavior 12 5 5 scored
§5a Design, objective 6 5 5 scored; spacing, radius, color, and motion tokens; only color transitions
§5b Design, rendered 4 not measured 5 scored from the exact-head frames (16 receipted frames): xsm, sm, md, lg in Neutral and Butter, light and dark; rest, hover (icon raised to primary emphasis), keyboard focus outline, click and Enter pin, Escape; the help surface above or below the button
§6 Testing 8 4 5 scored
§7 Code health 8 5 5 scored; no Effects; the hit-area watch lives in a callback ref
§8 Docs 8 2 5 scored
§9 i18n and RTL 5 4 5 scored; the default name is a catalog key; RTL is now a recorded verified N/A
§10 Responsive and touch 5 — — limited: an inline icon control; touch reach is graded in §1

limited and not measured sections are reported for information, and their weight is redistributed across the measured sections (91 of 100 before, 95 after). §11 is not run for an existing core component.

Why the score moved: the block templates close the §8 BLOCK and the anatomy and pattern docs close its FIXes (2→5); the size test closes the §6 gap (4→5); the verified-N/A entry closes the §9 RTL coverage gap (4→5); §5b is now measured. §2 stays at 4 because its finding needs an owner decision.

Pre-fix score: scored from base source before any change. Night Watch records only the landed post-fix result in the score ledger, so the pre-fix score lives here.

Findings fixed

ID Finding Authority Fix and proof
X6 / X7 (BLOCK) InfoTip had no block templates, so no hero example and no worked example. It was one of six Core components without them, and astryx validation reports it as component_without_example architecture:cli-surface DEC-13; architecture:template-authoring A showcase and two examples (metric definitions, permission notes) under blocks/components/InfoTip/, with exampleFor: 'InfoTip' and complete componentsUsed. The registry route lock gains their three routes, and InfoTip.tsx's SYNC: header names the folder
X4 (FIX) The docs had no anatomy component:InfoTip Design relationships usage.anatomy lists the trigger button, the info icon, and the help surface, as the contract names them
X16 (FIX) The docs did not name the accessibility pattern component:InfoTip AR2; component:Tooltip AR6 The English and dense usage text name the toggletip pattern and what a screen-reader user hears
V3 (FIX) No test proved FR1's icon: the registry's info artwork at size, sm by default component:InfoTip FR1, Public concepts; architecture:component-test-sufficiency A new test checks the icon's data-size and artwork against a reference Icon for each size and the default. Mutation proof: dropping size, or rendering another icon, fails only the new test; every other InfoTip test still passes
I17 (FIX) The RTL audit reports InfoTip all N/A with no recorded reason, which is a coverage gap architecture:rtl-audit-evidence INV5 A core/InfoTip verified-N/A entry with its reason and the sha256 of the story, source, barrel, and shared hit-area files
V15 No rendered evidence for InfoTip's states under a fine pointer component:InfoTip FR1, FR2, AR2; WCAG 2.5.8 A browser spec on the existing stories asserts, per frame: one named native button per InfoTip in the tab order, a decorative centered icon at 12/16/20/24 px, a round box, no fine-pointer growth, the spacing exception for any box under 24 px, and the rest, hover, focus, click-pin, Enter-pin, and Escape states with aria-expanded, aria-controls, and the description

Needs Review

  1. Theming participation (owner decision). InfoTip's button carries no theming target and its contract has no theming-anatomy disposition, so a theme can restyle the info button only through the shared icon color tokens. architecture:component-theming-surface INV1 says Core components provide targets, metadata, and anatomy dispositions, and INV3 says a none disposition is a valid, recorded outcome. Whether InfoTip gets an info-tip target on its button or a recorded none is a public theming decision, so this audit does not make it.
  2. Fine-pointer target size (owner decision, no current failure). At the default sm, the button is 20 by 20 CSS px under a mouse; xsm is 16 by 16. It passes WCAG 2.5.8 through the spacing exception wherever a 24 px circle on its center clears other targets, which every story frame proves. A caller who puts another control within about 2 px of it would fail. AR1 covers only coarse pointers. Whether InfoTip should promise 24 px under every pointer is a visual decision.
  3. Record drift, follow-up. The contract's Compatibility section says InfoTip is "not yet released in Core", but @astryxdesign/core@0.7.7 publishes ./InfoTip. Its verification map does not list the new size test or browser spec. Changing a current record needs an owner-approved record change, so it stays out of this pull request.
  4. Overlap. Open draft refactor(InfoTip): the button's touch target uses the shared touch layer #9916 changes InfoTip's hit area in InfoTip.tsx. This pull request changes one header comment line there; whichever lands second rebases one line.
  5. Header length, follow-up (NIT). The SYNC: line this pull request adds makes InfoTip.tsx's file header 13 lines, one past the about-12-line guidance in architecture:knowledge-contracts INV29. Folding @input and @position onto one line each fixes it; it is left for the next change to that file so this audit head does not rerun CI for a comment.

Evidence

  • Before, base 2951a3a: no blocks/components/InfoTip/ folder; usage.anatomy absent; the two mutants above survive every base InfoTip test; pnpm rtl:audit has no InfoTip target and no verified-N/A entry; no browser spec covers fine-pointer states.
  • After, exact head: CI run 41847196147 (attempt 2), all green:
    • component axe pass over the 4 InfoTip stories: 0 violations;
    • 16/16 Chromium frames pass their sensor receipts in artifact pr-a11y-evidence-572d85d (sha256:7607aed19df82641943997062349f8a4068451516bc4d19c33faed7bd8b5c5e5), each bound to build 572d85d;
    • icon contrast against its backdrop, recorded per frame: 5.41:1 (Neutral light), 5.65:1 (Neutral dark), 6.45:1 (Butter light), 6.81:1 (Butter dark), all above the 3:1 non-text minimum; hovered icon 21:1 and 15.13:1; focus outline 17.22:1 and 13.4:1;
    • every box is round with a centered icon: 16, 20, 24, and 28 px for xsm, sm, md, and lg at Neutral, and the xsm and sm boxes pass through the spacing exception in every frame;
    • pr-rtl (core): core/InfoTip is verified-na with no applicable dimension, so the entry is not stale.
  • Visual acceptance: N/A. No component source, style, token, target, default, or rendered output changes; the frames prove the unchanged surface.

Closed evidence inventory

Surface Source Tests Consumer docs Rendered evidence Authority Result
Exports InfoTip, InfoTipProps, InfoTipSize InfoTip/index.ts export checks in CI InfoTip.doc.mjs — architecture:public-component-api INV1 reachable
One native type="button", in the tab order, no wrapper InfoTip.tsx button, Tab, no-wrapper tests anatomy every frame FR1, FR2, AR1 pass
Name: label, else the translated default InfoTip.tsx name and catalog tests label aria-label in every frame FR1, ORD1 pass
Registry info icon at size, sm by default InfoTip.tsx new size test size, anatomy sizes-*: 12/16/20/24 px icons FR1, AV1 pass
Hover and focus preview, described by the help useTooltip hover and focus tests usage default-*-hover-*, next-to-a-label-*-focus-* FR2, component:Tooltip pass
Click, tap, Enter, Space pin; aria-expanded, aria-controls InfoTip.tsx pin tests usage (toggletip) *-click-pin-*, *-key-pin-* FR2, AR2 pass (tap and Space in jsdom)
Second press, press outside, focus leaving, Escape close useTooltip pin tests usage *-escape-* FR2 pass (Escape in browser; the rest in jsdom)
Announced once when it pins useTooltip announcement test usage (toggletip) — AR2 pass
A press stops at the button inside a row, card, or label InfoTip.tsx press-stop tests — — FR2 pass
Props closed to FR3; ref, xstyle, className, style on the button InfoTip.tsx props tests content, label, size, xstyle — FR3 pass
Coarse-pointer hit area toward 44 px, clamped by neighbours InfoTip.tsx, utils/hitArea.ts hit-area test — existing touch browser spec; no growth under a fine pointer in every new frame AR1 pass
Fine-pointer target InfoTip.tsx — — every frame WCAG 2.5.8 pass by spacing exception (Needs Review 2)
Lab re-export packages/lab/src/InfoTip Lab identity test — — FR4 pass
Theming InfoTip.tsx — — Neutral and Butter frames architecture:component-theming-surface INV1, INV3 open FIX (Needs Review 1)
Direction logical layout; symmetric glyph — — pr-rtl verified-na architecture:rtl-audit-evidence INV5 pass
FR10 eligibility report
{
  "schema": "astryx.audit-eligibility/v1",
  "component": "InfoTip",
  "package": "core",
  "mode": "night-watch",
  "rubricVersion": "1.16.6",
  "repository": {
    "base": "2951a3ac323b463b428a6a28c30c30a8c0b35330",
    "head": "572d85d260404aa29fd8e0398a1e4ee0c42c380c"
  },
  "contract": {"id": "component:InfoTip", "authority": "current", "changed": false},
  "inventory": {"closed": true, "rows": 15, "open": ["theming participation"]},
  "unresolved": {
    "objective": [],
    "manual": [
      "theming target or none disposition (component-theming-surface INV1, INV3)",
      "fine-pointer target size guarantee",
      "record drift in component:InfoTip (released status, verification map)"
    ],
    "ownedElsewhere": []
  },
  "remediations": [
    {"id": "X6/X7", "kind": "doc-drift", "evidence": "InfoTip block templates and route locks"},
    {"id": "X4", "kind": "doc-drift", "evidence": "usage.anatomy"},
    {"id": "X16", "kind": "doc-drift", "evidence": "toggletip pattern in usage text"},
    {"id": "V3", "kind": "objective-test", "evidence": "two mutants killed only by the new size test"},
    {"id": "I17", "kind": "objective-test", "evidence": "pr-rtl verified-na for core/InfoTip"},
    {"id": "V15", "kind": "browser-evidence", "evidence": "InfoTipAudit receipts, 16 frames"}
  ],
  "approvals": {"specOwner": "success (no record change)"},
  "checks": "all green at 572d85d (CI run 41847196147 attempt 2, pr-a11y and pr-rtl included)",
  "eligible": false,
  "reasons": ["spec:AST-029 is phase accepted; FR11 activation has not shipped"]
}

@vercel

vercel Bot commented Nov 4, 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 4, 2026 2:32pm UTC

Request Review

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

astracat-bot Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

AI review status for this pull request.

Review status Updated
🟢 Reviewed (for maintainers only) Nov 4, 2026, 3:09 PM UTC

@github-actions github-actions Bot added the needs:design-review Affects visuals — Design should review label Nov 4, 2026
@github-actions

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

PR Analysis Report

🔎 Preview · 572d85d

Storybook · Sandbox · built from this PR's head

Modified components

Component Size LoC Visual · A11y · RTL
InfoTip · Storybook 36.8 kB (0) · 5.0 kB CSS (0) 160 (0) — · ✓ · —

Package size:

  • @astryxdesign/cli 3.34 MB packed (+1.1 kB); no new dependencies
  • @astryxdesign/core 6.32 MB packed (+324 B); no new dependencies

API changes: none in this pull request

Committed API report behind this build: cli 8 rows, theme-butter 1 row, theme-chocolate 1 row, theme-gothic 1 row, theme-matcha 1 row, theme-neutral 1 row, theme-stone 1 row, theme-y2k 1 row; run pnpm api:report.

Touched components checked; add ci:run-visual to run the full suite.


Generated by PR Enrichment workflow | View full report

@cixzhang cixzhang changed the title [Component Audit] InfoTip: the docs page gets worked examples, and the toggletip states are proven in a browser [Component Audit] InfoTip: the docs page gets worked examples, and hover, focus, pin, and Escape are proven in a browser Nov 4, 2026
@cixzhang
cixzhang marked this pull request as ready for review November 4, 2026 12:06

@astracat-bot astracat-bot Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Changes requested: the InfoTip examples, anatomy and browser audit hold up, but one fix is needed before this can merge.

  • apps/sandbox/scripts/next-export-routes.json needs /templates/InfoTipMetricDefinitions/, /templates/InfoTipPermissionNotes/ and /templates/InfoTipShowcase/ (sorted after /templates/IconStatusIcons/); without them apps/sandbox/src/route-manifest.test.ts fails and the Sandbox build in the docs deploy stops, which matches the docs preview failure on both commits.

The Chromium audit spec passes all 17 of its tests against a Storybook built from this head, and the new unit test covers the icon at every size. CI started on this head when it was marked ready and had not finished when this review was written.

[Automated review]

"aliases": []
},
{
"name": "example-info-tip-metric-definitions",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The shadcn route lock gets the three new blocks, but the Sandbox route list does not: apps/sandbox/scripts/next-export-routes.json also needs /templates/InfoTipMetricDefinitions/, /templates/InfoTipPermissionNotes/ and /templates/InfoTipShowcase/, sorted after /templates/IconStatusIcons/. Without them apps/sandbox/src/route-manifest.test.ts fails, and the Sandbox build that the docs deploy runs stops in verify-export.mjs with "Static route mismatch".

@cixzhang cixzhang added ci:run-a11y Run the accessibility suite on this PR; write access, next push (AST-030 FR12) ci:run-rtl Run the RTL suite on this PR; write access, next push (AST-030 FR12) labels Nov 4, 2026

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approved pending CI: the required build, test and docsite-test suites were deferred on this push and still need to run before merge.

The three Sandbox routes fix the earlier route-contract and docs-deploy failure: the Sandbox route test and build pass on this head, and the docs preview now deploys. The InfoTip examples, anatomy and toggletip wording match the component's contract, and the focus, click, Enter and Escape states check out in Chromium. The description still reads as the draft placeholder.

[Automated review]

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Changes requested: one wording fix in the changeset before this can merge.

  • Miss: .changeset/info-tip-audit-examples.md says astryx component InfoTip now has worked examples, but that command prints the new Anatomy table and no example (they appear only with --showcase and --blocks), so name those flags in the changeset and in the description's User impact.

Everything else holds on this head: the showcase, the two examples, the anatomy list and the toggletip sentence match InfoTip's contract, and CI is green, including the 16 Chromium audit frames.

[Automated review]

Comment thread .changeset/info-tip-audit-examples.md Outdated
'@astryxdesign/core': patch
---

[docs] InfoTip: the component page and `astryx component InfoTip` now have worked examples — a showcase metric label, a row of metric definitions, and read-only settings with permission notes. InfoTip's docs list its anatomy (trigger button, info icon, help surface) and say it follows the toggletip pattern: the button reports `aria-expanded="true"` while the help is pinned, and a screen reader hears the help once when it pins.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Miss: on this head astryx component InfoTip prints the new Anatomy table but no example; the blocks appear only under astryx component InfoTip --showcase (the showcase source) and --blocks (the list). Suggested wording: "the component page, astryx component InfoTip --showcase and astryx component InfoTip --blocks now have worked examples". The description's User impact makes the same claim.

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Changes requested: one sentence in the pull request description still needs the fix the changeset got.

  • The description's User impact says astryx component InfoTip now shows the showcase and the two examples, but on this head that command prints the new Anatomy table and no example (they appear only with --showcase and --blocks), so name those flags there as the changeset now does.

The changeset, the three blocks, the anatomy list and the toggletip sentence match InfoTip's contract, and the 16 Chromium audit frames pass on this head. The description's Audit result and Evidence sections also still cite the previous head. One non-blocking inline suggestion covers the InfoTip.tsx header length.

[Automated review]

* - /docs/specs/components/InfoTip/InfoTip.spec.md (contract)
* - /packages/core/src/InfoTip/InfoTip.test.tsx (tests for new/changed behavior)
* - /packages/core/src/InfoTip/index.ts (exports if types change)
* - /packages/cli/assets/templates/blocks/components/InfoTip/ (showcase and example blocks)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Miss, non-blocking: with this line the file header holds 13 lines between /** and */, past the about-12-line header that architecture:knowledge-contracts INV29 allows. Keep this SYNC: line and fold @input and @position onto one line each, for example @input React, StyleX, useTooltip, Icon, the translator, the shared hit area, tokens.

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approved: the InfoTip showcase, the two example blocks, the anatomy list and the toggletip sentence match InfoTip's contract, and the description now names --showcase and --blocks, which is where the examples appear.

CI is green on this head, including the 16 Chromium audit frames, and the new size test fails when the icon ignores size or uses other artwork. The earlier non-blocking note on the InfoTip.tsx header length stays a follow-up.

[Automated review]

@cixzhang
cixzhang merged commit d9a3da5 into main Nov 4, 2026
107 of 110 checks passed
@github-actions
github-actions Bot deleted the night-watch-component-audit/InfoTip/2026-11-04 branch November 5, 2026 06:03

This branch was successfully deployed

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

Labels

ci:run-a11y Run the accessibility suite on this PR; write access, next push (AST-030 FR12) ci:run-rtl Run the RTL suite on this PR; write access, next push (AST-030 FR12) CLA Signed This label is managed by the Meta Open Source bot. needs:design-review Affects visuals — Design should review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant