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

[Interactive Graph] View a locked polygon #1353

Merged
merged 8 commits into from
Jun 17, 2024
6 changes: 6 additions & 0 deletions .changeset/metal-apricots-brake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@khanacademy/perseus": minor
"@khanacademy/perseus-editor": minor
---

[Interactive Graph] View a locked polygon
26 changes: 21 additions & 5 deletions packages/perseus-editor/src/components/__tests__/util.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@ describe("getDefaultFigureForType", () => {
});
});

test("should return a vector with default values", () => {
const figure = getDefaultFigureForType("vector");
expect(figure).toEqual({
type: "vector",
points: [
[0, 0],
[2, 2],
],
color: "grayH",
});
});

test("should return an ellipse with default values", () => {
const figure = getDefaultFigureForType("ellipse");
expect(figure).toEqual({
Expand All @@ -50,15 +62,19 @@ describe("getDefaultFigureForType", () => {
});
});

test("should return a vector with default values", () => {
const figure = getDefaultFigureForType("vector");
test("should return a polygon with default values", () => {
const figure = getDefaultFigureForType("polygon");
expect(figure).toEqual({
type: "vector",
type: "polygon",
points: [
[0, 0],
[2, 2],
[0, 2],
[-1, 0],
[1, 0],
],
color: "grayH",
showVertices: false,
fillStyle: "none",
strokeStyle: "solid",
});
});
});
Expand Down
11 changes: 4 additions & 7 deletions packages/perseus-editor/src/components/ellipse-swatch.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
import {
lockedFigureColors,
lockedEllipseFillStyles,
} from "@khanacademy/perseus";
import {lockedFigureColors, lockedFigureFillStyles} from "@khanacademy/perseus";
import {View} from "@khanacademy/wonder-blocks-core";
import {color as wbColor, spacing} from "@khanacademy/wonder-blocks-tokens";
import {StyleSheet} from "aphrodite";
import * as React from "react";

import type {
LockedFigureColor,
LockedEllipseFillType,
LockedFigureFillType,
} from "@khanacademy/perseus";

type Props = {
color: LockedFigureColor;
fillStyle: LockedEllipseFillType;
fillStyle: LockedFigureFillType;
strokeStyle: "solid" | "dashed";
};

Expand All @@ -36,7 +33,7 @@ const EllipseSwatch = (props: Props) => {
styles.innerCircle,
{
backgroundColor: lockedFigureColors[color],
opacity: lockedEllipseFillStyles[fillStyle],
opacity: lockedFigureFillStyles[fillStyle],
},
]}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {components, lockedEllipseFillStyles} from "@khanacademy/perseus";
import {components, lockedFigureFillStyles} from "@khanacademy/perseus";
import {View} from "@khanacademy/wonder-blocks-core";
import {OptionItem, SingleSelect} from "@khanacademy/wonder-blocks-dropdown";
import {Strut} from "@khanacademy/wonder-blocks-layout";
Expand All @@ -17,7 +17,7 @@ import LockedFigureSettingsActions from "./locked-figure-settings-actions";
import type {AccordionProps} from "./locked-figure-settings";
import type {
Coord,
LockedEllipseFillType,
LockedFigureFillType,
LockedEllipseType,
LockedFigureColor,
} from "@khanacademy/perseus";
Expand Down Expand Up @@ -118,13 +118,13 @@ const LockedEllipseSettings = (props: Props) => {
<Strut size={spacing.xxSmall_6} />
<SingleSelect
selectedValue={fillStyle}
onChange={(value: LockedEllipseFillType) =>
onChange={(value: LockedFigureFillType) =>
onChangeProps({fillStyle: value})
}
// Placeholder is required, but never gets used.
placeholder=""
>
{Object.keys(lockedEllipseFillStyles).map((option) => (
{Object.keys(lockedFigureFillStyles).map((option) => (
<OptionItem
key={option}
value={option}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,13 @@
return (
<View>
{figures?.map((figure, index) => {
if (figure.type === "polygon") {
// TODO(LEMS-1943): Implement locked polygon settings.
// Remove this block once locked polygon settings are
// implemented.
return;
}

Check warning on line 104 in packages/perseus-editor/src/components/locked-figures-section.tsx

View check run for this annotation

Codecov / codecov/patch

packages/perseus-editor/src/components/locked-figures-section.tsx#L100-L104

Added lines #L100 - L104 were not covered by tests

return (
<LockedFigureSettings
key={`${uniqueId}-locked-${figure}-${index}`}
Expand Down
25 changes: 20 additions & 5 deletions packages/perseus-editor/src/components/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
LockedLineType,
LockedEllipseType,
LockedVectorType,
LockedPolygonType,
} from "@khanacademy/perseus";

export function focusWithChromeStickyFocusBugWorkaround(element: Element) {
Expand Down Expand Up @@ -52,8 +53,9 @@

export function getDefaultFigureForType(type: "point"): LockedPointType;
export function getDefaultFigureForType(type: "line"): LockedLineType;
export function getDefaultFigureForType(type: "ellipse"): LockedEllipseType;
export function getDefaultFigureForType(type: "vector"): LockedVectorType;
export function getDefaultFigureForType(type: "ellipse"): LockedEllipseType;
export function getDefaultFigureForType(type: "polygon"): LockedPolygonType;
export function getDefaultFigureForType(type: LockedFigureType): LockedFigure;
export function getDefaultFigureForType(type: LockedFigureType): LockedFigure {
switch (type) {
Expand All @@ -80,6 +82,15 @@
showPoint1: false,
showPoint2: false,
};
case "vector":
return {
type: "vector",
points: [
[0, 0],
[2, 2],
],
color: DEFAULT_COLOR,
};
case "ellipse":
return {
type: "ellipse",
Expand All @@ -90,14 +101,18 @@
fillStyle: "none",
strokeStyle: "solid",
};
case "vector":
case "polygon":
return {
type: "vector",
type: "polygon",

Check warning on line 106 in packages/perseus-editor/src/components/util.ts

View check run for this annotation

Codecov / codecov/patch

packages/perseus-editor/src/components/util.ts#L106

Added line #L106 was not covered by tests
points: [
[0, 0],
[2, 2],
[0, 2],
[-1, 0],
[1, 0],

Check warning on line 110 in packages/perseus-editor/src/components/util.ts

View check run for this annotation

Codecov / codecov/patch

packages/perseus-editor/src/components/util.ts#L108-L110

Added lines #L108 - L110 were not covered by tests
],
color: DEFAULT_COLOR,
showVertices: false,
fillStyle: "none",
strokeStyle: "solid",

Check warning on line 115 in packages/perseus-editor/src/components/util.ts

View check run for this annotation

Codecov / codecov/patch

packages/perseus-editor/src/components/util.ts#L113-L115

Added lines #L113 - L115 were not covered by tests
};
default:
throw new UnreachableCaseError(type);
Expand Down
7 changes: 4 additions & 3 deletions packages/perseus/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export {
plotterPlotTypes,
ItemExtras,
lockedFigureColors,
lockedEllipseFillStyles,
lockedFigureFillStyles,
} from "./perseus-types";
export {traverse} from "./traversal";
export {isItemRenderableByVersion} from "./renderability";
Expand Down Expand Up @@ -160,12 +160,13 @@ export type {ParsedValue} from "./util";
export type {
LockedFigure,
LockedFigureColor,
LockedFigureFillType,
LockedFigureType,
LockedPointType,
LockedLineType,
LockedEllipseType,
LockedEllipseFillType,
LockedVectorType,
LockedEllipseType,
LockedPolygonType,
PerseusGraphType,
PerseusAnswerArea,
PerseusExpressionWidgetOptions,
Expand Down
24 changes: 17 additions & 7 deletions packages/perseus/src/perseus-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -677,8 +677,9 @@ export const lockedFigureColors: Record<LockedFigureColor, string> = {
export type LockedFigure =
| LockedPointType
| LockedLineType
| LockedVectorType
| LockedEllipseType
| LockedVectorType;
| LockedPolygonType;
export type LockedFigureType = LockedFigure["type"];

export type LockedPointType = {
Expand All @@ -698,8 +699,14 @@ export type LockedLineType = {
showPoint2: boolean;
};

export type LockedEllipseFillType = "none" | "solid" | "translucent";
export const lockedEllipseFillStyles: Record<LockedEllipseFillType, number> = {
export type LockedVectorType = {
type: "vector";
points: [tail: Coord, tip: Coord];
color: LockedFigureColor;
};

export type LockedFigureFillType = "none" | "solid" | "translucent";
export const lockedFigureFillStyles: Record<LockedFigureFillType, number> = {
none: 0,
solid: 1,
translucent: 0.4,
Expand All @@ -711,14 +718,17 @@ export type LockedEllipseType = {
radius: [x: number, y: number];
angle: number;
color: LockedFigureColor;
fillStyle: LockedEllipseFillType;
fillStyle: LockedFigureFillType;
strokeStyle: "solid" | "dashed";
};

export type LockedVectorType = {
type: "vector";
points: [tail: Coord, tip: Coord];
export type LockedPolygonType = {
type: "polygon";
points: ReadonlyArray<Coord>;
color: LockedFigureColor;
showVertices: boolean;
fillStyle: LockedFigureFillType;
strokeStyle: "solid" | "dashed";
};

export type PerseusGraphType =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
sinusoidQuestion,
segmentWithLockedEllipses,
segmentWithLockedVectors,
segmentWithLockedPolygons,
} from "../__testdata__/interactive-graph.testdata";

export default {
Expand Down Expand Up @@ -117,15 +118,22 @@ export const AllLockedRays = (args: StoryArgs): React.ReactElement => (
/>
);

export const LockedVector = (args: StoryArgs): React.ReactElement => (
<RendererWithDebugUI {...mafsOptions} question={segmentWithLockedVectors} />
);

export const LockedEllipse = (args: StoryArgs): React.ReactElement => (
<RendererWithDebugUI
{...mafsOptions}
question={segmentWithLockedEllipses}
/>
);

export const LockedVector = (args: StoryArgs): React.ReactElement => (
<RendererWithDebugUI {...mafsOptions} question={segmentWithLockedVectors} />
export const LockedPolygon = (args: StoryArgs): React.ReactElement => (
<RendererWithDebugUI
{...mafsOptions}
question={segmentWithLockedPolygons}
/>
);

export const Sinusoid = (args: StoryArgs): React.ReactElement => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2089,6 +2089,12 @@ export const segmentWithAllLockedRayVariations: PerseusRenderer = {
},
};

export const segmentWithLockedVectors: PerseusRenderer =
interactiveGraphQuestionBuilder()
.addLockedVector([0, 0], [2, 2])
.addLockedVector([2, 2], [-2, 4], "green")
.build();

export const segmentWithLockedEllipses: PerseusRenderer =
interactiveGraphQuestionBuilder()
.addLockedEllipse([0, 0], [5, 5])
Expand All @@ -2106,10 +2112,42 @@ export const segmentWithLockedEllipses: PerseusRenderer =
})
.build();

export const segmentWithLockedVectors: PerseusRenderer =
export const segmentWithLockedPolygons: PerseusRenderer =
interactiveGraphQuestionBuilder()
.addLockedVector([0, 0], [2, 2])
.addLockedVector([2, 2], [-2, 4], "green")
.addLockedPolygon([
[-3, 4],
[-5, 1],
[-1, 1],
])
.addLockedPolygon(
[
[1, 4],
[4, 4],
[4, 1],
[1, 1],
],
{
color: "green",
showVertices: true,
fillStyle: "translucent",
strokeStyle: "dashed",
},
)
.addLockedPolygon(
[
[0, -1],
[-2, -3],
[-1, -5],
[1, -5],
[2, -3],
],
{
color: "purple",
showVertices: false,
fillStyle: "solid",
strokeStyle: "solid",
},
)
.build();

export const segmentWithLockedFigures: PerseusRenderer =
Expand Down
Loading