Skip to content

Commit

Permalink
Update spacing in locked figure settings (#1231)
Browse files Browse the repository at this point in the history
## Summary:
Update spacing in the Locked Point Settings and Locked Line Settings
accordions so that the settings fit better.

PR includes
- spacing updates
- lowercase letters to save space
- checkboxes changed to switches (based on this [UX guidance](https://blog.uxtweak.com/checkbox-vs-toggle-switch/))
- LabeledSwitch component to remove redundancy
- LockedFiguresSection stories

Issue: https://khanacademy.atlassian.net/browse/LEMS-1965

## Test plan:
`yarn jest`

http://localhost:6006/?path=/story/perseus-editor-components-locked-figures-section--with-prod-width

### Screenshots

Note: the font styles are ever so slightly off, probably because of global styles in prod vs dev

| Before | After ("solid") | After ("dashed") |
| --- | --- | --- |
| ![Screenshot 2024-04-26 at 4 54 42 PM](https://github.com/Khan/perseus/assets/13231763/21403be0-dc63-426d-96b6-a70f56dbf13e) | ![Screenshot 2024-04-26 at 4 53 35 PM](https://github.com/Khan/perseus/assets/13231763/cc1ac547-4546-4af9-9004-3ac619f676c6) | ![Screenshot 2024-04-26 at 5 06 21 PM](https://github.com/Khan/perseus/assets/13231763/83b8875f-930e-4b1a-aed2-58d6036dcb8e) |

Author: nishasy

Reviewers: jeremywiebe, mark-fitzgerald

Required Reviewers:

Approved By: jeremywiebe

Checks: ✅ codecov/project, ✅ codecov/patch, ✅ Upload Coverage, ✅ Publish npm snapshot (ubuntu-latest, 20.x), ✅ Cypress (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), ✅ Jest Coverage (ubuntu-latest, 20.x), ✅ Lint, Typecheck, Format, and Test (ubuntu-latest, 20.x), ✅ Publish Storybook to Chromatic (ubuntu-latest, 20.x), ✅ gerald

Pull Request URL: #1231
  • Loading branch information
nishasy committed May 6, 2024
1 parent f757db5 commit 4fae015
Show file tree
Hide file tree
Showing 13 changed files with 377 additions and 124 deletions.
6 changes: 6 additions & 0 deletions .changeset/honest-pens-count.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@khanacademy/perseus": patch
"@khanacademy/perseus-editor": patch
---

Adjust spacing in locked point and locked line settings
49 changes: 49 additions & 0 deletions packages/perseus-editor/src/__stories__/editor-page.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {action} from "@storybook/addon-actions";
import * as React from "react";

import {EditorPage} from "..";
import {segmentWithLockedFigures} from "../../../perseus/src/widgets/__testdata__/interactive-graph.testdata";
import {registerAllWidgetsAndEditorsForTesting} from "../util/register-all-widgets-and-editors-for-testing";

import {flags} from "./flags-for-api-options";
Expand Down Expand Up @@ -68,3 +69,51 @@ export const Demo = (): React.ReactElement => {
/>
);
};

export const MafsWithLockedFigures = (): React.ReactElement => {
const [previewDevice, setPreviewDevice] =
React.useState<DeviceType>("phone");
const [jsonMode, setJsonMode] = React.useState<boolean | undefined>(false);
const [answerArea, setAnswerArea] = React.useState<
PerseusAnswerArea | undefined | null
>();
const [question, setQuestion] = React.useState<PerseusRenderer | undefined>(
segmentWithLockedFigures,
);
const [hints, setHints] = React.useState<ReadonlyArray<Hint> | undefined>();

return (
<EditorPage
apiOptions={{
isMobile: false,
flags,
}}
previewDevice={previewDevice}
onPreviewDeviceChange={(newDevice) => setPreviewDevice(newDevice)}
developerMode={true}
jsonMode={jsonMode}
answerArea={answerArea}
question={question}
hints={hints}
frameSource="about:blank"
previewURL="about:blank"
itemId="1"
onChange={(props) => {
onChangeAction(props);

if ("jsonMode" in props) {
setJsonMode(props.jsonMode);
}
if ("answerArea" in props) {
setAnswerArea(props.answerArea);
}
if ("question" in props) {
setQuestion(props.question);
}
if ("hints" in props) {
setHints(props.hints);
}
}}
/>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import {View} from "@khanacademy/wonder-blocks-core";
import {color, spacing} from "@khanacademy/wonder-blocks-tokens";
import {StyleSheet} from "aphrodite";
import * as React from "react";

import LockedFiguresSection from "../locked-figures-section";
import {getDefaultFigureForType} from "../util";

import type {Meta, StoryObj} from "@storybook/react";

export default {
title: "PerseusEditor/Components/Locked Figures Section",
component: LockedFiguresSection,
} as Meta<typeof LockedFiguresSection>;

export const Default = (args): React.ReactElement => {
return <LockedFiguresSection {...args} />;
};

type StoryComponentType = StoryObj<typeof LockedFiguresSection>;

// Set the default values in the control panel.
Default.args = {};

export const Controlled: StoryComponentType = {
render: function Render() {
const [figures, setFigures] = React.useState([]);

const handlePropsUpdate = (newProps) => {
setFigures(newProps.lockedFigures);
};

return (
<LockedFiguresSection
figures={figures}
onChange={handlePropsUpdate}
/>
);
},
};

export const WithProdWidth: StoryComponentType = {
render: function Render() {
const [figures, setFigures] = React.useState([
getDefaultFigureForType("point"),
getDefaultFigureForType("line"),
]);

const handlePropsUpdate = (newProps) => {
setFigures(newProps.lockedFigures);
};

return (
<View style={styles.prodSizeContainer}>
<LockedFiguresSection
figures={figures}
onChange={handlePropsUpdate}
/>
</View>
);
},
};

const contentSize = 310;
const padding = 10;
// Padding on each side
const containerSize = contentSize + 2 * padding;

const styles = StyleSheet.create({
prodSizeContainer: {
width: containerSize,
padding: padding,
marginInlineStart: spacing.medium_16,
border: `1px solid ${color.offBlack32}`,
borderRadius: spacing.xxxSmall_4,
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ describe("LockedPointSettings", () => {
{wrapper: RenderStateRoot},
);

const toggleSwitch = screen.getByLabelText("Show point on graph");
const toggleSwitch = screen.getByLabelText("show point on graph");

// Assert
expect(toggleSwitch).toBeInTheDocument();
Expand All @@ -82,7 +82,7 @@ describe("LockedPointSettings", () => {
{wrapper: RenderStateRoot},
);

const toggleSwitch = screen.getByLabelText("Show point on graph");
const toggleSwitch = screen.getByLabelText("show point on graph");

// Assert
expect(toggleSwitch).toBeChecked();
Expand All @@ -102,7 +102,7 @@ describe("LockedPointSettings", () => {
{wrapper: RenderStateRoot},
);

const toggleSwitch = screen.getByLabelText("Show point on graph");
const toggleSwitch = screen.getByLabelText("show point on graph");

// Assert
expect(toggleSwitch).not.toBeChecked();
Expand All @@ -122,8 +122,8 @@ describe("LockedPointSettings", () => {
{wrapper: RenderStateRoot},
);

const colorSelect = screen.getByLabelText("Color");
const openCheckbox = screen.getByLabelText("Open point");
const colorSelect = screen.getByLabelText("color");
const openCheckbox = screen.getByLabelText("open point");

// Assert
expect(colorSelect).toBeInTheDocument();
Expand Down
10 changes: 6 additions & 4 deletions packages/perseus-editor/src/components/color-select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,25 @@ import * as React from "react";
import ColorSwatch from "./color-swatch";

import type {LockedFigureColor} from "@khanacademy/perseus";
import type {StyleType} from "@khanacademy/wonder-blocks-core";

const possibleColors = Object.keys(lockedFigureColors) as LockedFigureColor[];

type Props = {
// Required ID so that the label can be associated with the select.
id: string;
selectedValue: LockedFigureColor;
style?: StyleType;
onChange: (newValue: string) => void;
};

const ColorSelect = (props: Props) => {
const {id, selectedValue, onChange} = props;
const {id, selectedValue, style, onChange} = props;

return (
<View style={styles.row}>
<View style={[styles.row, style]}>
<LabelMedium htmlFor={id} style={styles.label} tag="label">
Color
color
</LabelMedium>
<SingleSelect
id={id}
Expand Down Expand Up @@ -57,7 +59,7 @@ const styles = StyleSheet.create({
alignItems: "center",
},
label: {
marginInlineEnd: spacing.xSmall_8,
marginInlineEnd: spacing.xxxSmall_4,
},
});

Expand Down
42 changes: 42 additions & 0 deletions packages/perseus-editor/src/components/labeled-switch.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import {View, useUniqueIdWithMock} from "@khanacademy/wonder-blocks-core";
import {Strut} from "@khanacademy/wonder-blocks-layout";
import Switch from "@khanacademy/wonder-blocks-switch";
import {spacing} from "@khanacademy/wonder-blocks-tokens";
import {LabelMedium} from "@khanacademy/wonder-blocks-typography";
import {StyleSheet} from "aphrodite";
import * as React from "react";

import type {StyleType} from "@khanacademy/wonder-blocks-core";

type Props = {
label: string;
checked: boolean;
style?: StyleType;
onChange: (newValue: boolean) => void;
};

const LabeledSwitch = (props: Props) => {
const {checked, label, style, onChange} = props;

const ids = useUniqueIdWithMock();
const switchId = ids.get("switch");

return (
<View style={[styles.row, style]}>
<Switch id={switchId} checked={checked} onChange={onChange} />
<Strut size={spacing.xSmall_8} />
<LabelMedium tag="label" htmlFor={switchId}>
{label}
</LabelMedium>
</View>
);
};

const styles = StyleSheet.create({
row: {
flexDirection: "row",
alignItems: "center",
},
});

export default LabeledSwitch;
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const LockedFigureSelect = (props: Props) => {

const styles = StyleSheet.create({
container: {
marginTop: spacing.xxxSmall_4,
marginTop: spacing.xSmall_8,
},
addElementSelect: {
backgroundColor: color.fadedBlue8,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const styles = StyleSheet.create({
width: "100%",
flexDirection: "row",
alignItems: "center",
marginTop: spacing.xxxSmall_4,
},
deleteButton: {
// Line up the delete icon with the rest of the content.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
* the dropdown for adding figures as well as the settings for each figure.
*/
import {View, useUniqueIdWithMock} from "@khanacademy/wonder-blocks-core";
import {spacing} from "@khanacademy/wonder-blocks-tokens";
import {StyleSheet} from "aphrodite";
import * as React from "react";

import LockedFigureSelect from "./locked-figure-select";
Expand Down Expand Up @@ -69,7 +67,7 @@ const LockedFiguresSection = (props: Props) => {
}

return (
<View style={styles.container}>
<View>
{figures?.map((figure, index) => (
<LockedFigureSettings
key={`${uniqueId}-locked-${figure}-${index}`}
Expand All @@ -86,10 +84,4 @@ const LockedFiguresSection = (props: Props) => {
);
};

const styles = StyleSheet.create({
container: {
paddingTop: spacing.large_24,
},
});

export default LockedFiguresSection;

0 comments on commit 4fae015

Please sign in to comment.