Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create helper to build public widget options for Numeric Input #2174

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

Myranae
Copy link
Contributor

@Myranae Myranae commented Jan 30, 2025

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

@Myranae Myranae self-assigned this Jan 30, 2025
Copy link
Contributor

npm Snapshot: Published

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

Example:

yarn add @khanacademy/perseus@PR2174

If you are working in Khan Academy's webapp, you can run:

./dev/tools/bump_perseus_version.sh -t PR2174

Copy link
Contributor

Size Change: +70 B (0%)

Total Size: 1.48 MB

Filename Size Change
packages/perseus-core/dist/es/index.js 43.5 kB +51 B (+0.12%)
packages/perseus/dist/es/index.js 382 kB +19 B (0%)
ℹ️ View Unchanged
Filename Size
packages/kas/dist/es/index.js 39 kB
packages/keypad-context/dist/es/index.js 760 B
packages/kmath/dist/es/index.js 86.8 kB
packages/math-input/dist/es/index.js 77.6 kB
packages/math-input/dist/es/strings.js 1.79 kB
packages/perseus-editor/dist/es/index.js 688 kB
packages/perseus-linter/dist/es/index.js 22.2 kB
packages/perseus-score/dist/es/index.js 113 kB
packages/perseus/dist/es/strings.js 5.82 kB
packages/pure-markdown/dist/es/index.js 3.66 kB
packages/simple-markdown/dist/es/index.js 12.5 kB

compressed-size-action

@Myranae Myranae marked this pull request as ready for review January 30, 2025 16:03
@Myranae Myranae requested review from jeremywiebe, handeyeco and benchristel and removed request for jeremywiebe and handeyeco January 30, 2025 16:03
@@ -544,6 +545,7 @@ export type WidgetScorerFunction = (
* A union type of all the functions that provide public widget options.
*/
export type PublicWidgetOptionsFunction =
| typeof getNumericInputPublicWidgetOptions
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this file the best place for this union? It is used to type the getPublicWidgetOptionsFunction in the widgets.ts file, which was created to be the function used in the editor to access the correct getPublicWidgetOptions function.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fine!

Comment on lines +22 to +23
const {answers: _, answerForms: __, ...publicWidgetOptions} = options;
return publicWidgetOptions;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason this would be preferable or not preferable to building out the specific object we're looking for like I was doing previously? ex. {size: options.size, static: options.static, etc.}

I could see this being less brittle as it makes it easier to add fields to the widgetOptions and have them be automatically included. If this is preferable, should I go through and update the functions that do this the previous way?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it matters too much one way or the other. The tests ensure that we include the correct fields either way.

I guess one way of approaching it might be to ask, "when we add fields to the widget options, are they more likely to be public or private?" If the code is written the way you have it here, we won't need to change it when adding public options, but we will need to change it when adding private options. On the other hand, if we explicitly list the public fields, we won't need to change this code when adding private options, but we will need to change it when adding public options.

Then there's the question of what's easier to read. The current approach has the advantage of being short, but it might be a bit obscure.

Ultimately, it's a judgment call, and a two-way door, so we can just pick an approach and, worst case, change it later.

Comment on lines +7 to +12
type NumericInputPublicWidgetOptions = {
labelText?: PerseusNumericInputWidgetOptions["labelText"];
size: PerseusNumericInputWidgetOptions["size"];
coefficient: PerseusNumericInputWidgetOptions["coefficient"];
rightAlign?: PerseusNumericInputWidgetOptions["rightAlign"];
static: PerseusNumericInputWidgetOptions["static"];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left out both answers and answerForms as they both appear to contain information related to the correct answer. 'answerForms` even has a note that it's supposedly used in examples, but might not even be used anymore.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think answerForms should actually be considered public information. See e.g. the examples() method on NumericInput, which apparently generates learner-facing instructions based on the answerForms that are accepted.

Copy link
Member

@benchristel benchristel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes because I think we want to include answerForms in the public data, since it is used to display instructions to the learner. Other than that, this looks good!

Comment on lines +7 to +12
type NumericInputPublicWidgetOptions = {
labelText?: PerseusNumericInputWidgetOptions["labelText"];
size: PerseusNumericInputWidgetOptions["size"];
coefficient: PerseusNumericInputWidgetOptions["coefficient"];
rightAlign?: PerseusNumericInputWidgetOptions["rightAlign"];
static: PerseusNumericInputWidgetOptions["static"];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think answerForms should actually be considered public information. See e.g. the examples() method on NumericInput, which apparently generates learner-facing instructions based on the answerForms that are accepted.

Comment on lines +22 to +23
const {answers: _, answerForms: __, ...publicWidgetOptions} = options;
return publicWidgetOptions;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it matters too much one way or the other. The tests ensure that we include the correct fields either way.

I guess one way of approaching it might be to ask, "when we add fields to the widget options, are they more likely to be public or private?" If the code is written the way you have it here, we won't need to change it when adding public options, but we will need to change it when adding private options. On the other hand, if we explicitly list the public fields, we won't need to change this code when adding private options, but we will need to change it when adding public options.

Then there's the question of what's easier to read. The current approach has the advantage of being short, but it might be a bit obscure.

Ultimately, it's a judgment call, and a two-way door, so we can just pick an approach and, worst case, change it later.

@@ -544,6 +545,7 @@ export type WidgetScorerFunction = (
* A union type of all the functions that provide public widget options.
*/
export type PublicWidgetOptionsFunction =
| typeof getNumericInputPublicWidgetOptions
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fine!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants