Skip to content

refactor: locked polygon points shape#3705

Open
mojadem wants to merge 10 commits into
mainfrom
mojadem/locked-polygon-point/1
Open

refactor: locked polygon points shape#3705
mojadem wants to merge 10 commits into
mainfrom
mojadem/locked-polygon-point/1

Conversation

@mojadem

@mojadem mojadem commented Jun 1, 2026

Copy link
Copy Markdown

Summary

This is the first PR in a stack to enable per-vertex angle labeling in locked polygons.

  • Add LockedPolygonPointType with shape {coord: Coord}
  • Change LockedPolygonType.points from type Coord[] to LockedPolygonPointType[]
  • Update rendering, editor, linter, defaults, fixtures, stories, and tests to use points.coord
  • Keep parser backwards-compatible by accepting legacy raw Coord[] polygon points and normalizing to the new shape
  • Add parser coverage for both new and legacy locked polygon point formats

Next steps

  • Extend LockedPolygonPointType with a showAngle field that determines whether the angle should be shown for that point (feat: add showAngle field to LockedPolygonPointType #3730)
  • Extend LockedPolygonPointType with a computedAngle field that is populated during parsing with the computed angle measurement

Test plan

  • pnpm jest packages/perseus-core/src/parse-perseus-json/regression-tests/parse-perseus-json-regression.test.ts -u --runInBand --watchman=false
  • pnpm jest packages/perseus-core/src/parse-perseus-json/perseus-parsers/interactive-graph-widget.test.ts packages/perseus-core/src/utils/get-default-figure-for-type.test.ts packages/perseus-core/src/utils/generators/interactive-graph-widget-generator.test.ts packages/perseus-linter/src/rules/interactive-graph-widget-error.test.ts --runInBand --watchman=false

@mojadem mojadem self-assigned this Jun 1, 2026
@mojadem mojadem requested a review from SonicScrewdriver June 1, 2026 20:56
@github-actions github-actions Bot added the schema-change Attached to PRs when we detect Perseus Schema changes in it label Jun 1, 2026
@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

npm Snapshot: Published

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

Example:

pnpm add @khanacademy/perseus@PR3705

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

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

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

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

@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Size Change: +184 B (+0.04%)

Total Size: 508 kB

📦 View Changed
Filename Size Change
packages/perseus-core/dist/es/index.item-splitting.js 12.1 kB +51 B (+0.42%)
packages/perseus-core/dist/es/index.js 26.3 kB +71 B (+0.27%)
packages/perseus-editor/dist/es/index.js 105 kB +41 B (+0.04%)
packages/perseus-linter/dist/es/index.js 9.66 kB +11 B (+0.11%)
packages/perseus/dist/es/index.js 200 kB +10 B (0%)
ℹ️ 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-score/dist/es/index.js 10.2 kB
packages/perseus-utils/dist/es/index.js 403 B
packages/perseus/dist/es/strings.js 8.6 kB
packages/pure-markdown/dist/es/index.js 1.39 kB
packages/simple-markdown/dist/es/index.js 6.71 kB

compressed-size-action

@mojadem mojadem added the item-splitting-change-ack Acknowledges that this PR's item-splitting bundle change has been reviewed label Jun 2, 2026

@SonicScrewdriver SonicScrewdriver 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.

I think this looks good! Thanks for working on this. I'll also tag @jeremywiebe in case he has any further thoughts on the approach.

We'll need to be very careful deploying this, as we need to give the Content Platform a heads up about the schema change before we do. Otherwise we can break publishing. :) Happy to provide support with deploying if you need any!

export type LockedPolygonType = {
type: "polygon";
points: Coord[];
points: LockedPolygonPointType[];

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.

It might be nice to add a comment here explaining the intention to add more data in the LockedPolygonPointType, but it's not strictly neccessary

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

To clarify, I intend on merging the stacked PRs together as one schema change. I will be sure to get the Go schema change deployed first once the target schema is finalized.

@jeremywiebe jeremywiebe left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

A few thoughts, but nothing blocking! Thanks Matt!

Comment on lines +143 to +145
{coord: [-8, -7]},
{coord: [-8, -3]},
{coord: [-4, -3]},

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

These item-data/ files should never be modified as they represent data imported from production. Instead, create a second file with the new structure(s).

See my comment at the top of this file.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Ah, thanks for the heads up! I missed the note at the top of the file. Do we need a regression test in this context, or is unit testing the parser enough?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You should add a new file with this new data format. That way we ensure that our parser remains compatible with all previous known schema versions and supports the new version.

[-1, 0],
[1, 0],
],
points: [{coord: [0, 2]}, {coord: [-1, 0]}, {coord: [1, 0]}],

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nit: I'm not sure if prettier chose this, but the original, multi-line layout reads more easily. No worries if this new inline layout if prettier's choice.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Prettier doesn't allow:

points: [
    { coord: [1, 1] },
    { coord: [2, 2] },
    { coord: [3, 3] },
],

but does allow:

points: [
    {
        coord: [1, 1],
    },
    {
        coord: [2, 2],
    },
    {
        coord: [3, 3],
    },
],

which mirrors the labels below, so I'll update it to that.

expect.objectContaining({
type: "polygon",
points: [...defaultPolygon.points, [0, 0]],
points: [...defaultPolygon.points, {coord: [0, 0]}],

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm assuming this spread works because defaultPolygon.points has been changed to be an array of these new {coord: [number, number]} format?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Right! We do that in packages/perseus-core/src/utils/get-default-figure-for-type.ts

Comment on lines +1122 to +1124
points: squarePolygonPoints
.slice(1)
.map((coord) => ({coord})),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

suggestion: This predates your change, but using the original test data in the assertion is a smell We should inline the values like we do later in this file around lines 1152-1156 (next chunk in this PR)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Agreed! The assertion has been updated.

Comment on lines +69 to +71
const coords = points.map((point) => point.coord);
const coordsToPoints = (coords: Coord[]) =>
coords.map((coord) => ({coord}));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I haven't looked through all the usages of coords in this area, but I wonder if it'd be cleaner to use the new structure everywhere rather than have to keep dealing with both [number, number] and {x: number, y: number}.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Agreed! I updated the logic to always derive from the points prop

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

item-splitting-change item-splitting-change-ack Acknowledges that this PR's item-splitting bundle change has been reviewed olc-5.0.f429d schema-change Attached to PRs when we detect Perseus Schema changes in it

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants