Skip to content

Commit 115a086

Browse files
feat(LEMS-4171): Update answer area to include calculator variant (#3780)
## Summary - `packages/perseus-core/src/data-schema.ts` — adds CalculatorVariant type ("scientific" | "graphing" | "four_function") and extends PerseusAnswerArea with calculatorVariant: CalculatorVariant | null - `packages/perseus-core/src/parse-perseus-json/perseus-parsers/perseus-answer-area.ts` — adds calculatorVariant field to parser using nullable(enumeration(...)) for strict validation; migrates legacy calculator: true content to calculatorVariant: "scientific" on parse - `packages/perseus-core/src/utils/get-default-answer-area.ts` — includes `calculatorVariant: null` in the default answer area - `packages/perseus-editor/src/item-extras-editor.tsx` — converts flat "Show calculator" checkbox into an expandable group matching the financial calculator pattern; selecting the parent defaults to scientific; sub-options behave as mutually exclusive radio buttons - Remaining files add `calculatorVariant:null` to tests ### Notes - The legacy calculator boolean is preserved and kept in sync for backward compatibility while the frontend migrates - Existing content without calculatorVariant defaults to null (or "scientific" if calculator: true) [Associated Webapp Change](Khan/webapp#40228) Issue: LEMS-4171 ## Test plan: Validated with [ZND](https://prod-znd-260616-12526-c35f366.khanacademy.org/math/ap-statistics/bivariate-data-ap/least-squares-regression/e/calculating-equation-least-squares) ### Scenarios tested - [x] Unchecked `Show Calculator` doesn't show Calculator button - [x] Checked defaults to `Scientific` - [x] Changing from default to Graphing shows graphing - [x] Changing to four function shows four function https://github.com/user-attachments/assets/55c08478-508b-4c62-8232-50160b5f821c Author: anakaren-rojas Reviewers: jeremywiebe, anakaren-rojas Required Reviewers: Approved By: jeremywiebe Checks: ⏭️ 1 check has been skipped, ✅ 11 checks were successful Pull Request URL: #3780
1 parent 0bd0842 commit 115a086

25 files changed

Lines changed: 353 additions & 11 deletions

.changeset/angry-meals-sing.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@khanacademy/perseus": minor
3+
"@khanacademy/perseus-core": minor
4+
"@khanacademy/perseus-editor": minor
5+
---
6+
7+
Updates answer area to include calculator variant

packages/perseus-core/src/data-schema.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,12 @@ export const ItemExtras = [
360360
*/
361361
"periodicTableWithKey",
362362
] as const;
363-
export type PerseusAnswerArea = Record<(typeof ItemExtras)[number], boolean>;
363+
364+
export type CalculatorVariant = "scientific" | "graphing" | "four_function";
365+
366+
export type PerseusAnswerArea = Record<(typeof ItemExtras)[number], boolean> & {
367+
calculatorVariant: CalculatorVariant | null;
368+
};
364369

365370
/**
366371
* The type representing the common structure of all widget's options. The

packages/perseus-core/src/feature-flags.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
const PerseusFeatureFlags = [
1313
"input-number-to-numeric-input", // TODO(LEMS-4085): clean up feature flag
1414
"grapher-to-interactive-graph", // TODO(LEMS-4259): clean up feature flag
15+
"desmos-calculator", // TODO(LEMS-4180): clean up feature flag
1516
] as const;
1617

1718
export default PerseusFeatureFlags;

packages/perseus-core/src/parse-perseus-json/perseus-parsers/perseus-answer-area.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import type {PerseusAnswerArea} from "../../data-schema";
1010
describe("parsePerseusAnswerArea", () => {
1111
const allFalse: PerseusAnswerArea = {
1212
calculator: false,
13+
calculatorVariant: null,
1314
financialCalculatorMonthlyPayment: false,
1415
financialCalculatorTotalAmount: false,
1516
financialCalculatorTimeToPayOff: false,
@@ -25,6 +26,7 @@ describe("parsePerseusAnswerArea", () => {
2526
it("keeps `true` values", () => {
2627
const allTrue: PerseusAnswerArea = {
2728
calculator: true,
29+
calculatorVariant: "scientific",
2830
financialCalculatorMonthlyPayment: true,
2931
financialCalculatorTotalAmount: true,
3032
financialCalculatorTimeToPayOff: true,
Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,25 @@
1-
import {boolean, defaulted, object} from "../general-purpose-parsers";
1+
import {
2+
boolean,
3+
defaulted,
4+
enumeration,
5+
nullable,
6+
object,
7+
pipeParsers,
8+
} from "../general-purpose-parsers";
9+
import {convert} from "../general-purpose-parsers/convert";
10+
11+
type CalculatorVariant = "scientific" | "graphing" | "four_function";
212

313
const booleanOrFalse = defaulted(boolean, () => false);
14+
const nullableCalculatorVariant = defaulted(
15+
nullable(enumeration("scientific", "graphing", "four_function")),
16+
() => null,
17+
);
418

5-
export const parsePerseusAnswerArea = defaulted(
19+
const baseParser = defaulted(
620
object({
721
calculator: booleanOrFalse,
22+
calculatorVariant: nullableCalculatorVariant,
823
financialCalculatorMonthlyPayment: booleanOrFalse,
924
financialCalculatorTotalAmount: booleanOrFalse,
1025
financialCalculatorTimeToPayOff: booleanOrFalse,
@@ -13,10 +28,22 @@ export const parsePerseusAnswerArea = defaulted(
1328
}),
1429
() => ({
1530
calculator: false,
31+
calculatorVariant: null,
1632
financialCalculatorMonthlyPayment: false,
1733
financialCalculatorTotalAmount: false,
1834
financialCalculatorTimeToPayOff: false,
1935
periodicTable: false,
2036
periodicTableWithKey: false,
2137
}),
2238
);
39+
40+
export const parsePerseusAnswerArea = pipeParsers(baseParser).then(
41+
convert((parsed) => {
42+
const calculatorVariant: CalculatorVariant | null =
43+
parsed.calculator && parsed.calculatorVariant === null
44+
? "scientific"
45+
: parsed.calculatorVariant;
46+
47+
return {...parsed, calculatorVariant};
48+
}),
49+
).parser;

0 commit comments

Comments
 (0)