Skip to content

[Color][Graded Group] Convert graded-group font and colors to semantic tokens#3836

Draft
Myranae wants to merge 14 commits into
mainfrom
tb/LEMS-4266/graded-group-color-sync
Draft

[Color][Graded Group] Convert graded-group font and colors to semantic tokens#3836
Myranae wants to merge 14 commits into
mainfrom
tb/LEMS-4266/graded-group-color-sync

Conversation

@Myranae

@Myranae Myranae commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Summary:

Replaces all hardcoded font sizes, font weights, colors, border widths, and border radii in graded-group, graded-group-answer-bar, and graded-group-set with Wonder Blocks semantic and structural tokens. Adds visual regression stories for both widgets establishing a Chromatic baseline before the changes.

One design gap was identified: the try-again icon's teal (#63D9EA) has no semantic equivalent in the WB token system and was mapped to foreground.instructive.default as the closest semantic intent — a design token for teal/cyan action states is recommended.

color-changes-visualization

Issue: LEMS-4266

Test plan:

  • Chromatic diffs show only intentional color/font changes against the baseline
  • All checks pass

@Myranae Myranae self-assigned this Jun 29, 2026
@github-actions

github-actions Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Size Change: -21 B (0%)

Total Size: 517 kB

📦 View Changed
Filename Size Change
packages/perseus/dist/es/index.js 204 kB -21 B (-0.01%)
ℹ️ 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.31 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.9 kB
packages/perseus-core/dist/es/index.js 27.6 kB
packages/perseus-editor/dist/es/index.js 104 kB
packages/perseus-linter/dist/es/index.js 9.79 kB
packages/perseus-score/dist/es/index.js 9.86 kB
packages/perseus-utils/dist/es/index.js 403 B
packages/perseus/dist/es/strings.js 12.4 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

github-actions Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

npm Snapshot: Published

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

Example:

pnpm add @khanacademy/perseus@PR3836

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

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

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

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

@Myranae Myranae changed the title wip - [Color][Graded Group] Convert tokens and add stories for Graded Group wip - [Color][Graded Group] Convert graded-group font and colors to semantic tokens Jun 30, 2026
@Myranae Myranae changed the title wip - [Color][Graded Group] Convert graded-group font and colors to semantic tokens [Color][Graded Group] Convert graded-group font and colors to semantic tokens Jun 30, 2026
fontWeight: "bold",
fontSize: fontSize,
fontWeight: font.weight.bold,
fontSize: font.size.medium,

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.

This is not exact. 17→font.size.medium (16px) is the change here.

fontSize: 28,
color: "#63D9EA",
fontSize: font.size.xxLarge,
color: semanticColor.core.foreground.instructive.default,

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.

It doesn't seem like teal has a semantic equivalent, so we used instructive blue here.

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.

Do we need sign-off from UX for this?

gradedGroups: [
generateGradedGroupOptions({
title: "Problem 1a",
content: "$0.5 + 0.4 =$ [[☃ numeric-input 1]]",

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 wonder if we should have some additional content included, like regular text, lists, bold, italic, etc. Maybe even a table?

const secondIndicator = canvas.getByRole("button", {
name: "Problem 1b",
});
await userEvent.click(secondIndicator);

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 wonder if we can combine a couple of tests with this one. Instead of clicking the indicator, can we use keyboard navigation to get focus on it and then using the enter key to do the navigation? That way, the focus indicator stays on the navigation dot, and we can see the content change.

},
};

export const DesktopFirstGroupCorrectAnswer: Story = {

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.

Do we need an incorrect/try-again story, also?

title: {
fontSize: 12,
fontSize: font.heading.size.small,
color: semanticColor.core.foreground.neutral.subtle,

@mark-fitzgerald mark-fitzgerald Jul 6, 2026

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.

While we are here, I think we should modify the color to be accessible. It is currently at a contrast ratio of 4.46, which is just shy of the minimum 4.5. If we instead go with semanticColor.core.foreground.neutral.default, we can get a ratio of 5.82.

},
hint: {
content:
"Solar power is renewable because sunlight is continuously available.",

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.

Except at night. Just sayin'.

},
};

export const RightToLeft: Story = {

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 would love to have this as an automatic "theme", like with SYL and dark mode. Not asking to do that here, but one day, maybe.

images: {},
} satisfies Partial<PerseusGradedGroupWidgetOptions>;

export const DesktopWithTex: Story = {

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 feels more like a "TeX in Radio" story than a "TeX in Graded Group" story. Is there a way that we can minimize the use of a full-featured widget for something simpler, like numeric-input?

@@ -257,16 +251,27 @@ export class GradedGroup

let gradeStatus: string | null = null;
let icon = null;

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.

Since we are here, should we type this to avoid all the @ts-expect-error lines?

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.

2 participants