Skip to content

Delete most InputNumber code, replace with NumericInput#3760

Open
benchristel wants to merge 26 commits into
mainfrom
benc/input-number-v2-take-3
Open

Delete most InputNumber code, replace with NumericInput#3760
benchristel wants to merge 26 commits into
mainfrom
benc/input-number-v2-take-3

Conversation

@benchristel

@benchristel benchristel commented Jun 10, 2026

Copy link
Copy Markdown
Member

Summary:

The input-number widget has been deprecated for... a decade? In this PR, we
replace the input-number editor and component with the numeric-input ones. To
make this a drop-in replacement, we migrate the input number data to a new v1
schema in the parser. The v1 schema is identical to the numeric-input schema.

Issue: LEMS-4112

Test plan:

Deploy the dev build to a ZND. Test that input-number widgets can be used and
scored. Test editing: existing input-numbers should display the numeric-input
editor (but the placeholder in the content will still say input-number).

  • incorporate Matthew's textAlign changes
  • deploy Go schema changes
  • change major version number output by editor to 1.
  • make input-number data-schema types alias numeric-input types
  • address all TODO and FIXME comments
  • ensure the perseus service no longer calls scorePerseusItemWithInputNumberAsNumericInput

Comment thread packages/perseus-core/src/data-schema.ts Outdated
@benchristel

Copy link
Copy Markdown
Member Author

/review

… code has been removed; widgets with type "input-number" will now render as NumericInput widgets. This involves a breaking change to the InputNumber widget types in data-schema. Callers should, as always, use the parser to migrate Perseus JSON to the latest schema version before using it, and avoid depending directly on the schema types.
@benchristel

Copy link
Copy Markdown
Member Author

Before this lands, we need to update the Go schema: https://github.com/Khan/webapp/pull/39496

…al function `scorePerseusItemWithInputNumberAsNumericInput`.
@github-actions github-actions Bot added item-splitting-change schema-change Attached to PRs when we detect Perseus Schema changes in it labels Jun 11, 2026
@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Size Change: -1.15 kB (-0.23%)

Total Size: 507 kB

📦 View Changed
Filename Size Change
packages/perseus-core/dist/es/index.item-splitting.js 12.5 kB +494 B (+4.1%)
packages/perseus-core/dist/es/index.js 26.4 kB +135 B (+0.51%)
packages/perseus-editor/dist/es/index.js 104 kB -711 B (-0.68%)
packages/perseus-score/dist/es/index.js 9.88 kB -308 B (-3.02%)
packages/perseus/dist/es/index.js 199 kB -764 B (-0.38%)
ℹ️ 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-linter/dist/es/index.js 9.8 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

@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

npm Snapshot: Published

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

Example:

pnpm add @khanacademy/perseus@PR3760

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

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

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

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

message: "",
strict: true,
},
],

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.

This test and the ones below could use the generator functions.

],
},
alignment: "default",
} as InputNumberWidget,

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.

We should not need to cast here.

Comment on lines +31 to +42
coefficient: false,
answers: [
{
status: "correct",
value: 0.5,
maxError: 0,
simplify: "required",
answerForms: [],
message: "",
strict: true,
},
],

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.

Could use the generator functions.

message: "",
strict: true,
},
],

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.

Could use the generator functions.

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.

This file doesn't have many usages. The data in it could be inlined into the tests that need it, and maybe replaced with generation function calls.

@benchristel benchristel added schema-change-ack Acknowledges that this PR's data-schema change has been reviewed by Content Platform item-splitting-change-ack Acknowledges that this PR's item-splitting bundle change has been reviewed labels Jun 11, 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.

SO STOKED for this! It looks great :)

I just have one blocking comment to check in on the shift of the default of "strict" from false to true, as I want to make sure this was intentional. I also left a non-blocking comment about supporting Khanmigo.

@@ -1,300 +1,7 @@
import {

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.

❤️

simplify: widgetData.simplify,
answerType: widgetData.answerType,
},
label: widgetData.labelText,

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 do wonder about removing simplify and answerType from Khanmigo, as that seems like helpful information for it to have in order to support student questions. I suspect VERY few of our Numeric Inputs have the labelText set, and obviously none of our our Input Numbers will have it either.

I can see that you've just brought this inline to match Numeric Input, but I wonder if we should check in with the Khanmigo team to see if we should be providing these values for both Input Number and Numeric Input.


it("should consider decimals as the thousands separator in FR locale", () => {
// TODO(benchristel): This test seems wrong. The correct answer is 16.5, but
// 16.500,00 is accepted.

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.

Ooooo that's a good find. I recall that the decimal separator logic is a little rough between languages, but I have a feeling we can fix this! :)

simplify: inputNumberOptions.simplify,
message: "",
maxError: getMaxError(inputNumberOptions),
strict: true,

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 thought we had strict set to false before, did you find something that indicated that it would be better to change it to true?

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.

It's been true from the beginning of the project. Here it is on main:

strict: false causes the "default" answer forms to be accepted in addition to the ones explicitly listed. Here's where that logic lives in the numeric-input scoring code:

        // When an answer is set to strict, we validate using ONLY
        // the provided answerForms. If strict is false, or if there
        // were no provided answer forms, we will include all
        // of the default answer forms in our validator.
        if (!answer.strict || validatorForms.length === 0) {
            validatorForms.push(...defaultAnswerForms);
        }

InputNumber never had any equivalent of strict — that is, it always used an explicit allowlist of answer forms. There was no way to also allow the "default" set of forms. Here's the original code for input-number answer forms:

forms: inputNumberAnswerTypes[rubric.answerType].forms,

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.

Oh weird! I was sure it was false. Okay wonderful! My apologies for the confusion

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.7fb98 schema-change Attached to PRs when we detect Perseus Schema changes in it schema-change-ack Acknowledges that this PR's data-schema change has been reviewed by Content Platform

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants