Delete most InputNumber code, replace with NumericInput#3760
Open
benchristel wants to merge 26 commits into
Open
Delete most InputNumber code, replace with NumericInput#3760benchristel wants to merge 26 commits into
benchristel wants to merge 26 commits into
GitHub Actions / PR Comparison: Item Splitting
succeeded
Jun 11, 2026 in 0s
PR Comparison: Item Splitting: Changes Acknowledged ✅
Acknowledged via the
item-splitting-change-acklabel. Remove the label to require re-acknowledgement.
View diff
diff --unified /home/github/work/_temp/branch-compare/base/item-splitting.bundle.js /home/github/work/_temp/branch-compare/pr/item-splitting.bundle.js
--- /home/github/work/_temp/branch-compare/base/item-splitting.bundle.js 2026-06-11 18:46:56.975788949 +0000
+++ /home/github/work/_temp/branch-compare/pr/item-splitting.bundle.js 2026-06-11 18:46:53.975789066 +0000
@@ -6383,13 +6383,54 @@
);
// packages/perseus-core/src/parse-perseus-json/perseus-parsers/input-number-widget.ts
-var booleanToString = (rawValue, ctx) => {
+var booleanToZero = (rawValue, ctx) => {
if (typeof rawValue === "boolean") {
- return ctx.success(String(rawValue));
+ return ctx.success(0);
}
return ctx.failure("boolean", rawValue);
};
-var parseInputNumberWidget = parseWidget(
+var parseMathFormat = enumeration(
+ "integer",
+ "mixed",
+ "improper",
+ "proper",
+ "decimal",
+ "percent",
+ "pi"
+);
+var parseInputNumberWidgetV1 = parseWidgetWithVersion(
+ object({ major: constant(1), minor: number }),
+ constant("input-number"),
+ object({
+ size: string,
+ coefficient: boolean,
+ labelText: optional(string),
+ rightAlign: optional(boolean),
+ answers: array(
+ object({
+ value: optional(nullable(number)),
+ status: string,
+ message: string,
+ answerForms: optional(array(parseMathFormat)),
+ // FIXME: confirm that we need the default on `strict`.
+ // cribbed from numeric-input-widget.ts.
+ strict: defaulted(boolean, () => false),
+ maxError: optional(nullable(number)),
+ simplify: enumeration("required", "enforced", "optional")
+ })
+ )
+ })
+);
+function migrateV0ToV12(v0) {
+ const v1Options = convertInputNumberOptionsToNumericInput(v0.options);
+ return {
+ ...v0,
+ version: { major: 1, minor: 0 },
+ options: v1Options
+ };
+}
+var parseInputNumberWidgetV0 = parseWidgetWithVersion(
+ optional(object({ major: constant(0), minor: number })),
constant("input-number"),
object({
answerType: optional(
@@ -6414,11 +6455,66 @@
// those content items are actually published anywhere, and consider
// updating them.
value: defaulted(
- union(number).or(string).or(booleanToString).parser,
+ union(number).or(string).or(booleanToZero).parser,
() => 0
)
})
);
+function convertInputNumberOptionsToNumericInput(inputNumberOptions) {
+ return {
+ coefficient: false,
+ rightAlign: inputNumberOptions.rightAlign,
+ size: inputNumberOptions.size,
+ answers: [
+ {
+ status: "correct",
+ value: Number(inputNumberOptions.value),
+ simplify: inputNumberOptions.simplify,
+ message: "",
+ maxError: getMaxError(inputNumberOptions),
+ strict: true,
+ answerForms: getAnswerForms(inputNumberOptions)
+ }
+ ]
+ };
+}
+function getMaxError(inputNumberOptions) {
+ if (!inputNumberOptions.inexact) {
+ return 0;
+ }
+ if (inputNumberOptions.maxError == null) {
+ return void 0;
+ }
+ return Number(inputNumberOptions.maxError);
+}
+var mathFormatsForAnswerType = {
+ number: [],
+ decimal: ["decimal"],
+ integer: ["integer"],
+ rational: ["integer", "proper", "improper", "mixed"],
+ improper: ["integer", "proper", "improper"],
+ mixed: ["integer", "proper", "mixed"],
+ percent: ["integer", "decimal", "proper", "improper", "mixed", "percent"],
+ pi: ["pi"]
+};
+function getAnswerForms(options) {
+ const value = Number(options.value);
+ const { inexact } = options;
+ const precision = 1e10;
+ const rounded = Math.round(value * precision) / precision;
+ const answerType = options.answerType ?? "number";
+ if (answerType === "number" && !inexact && !equalFloats(rounded, value)) {
+ return ["proper", "improper", "mixed"];
+ }
+ return mathFormatsForAnswerType[answerType];
+}
+function equalFloats(a, b) {
+ return Math.abs(a - b) < Math.pow(2, -42);
+}
+var parseInputNumberWidget = versionedWidgetOptions(
+ 1,
+ parseInputNumberWidgetV1
+).withMigrationFrom(0, parseInputNumberWidgetV0, migrateV0ToV12).parser;
// packages/perseus-core/src/parse-perseus-json/perseus-parsers/interaction-widget.ts
var pairOfNumbers3 = pair(number, number);
@@ -7010,7 +7106,7 @@
);
// packages/perseus-core/src/parse-perseus-json/perseus-parsers/numeric-input-widget.ts
-var parseMathFormat = enumeration(
+var parseMathFormat2 = enumeration(
"integer",
"mixed",
"improper",
@@ -7048,7 +7144,7 @@
value: optional(nullable(number)),
status: string,
answerForms: defaulted(
- optional(array(parseMathFormat)),
+ optional(array(parseMathFormat2)),
() => void 0
),
strict: defaulted(boolean, () => false),
@@ -7330,7 +7426,7 @@
}
};
}
-function migrateV0ToV12(widget) {
+function migrateV0ToV13(widget) {
const { options } = widget;
const { noneOfTheAbove: _5, ...rest } = options;
return {
@@ -7343,7 +7439,7 @@
}
};
}
-var parseRadioWidget = versionedWidgetOptions(3, parseRadioWidgetV3).withMigrationFrom(2, parseRadioWidgetV2, migrateV2toV3).withMigrationFrom(1, parseRadioWidgetV1, migrateV1ToV22).withMigrationFrom(0, parseRadioWidgetV0, migrateV0ToV12).parser;
+var parseRadioWidget = versionedWidgetOptions(3, parseRadioWidgetV3).withMigrationFrom(2, parseRadioWidgetV2, migrateV2toV3).withMigrationFrom(1, parseRadioWidgetV1, migrateV1ToV22).withMigrationFrom(0, parseRadioWidgetV0, migrateV0ToV13).parser;
// packages/perseus-core/src/parse-perseus-json/perseus-parsers/sorter-widget.ts
var parseSorterWidget = parseWidget(
Loading