From 97e07c8baee12a37e471e8292dedbcf0588e2f50 Mon Sep 17 00:00:00 2001 From: Tamara <60857422+Myranae@users.noreply.github.com> Date: Fri, 31 Jan 2025 14:28:39 -0600 Subject: [PATCH] Create helper to build public widget options for Numeric Input (#2174) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary: Adds a function that takes a Numeric Input widget's full widget options and removes correct answer information. It also adds the function to the widget's widget export and adds a test confirming the function works as expected. Issue: LEMS-2767 ## Test plan: - Confirm all checks pass - Confirm the Numeric Input widget still acts as expected Author: Myranae Reviewers: Myranae, benchristel, handeyeco, SonicScrewdriver, jeremywiebe Required Reviewers: Approved By: benchristel Checks: ✅ Publish npm snapshot (ubuntu-latest, 20.x), ✅ Lint, Typecheck, Format, and Test (ubuntu-latest, 20.x), ✅ Check builds for changes in size (ubuntu-latest, 20.x), ✅ Check for .changeset entries for all changed files (ubuntu-latest, 20.x), ✅ Cypress (ubuntu-latest, 20.x), ✅ Publish Storybook to Chromatic (ubuntu-latest, 20.x) Pull Request URL: https://github.com/Khan/perseus/pull/2174 --- .changeset/good-cheetahs-drum.md | 6 +++ packages/perseus-core/src/index.ts | 1 + .../numeric-input/numeric-input-util.test.ts | 40 +++++++++++++++++++ .../numeric-input/numeric-input-util.ts | 27 +++++++++++++ packages/perseus/src/types.ts | 2 + .../widgets/numeric-input/numeric-input.tsx | 3 +- 6 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 .changeset/good-cheetahs-drum.md create mode 100644 packages/perseus-core/src/widgets/numeric-input/numeric-input-util.test.ts create mode 100644 packages/perseus-core/src/widgets/numeric-input/numeric-input-util.ts diff --git a/.changeset/good-cheetahs-drum.md b/.changeset/good-cheetahs-drum.md new file mode 100644 index 0000000000..ac9c50b99f --- /dev/null +++ b/.changeset/good-cheetahs-drum.md @@ -0,0 +1,6 @@ +--- +"@khanacademy/perseus": minor +"@khanacademy/perseus-core": minor +--- + +Implement a widget export function to filter out rubric data from widget options for the Numeric Input widget diff --git a/packages/perseus-core/src/index.ts b/packages/perseus-core/src/index.ts index 5d5c449942..1b62efa61a 100644 --- a/packages/perseus-core/src/index.ts +++ b/packages/perseus-core/src/index.ts @@ -120,3 +120,4 @@ export {default as getExpressionPublicWidgetOptions} from "./widgets/expression/ export {default as getLabelImagePublicWidgetOptions} from "./widgets/label-image/label-image-util"; export {default as getSorterPublicWidgetOptions} from "./widgets/sorter/sorter-util"; export {default as getDropdownPublicWidgetOptions} from "./widgets/dropdown/dropdown-util"; +export {default as getNumericInputPublicWidgetOptions} from "./widgets/numeric-input/numeric-input-util"; diff --git a/packages/perseus-core/src/widgets/numeric-input/numeric-input-util.test.ts b/packages/perseus-core/src/widgets/numeric-input/numeric-input-util.test.ts new file mode 100644 index 0000000000..7778972d00 --- /dev/null +++ b/packages/perseus-core/src/widgets/numeric-input/numeric-input-util.test.ts @@ -0,0 +1,40 @@ +import getNumericInputPublicWidgetOptions from "./numeric-input-util"; + +import type {PerseusNumericInputWidgetOptions} from "../../data-schema"; + +describe("getNumericInputPublicWidgetOptions", () => { + it("should return the correct public options without any answer data", () => { + // Arrange + const options: PerseusNumericInputWidgetOptions = { + answers: [ + { + status: "correct", + maxError: null, + strict: false, + value: 1252, + simplify: "required", + message: "", + }, + ], + labelText: "labelText", + size: "Normal", + coefficient: false, + rightAlign: false, + static: false, + answerForms: [{simplify: "required", name: "decimal"}], + }; + + // Act + const publicWidgetOptions = getNumericInputPublicWidgetOptions(options); + + // Assert + expect(publicWidgetOptions).toEqual({ + labelText: "labelText", + size: "Normal", + coefficient: false, + rightAlign: false, + static: false, + answerForms: [{simplify: "required", name: "decimal"}], + }); + }); +}); diff --git a/packages/perseus-core/src/widgets/numeric-input/numeric-input-util.ts b/packages/perseus-core/src/widgets/numeric-input/numeric-input-util.ts new file mode 100644 index 0000000000..115286533b --- /dev/null +++ b/packages/perseus-core/src/widgets/numeric-input/numeric-input-util.ts @@ -0,0 +1,27 @@ +import type {PerseusNumericInputWidgetOptions} from "@khanacademy/perseus-core"; + +/** + * For details on the individual options, see the + * PerseusNumericInputWidgetOptions type + */ +type NumericInputPublicWidgetOptions = { + labelText?: PerseusNumericInputWidgetOptions["labelText"]; + size: PerseusNumericInputWidgetOptions["size"]; + coefficient: PerseusNumericInputWidgetOptions["coefficient"]; + rightAlign?: PerseusNumericInputWidgetOptions["rightAlign"]; + static: PerseusNumericInputWidgetOptions["static"]; + answerForms?: PerseusNumericInputWidgetOptions["answerForms"]; +}; + +/** + * Given a PerseusNumericInputWidgetOptions object, return a new object with only + * the public options that should be exposed to the client. + */ +function getNumericInputPublicWidgetOptions( + options: PerseusNumericInputWidgetOptions, +): NumericInputPublicWidgetOptions { + const {answers: _, ...publicWidgetOptions} = options; + return publicWidgetOptions; +} + +export default getNumericInputPublicWidgetOptions; diff --git a/packages/perseus/src/types.ts b/packages/perseus/src/types.ts index 0f67b78b9a..027a97ba3d 100644 --- a/packages/perseus/src/types.ts +++ b/packages/perseus/src/types.ts @@ -18,6 +18,7 @@ import type { getExpressionPublicWidgetOptions, getSorterPublicWidgetOptions, getDropdownPublicWidgetOptions, + getNumericInputPublicWidgetOptions, } from "@khanacademy/perseus-core"; import type {LinterContextProps} from "@khanacademy/perseus-linter"; import type { @@ -544,6 +545,7 @@ export type WidgetScorerFunction = ( * A union type of all the functions that provide public widget options. */ export type PublicWidgetOptionsFunction = + | typeof getNumericInputPublicWidgetOptions | typeof getDropdownPublicWidgetOptions | typeof getCategorizerPublicWidgetOptions | typeof getOrdererPublicWidgetOptions diff --git a/packages/perseus/src/widgets/numeric-input/numeric-input.tsx b/packages/perseus/src/widgets/numeric-input/numeric-input.tsx index 583a317488..e1057e84e1 100644 --- a/packages/perseus/src/widgets/numeric-input/numeric-input.tsx +++ b/packages/perseus/src/widgets/numeric-input/numeric-input.tsx @@ -1,4 +1,5 @@ import {KhanMath} from "@khanacademy/kmath"; +import {getNumericInputPublicWidgetOptions} from "@khanacademy/perseus-core"; import {linterContextDefault} from "@khanacademy/perseus-linter"; import {scoreNumericInput} from "@khanacademy/perseus-score"; import {StyleSheet} from "aphrodite"; @@ -379,7 +380,7 @@ export default { // TODO(LEMS-2656): remove TS suppression // @ts-expect-error: Type 'UserInput' is not assignable to type 'PerseusNumericInputUserInput'. scorer: scoreNumericInput, - + getPublicWidgetOptions: getNumericInputPublicWidgetOptions, // TODO(LEMS-2656): remove TS suppression // @ts-expect-error: Type 'Rubric' is not assignable to type 'PerseusNumericInputRubric' getOneCorrectAnswerFromRubric(