Skip to content

[Interactive Graph] Add WB Announcer to Quadratic graph.#3678

Open
catandthemachines wants to merge 2 commits into
mainfrom
catjohnson/wb-announcer-quad
Open

[Interactive Graph] Add WB Announcer to Quadratic graph.#3678
catandthemachines wants to merge 2 commits into
mainfrom
catjohnson/wb-announcer-quad

Conversation

@catandthemachines
Copy link
Copy Markdown
Member

@catandthemachines catandthemachines commented May 28, 2026

Summary:

Wires the Quadratic graph's movePoint action into the WB Announcer
pipeline.

What this PR does:

  • Reducer: case "quadratic" in doMovePoint now emits
    stateAnnouncement: {type: "move-quadratic-point", pointIndex, x, y, vertex}.
    The reducer pre-computes the vertex from the new quadratic
    coefficients — vertex is null when a === 0 (the parabola
    degenerates to a line and has no vertex).
  • Types: adds MoveQuadraticPointAnnouncement to InteractiveGraphStateAnnouncement.
  • Screen reader text: getAnnouncementText handles
    "move-quadratic-point" by composing the quadrant-aware point label
    with the vertex string when present:
    • getQuadraticPointString(pointIndex + 1, [x, y], strings, locale) for the moved point
      (origin / on-axis / quadrant 1-4 variants)
    • When vertex \!== null, appends getQuadraticVertexString(vertex, strings)
      (origin / on-axis / quadrant 1-4 variants)
  • Helper move: relocates getCoordQuadrant, getQuadraticVertexString,
    and getQuadraticPointString from graphs/utils.ts to
    graphs/screenreader-text.ts. utils.ts was already importing
    srFormatNumber from screenreader-text.ts, so importing the
    quadratic string helpers back would have created a cycle. Moving them
    keeps the dependency one-way (utils.tsscreenreader-text.ts).
    quadratic.tsx is updated to import the helpers from their new home.
  • Quadratic component: passes ariaLive="off" to each MovablePoint
    so the WB Announcer is the only source of move announcements for
    quadratic. Includes a TODO(LEMS-4189) on the call site to remove
    the prop once aria-live is dropped from useControlPoint.
  • Tests: adds two reducer tests for movePoint on quadratic (a normal
    move emits the announcement with a non-null vertex; a move that
    produces collinear points emits the announcement with vertex: null),
    and four screenreader-text tests covering each branch of the
    composed label (point in a quadrant + vertex in a quadrant, point on
    an axis + vertex at the origin, point at the origin + vertex on an
    axis, degenerate-line case where the vertex is omitted entirely).

Issue: LEMS-4192

Test plan:

Automated

  • pnpm tsc — passes
  • pnpm lint packages/perseus — passes

Manual (reviewer)

  • Open the Interactive Graph → Quadratic story in Storybook (pnpm storybook). Turn on VoiceOver / NVDA (or use the Storybook a11y addon's live-region inspector).
  • Tab to any of the three control-point handles. Confirm the initial focus announces the point's aria-label (unchanged — still includes the vertex context).
  • Press arrow keys to move the focused point one snap step at a time. Confirm:
    • You hear the point label appropriate to the point's new location, e.g.:
      • "Point 1 on parabola in quadrant 2 at -2 comma 4." when the point lands in a quadrant.
      • "Point 2 on parabola at 3 comma 0." when the point lands on an axis.
      • "Point 3 on parabola at the origin." when the point lands at the origin.
    • When the parabola is a real curve, you also hear the vertex line, e.g. "Vertex is in quadrant 4." / "Vertex is at the origin." / "Vertex is on the X-axis." / "Vertex is on the Y-axis." based on the new vertex location.
    • You do not hear the announcement twice. Before this PR, both the per-point aria-live and the WB Announcer would have fired.
  • Arrange the three control points so they are collinear (e.g. all on y = x). Move one of them and confirm the announcement is only the point label — no vertex sentence — since the parabola has degenerated to a line.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 28, 2026

Size Change: +159 B (+0.03%)

Total Size: 505 kB

📦 View Changed
Filename Size Change
packages/perseus/dist/es/index.js 198 kB +159 B (+0.08%)
ℹ️ View Unchanged
Filename Size
packages/kas/dist/es/index.js 20.6 kB
packages/keypad-context/dist/es/index.js 1 kB
packages/kmath/dist/es/index.js 6.32 kB
packages/math-input/dist/es/index.js 98.5 kB
packages/math-input/dist/es/strings.js 1.61 kB
packages/perseus-core/dist/es/index.item-splitting.js 12.1 kB
packages/perseus-core/dist/es/index.js 26.1 kB
packages/perseus-editor/dist/es/index.js 104 kB
packages/perseus-linter/dist/es/index.js 9.41 kB
packages/perseus-score/dist/es/index.js 10.2 kB
packages/perseus-utils/dist/es/index.js 403 B
packages/perseus/dist/es/strings.js 8.55 kB
packages/pure-markdown/dist/es/index.js 1.39 kB
packages/simple-markdown/dist/es/index.js 6.71 kB

compressed-size-action

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 28, 2026

npm Snapshot: Published

Good news!! We've packaged up the latest commit from this PR (3cad008) and published it to npm. You
can install it using the tag PR3678.

Example:

pnpm add @khanacademy/perseus@PR3678

If you are working in Khan Academy's frontend, you can run the below command.

./dev/tools/bump_perseus_version.ts -t PR3678

If you are working in Khan Academy's webapp, you can run the below command.

./dev/tools/bump_perseus_version.js -t PR3678

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Moved these functions to screenreader-text.ts to avoid circular dependency.

// (Undefined means the quadratic graph is a line and has no vertex.)
const srQuadraticVertex =
a !== 0 ? getQuadraticVertexString(vertex, strings) : undefined;
vertex === undefined
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Since the vertex is now calculated using the above function. It will return defined or undefined if there is a vertex to describe.

@catandthemachines catandthemachines marked this pull request as ready for review May 28, 2026 19:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant