diff --git a/packages/perseus-editor/src/widgets/__stories__/label-image-editor.stories.tsx b/packages/perseus-editor/src/widgets/__stories__/label-image-editor.stories.tsx index 6b9126988b..01d9311ea0 100644 --- a/packages/perseus-editor/src/widgets/__stories__/label-image-editor.stories.tsx +++ b/packages/perseus-editor/src/widgets/__stories__/label-image-editor.stories.tsx @@ -4,7 +4,10 @@ import * as React from "react"; import LabelImageEditor from "../label-image-editor"; -import type {MarkerAnswers} from "@khanacademy/perseus"; +import type { + LabelImageMarker, + LabelImageMarkerScoringData, +} from "@khanacademy/perseus"; type StoryArgs = Record; @@ -29,7 +32,7 @@ type State = { imageUrl: string; imageWidth: number; imageHeight: number; - markers: ReadonlyArray; + markers: ReadonlyArray; }; class WithState extends React.Component { diff --git a/packages/perseus-editor/src/widgets/label-image-editor.tsx b/packages/perseus-editor/src/widgets/label-image-editor.tsx index ff05ac8330..b4368467dc 100644 --- a/packages/perseus-editor/src/widgets/label-image-editor.tsx +++ b/packages/perseus-editor/src/widgets/label-image-editor.tsx @@ -17,7 +17,10 @@ import Behavior from "./label-image/behavior"; import QuestionMarkers from "./label-image/question-markers"; import SelectImage from "./label-image/select-image"; -import type {MarkerAnswers} from "@khanacademy/perseus"; +import type { + LabelImageMarker, + LabelImageMarkerScoringData, +} from "@khanacademy/perseus"; type Props = { // List of answer choices to label question image with. @@ -28,7 +31,7 @@ type Props = { imageWidth: number; imageHeight: number; // The list of label markers on the question image. - markers: ReadonlyArray; + markers: ReadonlyArray; // Whether multiple answer choices may be selected for markers. multipleAnswers: boolean; // Whether to hide answer choices from user instructions. @@ -176,8 +179,10 @@ class LabelImageEditor extends React.Component { this.props.onChange({choices}); }; - handleMarkersChange: (markers: ReadonlyArray) => void = ( - markers: ReadonlyArray, + handleMarkersChange: ( + markers: ReadonlyArray, + ) => void = ( + markers: ReadonlyArray, ) => { this.props.onChange({markers}); }; diff --git a/packages/perseus-editor/src/widgets/label-image/__stories__/question-markers.stories.tsx b/packages/perseus-editor/src/widgets/label-image/__stories__/question-markers.stories.tsx index 6faa86a0f1..1faacb5c42 100644 --- a/packages/perseus-editor/src/widgets/label-image/__stories__/question-markers.stories.tsx +++ b/packages/perseus-editor/src/widgets/label-image/__stories__/question-markers.stories.tsx @@ -3,7 +3,10 @@ import * as React from "react"; import QuestionMarkers from "../question-markers"; -import type {MarkerAnswers} from "@khanacademy/perseus"; +import type { + LabelImageMarker, + LabelImageMarkerScoringData, +} from "@khanacademy/perseus"; type StoryArgs = Record; @@ -31,7 +34,7 @@ const Wrapper = (props) => ( class WithState extends React.Component< Record, { - markers: ReadonlyArray; + markers: ReadonlyArray; } > { state = { diff --git a/packages/perseus-editor/src/widgets/label-image/marker.tsx b/packages/perseus-editor/src/widgets/label-image/marker.tsx index ff3cdb9548..bdd4aaf7c2 100644 --- a/packages/perseus-editor/src/widgets/label-image/marker.tsx +++ b/packages/perseus-editor/src/widgets/label-image/marker.tsx @@ -14,16 +14,22 @@ import Option, {OptionGroup} from "../../components/dropdown-option"; import FormWrappedTextField from "../../components/form-wrapped-text-field"; import {gray17, gray85, gray98} from "../../styles/global-colors"; -import type {MarkerAnswers} from "@khanacademy/perseus"; - -type Props = MarkerAnswers & { - // The list of possible answer choices. - choices: ReadonlyArray; - // Callback for when any of the marker props are changed. - onChange: (marker: MarkerAnswers) => void; - // Callback to remove marker from the question image. - onRemove: () => void; -}; +import type { + LabelImageMarker, + LabelImageMarkerScoringData, +} from "@khanacademy/perseus"; + +type Props = LabelImageMarker & + LabelImageMarkerScoringData & { + // The list of possible answer choices. + choices: ReadonlyArray; + // Callback for when any of the marker props are changed. + onChange: ( + marker: LabelImageMarker & LabelImageMarkerScoringData, + ) => void; + // Callback to remove marker from the question image. + onRemove: () => void; + }; type State = { // Whether answer choices dropdown is shown, controlled by the user clicking diff --git a/packages/perseus-editor/src/widgets/label-image/question-markers.tsx b/packages/perseus-editor/src/widgets/label-image/question-markers.tsx index 6c6d6a36b6..6be507662c 100644 --- a/packages/perseus-editor/src/widgets/label-image/question-markers.tsx +++ b/packages/perseus-editor/src/widgets/label-image/question-markers.tsx @@ -3,7 +3,13 @@ * label image with answers from list of choices. */ -import {Util, Dependencies, bodyXsmallBold} from "@khanacademy/perseus"; +import { + Util, + Dependencies, + bodyXsmallBold, + type LabelImageMarker, + type LabelImageMarkerScoringData, +} from "@khanacademy/perseus"; import {StyleSheet, css} from "aphrodite"; import * as React from "react"; @@ -11,8 +17,6 @@ import {gray17, gray68} from "../../styles/global-colors"; import Marker from "./marker"; -import type {MarkerAnswers} from "@khanacademy/perseus"; - type Props = { // The list of possible answers in a specific order. choices: ReadonlyArray; @@ -21,9 +25,11 @@ type Props = { imageWidth: number; imageHeight: number; // The list of markers placed on the question image. - markers: ReadonlyArray; + markers: ReadonlyArray; // Callback for when any of markers change. - onChange: (markers: ReadonlyArray) => void; + onChange: ( + markers: ReadonlyArray, + ) => void; }; export default class QuestionMarkers extends React.Component { diff --git a/packages/perseus/src/index.ts b/packages/perseus/src/index.ts index 581a482f0d..fc38f32d01 100644 --- a/packages/perseus/src/index.ts +++ b/packages/perseus/src/index.ts @@ -234,7 +234,10 @@ export type { } from "./perseus-types"; export type {UserInputMap} from "./validation.types"; export type {Coord} from "./interactive2/types"; -export type {MarkerAnswers} from "./widgets/label-image/types"; +export type { + LabelImageMarker, + LabelImageMarkerScoringData, +} from "./widgets/label-image/types"; /** * Multi-items diff --git a/packages/perseus/src/perseus-types.ts b/packages/perseus/src/perseus-types.ts index 02ea0c8cf4..01f719e893 100644 --- a/packages/perseus/src/perseus-types.ts +++ b/packages/perseus/src/perseus-types.ts @@ -2,7 +2,10 @@ // TODO(FEI-4011): Use types generated by https://github.com/jaredly/generate-perseus-flowtypes import type {Coord} from "./interactive2/types"; -import type {MarkerAnswers} from "./widgets/label-image/types"; +import type { + LabelImageMarker, + LabelImageMarkerScoringData, +} from "./widgets/label-image/types"; import type {Interval, vec} from "mafs"; // Range is replaced within this file with Interval, but it is used elsewhere @@ -1051,7 +1054,7 @@ export type PerseusLabelImageWidgetOptions = { // The width of the image imageWidth: number; // A list of markers to display on the image - markers: ReadonlyArray; + markers: ReadonlyArray; // Do not display answer choices in instructions hideChoicesFromInstructions: boolean; // Allow multiple answers per marker diff --git a/packages/perseus/src/validation.types.ts b/packages/perseus/src/validation.types.ts index cfaf6f6242..32f8f36861 100644 --- a/packages/perseus/src/validation.types.ts +++ b/packages/perseus/src/validation.types.ts @@ -44,8 +44,9 @@ import type { PerseusGraphCorrectType, } from "./perseus-types"; import type { - InteractiveMarkerType, - MarkerAnswers, + LabelImageMarker, + LabelImageMarkerScoringData, + LabelImageMarkerUserInput, } from "./widgets/label-image/types"; import type {Relationship} from "./widgets/number-line/number-line"; @@ -142,11 +143,11 @@ export type PerseusInteractiveGraphRubric = { export type PerseusInteractiveGraphUserInput = PerseusGraphType; export type PerseusLabelImageScoringData = { - markers: ReadonlyArray; + markers: ReadonlyArray; }; export type PerseusLabelImageUserInput = { - markers: ReadonlyArray>; + markers: ReadonlyArray; }; export type PerseusMatcherRubric = PerseusMatcherWidgetOptions; diff --git a/packages/perseus/src/widgets/label-image/label-image.tsx b/packages/perseus/src/widgets/label-image/label-image.tsx index 8e395e13ed..f284fd986c 100644 --- a/packages/perseus/src/widgets/label-image/label-image.tsx +++ b/packages/perseus/src/widgets/label-image/label-image.tsx @@ -27,7 +27,7 @@ import {HideAnswersToggle} from "./hide-answers-toggle"; import Marker from "./marker"; import scoreLabelImage, {scoreMarker} from "./score-label-image"; -import type {InteractiveMarkerType} from "./types"; +import type {LabelImageFullMarker} from "./types"; import type {DependencyProps} from "../../dependencies"; import type {ChangeableProps} from "../../mixins/changeable"; import type {PerseusLabelImageWidgetOptions} from "../../perseus-types"; @@ -75,7 +75,7 @@ type LabelImageProps = ChangeableProps & Omit & { apiOptions: APIOptions; // The list of label markers on the question image. - markers: ReadonlyArray; + markers: ReadonlyArray; // Whether the question has been answered by the user. questionCompleted: boolean; // preferred placement for popover (preference, not MUST) diff --git a/packages/perseus/src/widgets/label-image/marker.tsx b/packages/perseus/src/widgets/label-image/marker.tsx index 79d4089e9f..53eae30d5f 100644 --- a/packages/perseus/src/widgets/label-image/marker.tsx +++ b/packages/perseus/src/widgets/label-image/marker.tsx @@ -16,12 +16,12 @@ import {iconCheck, iconChevronDown, iconMinus} from "../../icon-paths"; import {AnswerPill} from "./answer-pill"; -import type {InteractiveMarkerType} from "./types"; +import type {LabelImageFullMarker} from "./types"; import type {IconType} from "../../components/icon"; import type {AnalyticsEventHandlerFn} from "@khanacademy/perseus-core"; import type {CSSProperties} from "aphrodite"; -type Props = InteractiveMarkerType & { +type Props = LabelImageFullMarker & { // Whether this marker has been selected by user. showSelected: boolean; // Whether this marker should pulsate to draw user attention. diff --git a/packages/perseus/src/widgets/label-image/score-label-image.ts b/packages/perseus/src/widgets/label-image/score-label-image.ts index 7ef4199e05..49a678d48d 100644 --- a/packages/perseus/src/widgets/label-image/score-label-image.ts +++ b/packages/perseus/src/widgets/label-image/score-label-image.ts @@ -1,4 +1,4 @@ -import type {InteractiveMarkerType} from "./types"; +import type {LabelImageFullMarker} from "./types"; import type {PerseusScore} from "../../types"; import type { PerseusLabelImageScoringData, @@ -14,7 +14,7 @@ type InteractiveMarkerScore = { }; export function scoreMarker( - marker: InteractiveMarkerType, + marker: LabelImageFullMarker, ): InteractiveMarkerScore { const score = { hasAnswers: false, diff --git a/packages/perseus/src/widgets/label-image/types.ts b/packages/perseus/src/widgets/label-image/types.ts index 30c14a4648..548e5ffdbe 100644 --- a/packages/perseus/src/widgets/label-image/types.ts +++ b/packages/perseus/src/widgets/label-image/types.ts @@ -1,7 +1,7 @@ -// Base marker, with the props that are set by the editor. -export type MarkerAnswers = { - // The list of correct answers expected for the marker. Often only one but can have multiple - answers: ReadonlyArray; +export type LabelImageMarker = { + // Reveal the correctness state of the user selected answers for the marker. + showCorrectness?: "correct" | "incorrect"; + focused?: boolean; // Translatable Text; The text to show for the marker. Not displayed directly to the user label: string; // The marker coordinates on the question image as percent of image size. @@ -9,13 +9,17 @@ export type MarkerAnswers = { y: number; }; -export type MarkerUserInput = { +export type LabelImageMarkerScoringData = { + // The list of correct answers expected for the marker. Often only one but can have multiple + answers: ReadonlyArray; +}; + +export type LabelImageMarkerUserInput = { // The user selected list of answers, used to grade the question. selected?: ReadonlyArray; - // Reveal the correctness state of the user selected answers for the marker. - showCorrectness?: "correct" | "incorrect"; - focused?: boolean; }; // Additional props that are set when user interacts with the marker. -export type InteractiveMarkerType = MarkerAnswers & MarkerUserInput; +export type LabelImageFullMarker = LabelImageMarker & + LabelImageMarkerScoringData & + LabelImageMarkerUserInput;