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(