Skip to content

[ Interactive Graph | Vector Graph ] PR5: Editor Support#3443

Merged
SonicScrewdriver merged 5 commits intomainfrom
LEMS-3971/vector-pr5
Apr 28, 2026
Merged

[ Interactive Graph | Vector Graph ] PR5: Editor Support#3443
SonicScrewdriver merged 5 commits intomainfrom
LEMS-3971/vector-pr5

Conversation

@SonicScrewdriver
Copy link
Copy Markdown
Contributor

@SonicScrewdriver SonicScrewdriver commented Apr 1, 2026

Summary

This PR was created with the help of AI, albeit with heavy oversight and review.

This is part of a series of PRs implementing the vector graph type for the Interactive Graph widget:

PR1 – type definitions and schema
PR2 – state management
PR3 – rendering & accessibility
PR4 – scoring
▶️ PR5 – editor support (this PR)

Issue: LEMS-3971

  • Surfaces the vector graph type in the content-creator UI. Once landed and the feature flag is enabled, content creators can author vector graph exercises.

Changes:

  • graph-type-selector.tsx — Adds "Vector" option to the graph type dropdown, gated behind interactive-graph-vector feature flag.
  • start-coords/types.ts — Adds {type: "vector"} to GraphTypesThatHaveStartCoords union.
  • start-coords/util.ts — Imports getVectorCoords and adds case "vector" in getDefaultGraphStartCoords.
  • start-coords/start-coords-settings.tsx — Adds case "vector" dispatching to <StartCoordsLine> (reuses the existing component since vector has the same CollinearTuple shape as ray/linear).
  • interactive-graph-question-builder.ts — Adds withVector() builder method and VectorGraphConfig class to the editor's test data builder.
  • testdata/interactive-graph.testdata.ts — Adds vectorMinimalQuestion test fixture for the editor story.
  • interactive-graph-editor.stories.tsx — Adds InteractiveGraphVector editor Storybook story.

Design decisions:

  • No editor validation for overlapping start coords — Consistent with ray, linear, and segment which also don't validate for overlapping points in the editor. The reducer already rejects moves that would cause overlap during interaction.
  • Reuses StartCoordsLine — Vector's CollinearTuple start coords shape matches ray/linear, so no custom start coords component is needed (unlike exponential which has an asymptote field).

Test plan:

  • pnpm tsc — no new type errors
  • pnpm lint — no lint errors
  • Verified in Storybook: editor correctly shows vector graph type when feature flag is enabled, start coords UI works
  • No existing tests regress

@SonicScrewdriver SonicScrewdriver self-assigned this Apr 1, 2026
@SonicScrewdriver SonicScrewdriver changed the title docs(changeset): Creation of new Vector Graph Editor [ Interactive Graph | Vector Graph ] PR5: Editor Support Apr 1, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 1, 2026

🗄️ Schema Change: No Changes ✅

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 1, 2026

🛠️ Item Splitting: No Changes ✅

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 1, 2026

Size Change: +179 B (+0.04%)

Total Size: 502 kB

📦 View Changed
Filename Size Change
packages/perseus-editor/dist/es/index.js 103 kB +179 B (+0.17%)
ℹ️ 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.36 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 kB
packages/perseus-core/dist/es/index.js 25.2 kB
packages/perseus-linter/dist/es/index.js 9.42 kB
packages/perseus-score/dist/es/index.js 9.78 kB
packages/perseus-utils/dist/es/index.js 403 B
packages/perseus/dist/es/index.js 198 kB
packages/perseus/dist/es/strings.js 8.46 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 Apr 1, 2026

npm Snapshot: Published

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

Example:

pnpm add @khanacademy/perseus@PR3443

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

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

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

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

@SonicScrewdriver SonicScrewdriver force-pushed the LEMS-3971/vector-pr4 branch 2 times, most recently from 4f81f2b to 9df7edc Compare April 13, 2026 21:21
@SonicScrewdriver SonicScrewdriver force-pushed the LEMS-3971/vector-pr4 branch 2 times, most recently from 22d9919 to bb050ee Compare April 15, 2026 22:19
@SonicScrewdriver SonicScrewdriver marked this pull request as ready for review April 15, 2026 23:42
Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

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

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

Copy link
Copy Markdown
Contributor

@ivyolamit ivyolamit left a comment

Choose a reason for hiding this comment

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

@SonicScrewdriver overall PR looks good, i just have few non-blocking comments. Great work here! Editor looks good 👌🏼

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.

ooopppss I think not all new graph types has editor stories 🙈
let's create a follow-up tasks for it

<OptionItem value="segment" label="Line Segment(s)" />
<OptionItem value="ray" label="Ray" />
{showVector && <OptionItem value="vector" label="Vector" />}
<OptionItem value="angle" label="Angle" />
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.

Not sure if there was a reason adding the Angle at the last, but can we rearrange this, looks weird Angle is at the bottom 😓

Image

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I agree! I wonder if we should have this be a separate ticket to discuss with content. My inclination is just to make everything alphabetical, but perhaps they would prefer a different order according to the graph types frequency of use?

correct={this.props.correct}
onChange={this.props.onChange}
/>
)}
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.

Just an observation, probably it's the intended behavior of Correct Answer section the coordinates will not show up at initial render. I noticed this in Absolute Value. But it would be nice to see the initial coordinates like other graphs. (See (5.000, 5.000) on the right.)

Initial After Moving
Image Image

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Oh! Yeah I fully agree, I'll update this so that it's always visible.


export default function VectorAnswerOptions({correct, onChange}: Props) {
return (
<LabeledRow label="Student answer must">
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.

This is something I noticed when doing the POC yesterday in Matthew's interactive but not scored PR, the font of a label beside a dropdown is not consistent with the rest of the editor. I'm not sure if it was intentional, but in the POC i did made it consistent. I'll leave that up to you if you'll update that here, it's a trivial thing and not a blocker.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Oooo I'll look into this to make sure I've implemented it how we've set up the feature previously. I was pretty sure I copied this logic exactly from the Polygon Graph, but I could have missed something!

<OptionItem value="exact" label="match exactly" />
<OptionItem value="congruent" label="be congruent" />
</SingleSelect>
<InfoTip>
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 font in the info tip here looks smaller and not consistent styling with the screen reader tree.

Congruent Screen reader tree
Image Image

I can't pin point where it is defined in screen reader tree code, it looks the same how you implemented here <InfoTip> 🤔

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm less inclined to worry about this if it's a deep dive, but I'll give it a quick look to see if I can notice anything different about my implementation! :)

@SonicScrewdriver SonicScrewdriver changed the base branch from LEMS-3971/vector-pr4 to main April 28, 2026 01:36
An error occurred while trying to automatically change base from LEMS-3971/vector-pr4 to main April 28, 2026 01:36
@SonicScrewdriver SonicScrewdriver merged commit a339660 into main Apr 28, 2026
11 checks passed
@SonicScrewdriver SonicScrewdriver deleted the LEMS-3971/vector-pr5 branch April 28, 2026 01:51
SonicScrewdriver added a commit that referenced this pull request Apr 28, 2026
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @khanacademy/perseus-core@25.0.0

### Major Changes

- [#3511](#3511)
[`15b0193db5`](15b0193)
Thanks [@benchristel](https://github.com/benchristel)! - Remove unused
`static` field from PerseusCSProgramWidgetOptions. Callers should update
test data that constructs `PerseusCSProgramWidgetOptions` to remove the
static field.

### Minor Changes

- [#3441](#3441)
[`de45286302`](de45286)
Thanks [@SonicScrewdriver](https://github.com/SonicScrewdriver)! -
Creation of new Vector graph and subcomponents.


- [#3433](#3433)
[`b4bb6e2f42`](b4bb6e2)
Thanks [@SonicScrewdriver](https://github.com/SonicScrewdriver)! -
Creation of initial types and stubs for Vector graph

### Patch Changes

- [#3434](#3434)
[`de2dda0258`](de2dda0)
Thanks [@SonicScrewdriver](https://github.com/SonicScrewdriver)! -
Implementation of state management logic for new Vector graph

- Updated dependencies
\[[`a5b9105c28`](a5b9105)]:
    -   @khanacademy/kas@2.2.2

## @khanacademy/perseus@77.3.0

### Minor Changes

- [#3441](#3441)
[`de45286302`](de45286)
Thanks [@SonicScrewdriver](https://github.com/SonicScrewdriver)! -
Creation of new Vector graph and subcomponents.


- [#3433](#3433)
[`b4bb6e2f42`](b4bb6e2)
Thanks [@SonicScrewdriver](https://github.com/SonicScrewdriver)! -
Creation of initial types and stubs for Vector graph


- [#3494](#3494)
[`8fb79829d0`](8fb7982)
Thanks [@ivyolamit](https://github.com/ivyolamit)! - Interactive Graph:
change asymptote line to dashed for both exponential and logarithm based
on user feedback

### Patch Changes

- [#3523](#3523)
[`c89cdbe2aa`](c89cdbe)
Thanks [@SonicScrewdriver](https://github.com/SonicScrewdriver)! -
Ensure the default coords for Exponential and Logarithm are slightly
further away from the asymptote.


- [#3508](#3508)
[`16f7f77ba1`](16f7f77)
Thanks [@nishasy](https://github.com/nishasy)! - [Image] | (CX) | Give
explore modal launcher a label saying it has description


- [#3496](#3496)
[`4d923417cd`](4d92341)
Thanks [@SonicScrewdriver](https://github.com/SonicScrewdriver)! - Add
fallback label to Numeric Inputs and a linter warning for missing labels
in the editor.


- [#3511](#3511)
[`15b0193db5`](15b0193)
Thanks [@benchristel](https://github.com/benchristel)! - Remove unused
`static` field from PerseusCSProgramWidgetOptions. Callers should update
test data that constructs `PerseusCSProgramWidgetOptions` to remove the
static field.


- [#3504](#3504)
[`b8178b52e7`](b8178b5)
Thanks [@nishasy](https://github.com/nishasy)! - [Image] | (a11y) | Add
aria-describedby to Explore Image modal


- [#3488](#3488)
[`3abc5e8277`](3abc5e8)
Thanks [@mark-fitzgerald](https://github.com/mark-fitzgerald)! - [Free
Response] Add visual regression tests


- [#3493](#3493)
[`11742c2cff`](11742c2)
Thanks [@SonicScrewdriver](https://github.com/SonicScrewdriver)! -
Implementing bug fix for jumping MovableLines in the Correct Answer
graph in the editor


- [#3483](#3483)
[`7794943ec7`](7794943)
Thanks [@nishasy](https://github.com/nishasy)! - [ColorSync] Numeric
Input - update visual regression tests


- [#3434](#3434)
[`de2dda0258`](de2dda0)
Thanks [@SonicScrewdriver](https://github.com/SonicScrewdriver)! -
Implementation of state management logic for new Vector graph

- Updated dependencies
\[[`de45286302`](de45286),
[`4d923417cd`](4d92341),
[`15b0193db5`](15b0193),
[`b4bb6e2f42`](b4bb6e2),
[`d3ef4dbcc2`](d3ef4db),
[`a5b9105c28`](a5b9105),
[`de2dda0258`](de2dda0)]:
    -   @khanacademy/perseus-core@25.0.0
    -   @khanacademy/perseus-linter@4.9.5
    -   @khanacademy/perseus-score@8.7.0
    -   @khanacademy/kas@2.2.2
    -   @khanacademy/keypad-context@3.2.44
    -   @khanacademy/kmath@2.4.2
    -   @khanacademy/math-input@26.4.15

## @khanacademy/perseus-editor@30.4.0

### Minor Changes

- [#3441](#3441)
[`de45286302`](de45286)
Thanks [@SonicScrewdriver](https://github.com/SonicScrewdriver)! -
Creation of new Vector graph and subcomponents.


- [#3443](#3443)
[`a3396604a7`](a339660)
Thanks [@SonicScrewdriver](https://github.com/SonicScrewdriver)! -
Creation of new Vector Graph Editor


- [#3433](#3433)
[`b4bb6e2f42`](b4bb6e2)
Thanks [@SonicScrewdriver](https://github.com/SonicScrewdriver)! -
Creation of initial types and stubs for Vector graph


- [#3492](#3492)
[`883133a28f`](883133a)
Thanks [@jeremywiebe](https://github.com/jeremywiebe)! - Add preview
data sanitizer to strip non-serializable values before postMessage

### Patch Changes

- [#3522](#3522)
[`19911cc966`](19911cc)
Thanks [@SonicScrewdriver](https://github.com/SonicScrewdriver)! - Label
absolute-value graph start coordinates as "Vertex" and "Arm" in the
editor instead of "Point 1" and "Point 2".


- [#3505](#3505)
[`1ab914fc41`](1ab914f)
Thanks [@nishasy](https://github.com/nishasy)! - [Image] | (CX) | Add
warning for large images


- [#3530](#3530)
[`b5e918e8b3`](b5e918e)
Thanks [@nishasy](https://github.com/nishasy)! - [Image] Update copy of
recalculate button in editor


- [#3434](#3434)
[`de2dda0258`](de2dda0)
Thanks [@SonicScrewdriver](https://github.com/SonicScrewdriver)! -
Implementation of state management logic for new Vector graph

- Updated dependencies
\[[`de45286302`](de45286),
[`c89cdbe2aa`](c89cdbe),
[`16f7f77ba1`](16f7f77),
[`4d923417cd`](4d92341),
[`15b0193db5`](15b0193),
[`b8178b52e7`](b8178b5),
[`b4bb6e2f42`](b4bb6e2),
[`d3ef4dbcc2`](d3ef4db),
[`3abc5e8277`](3abc5e8),
[`a5b9105c28`](a5b9105),
[`11742c2cff`](11742c2),
[`7794943ec7`](7794943),
[`de2dda0258`](de2dda0),
[`8fb79829d0`](8fb7982)]:
    -   @khanacademy/perseus@77.3.0
    -   @khanacademy/perseus-core@25.0.0
    -   @khanacademy/perseus-linter@4.9.5
    -   @khanacademy/perseus-score@8.7.0
    -   @khanacademy/kas@2.2.2
    -   @khanacademy/keypad-context@3.2.44
    -   @khanacademy/kmath@2.4.2
    -   @khanacademy/math-input@26.4.15

## @khanacademy/perseus-score@8.7.0

### Minor Changes

- [#3442](#3442)
[`d3ef4dbcc2`](d3ef4db)
Thanks [@SonicScrewdriver](https://github.com/SonicScrewdriver)! - Added
ability to score Vector Interactive Graphs

### Patch Changes

- Updated dependencies
\[[`de45286302`](de45286),
[`15b0193db5`](15b0193),
[`b4bb6e2f42`](b4bb6e2),
[`a5b9105c28`](a5b9105),
[`de2dda0258`](de2dda0)]:
    -   @khanacademy/perseus-core@25.0.0
    -   @khanacademy/kas@2.2.2
    -   @khanacademy/kmath@2.4.2

## @khanacademy/kas@2.2.2

### Patch Changes

- [#3503](#3503)
[`a5b9105c28`](a5b9105)
Thanks [@benchristel](https://github.com/benchristel)! - Expressions are
now compared more thoroughly. Now we always check that the expressions
evaluate the same with all variables bound to -1, 0, and 1. We also
check more randomly-chosen values: 28 instead of 12.

## @khanacademy/keypad-context@3.2.44

### Patch Changes

- Updated dependencies
\[[`de45286302`](de45286),
[`15b0193db5`](15b0193),
[`b4bb6e2f42`](b4bb6e2),
[`de2dda0258`](de2dda0)]:
    -   @khanacademy/perseus-core@25.0.0

## @khanacademy/kmath@2.4.2

### Patch Changes

- Updated dependencies
\[[`de45286302`](de45286),
[`15b0193db5`](15b0193),
[`b4bb6e2f42`](b4bb6e2),
[`de2dda0258`](de2dda0)]:
    -   @khanacademy/perseus-core@25.0.0

## @khanacademy/math-input@26.4.15

### Patch Changes

- Updated dependencies
\[[`de45286302`](de45286),
[`15b0193db5`](15b0193),
[`b4bb6e2f42`](b4bb6e2),
[`de2dda0258`](de2dda0)]:
    -   @khanacademy/perseus-core@25.0.0
    -   @khanacademy/keypad-context@3.2.44

## @khanacademy/perseus-linter@4.9.5

### Patch Changes

- [#3496](#3496)
[`4d923417cd`](4d92341)
Thanks [@SonicScrewdriver](https://github.com/SonicScrewdriver)! - Add
fallback label to Numeric Inputs and a linter warning for missing labels
in the editor.

- Updated dependencies
\[[`de45286302`](de45286),
[`15b0193db5`](15b0193),
[`b4bb6e2f42`](b4bb6e2),
[`a5b9105c28`](a5b9105),
[`de2dda0258`](de2dda0)]:
    -   @khanacademy/perseus-core@25.0.0
    -   @khanacademy/kas@2.2.2
    -   @khanacademy/kmath@2.4.2
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.

3 participants