-
Notifications
You must be signed in to change notification settings - Fork 350
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Storybook: Editor Page] Add a working preview for the editor page in…
… storybook (#1372) ## Summary: The preview iframe doesn't work in storybook, because in links to a local URL to webapp when it's in prod. It has never worked in storybook. We need to be able to see what the initial state of the questions on the editor page would look like without making any changes to the actual preview (yet). I've added a preview here that shows the question and the hints in the editor page. This works for all widgets. It's sticky, so it follows as you scroll down a long editor. You can also close it if it's taking too much space. This is a prerequisite to viewing an interactive graph with initial coordinates. Issue: https://khanacademy.atlassian.net/browse/LEMS-2051 ## Test plan: http://localhost:6006/?path=/story/perseuseditor-editorpage--demo ### Interactive graph widget <img width="1568" alt="Screenshot 2024-06-21 at 2 58 45 PM" src="https://github.com/Khan/perseus/assets/13231763/69dd2c62-05af-4d9f-a279-1575c9adbc33"> ### Expression widget <img width="863" alt="Screenshot 2024-06-21 at 2 58 14 PM" src="https://github.com/Khan/perseus/assets/13231763/3609a064-b226-4a43-bc01-b833269e62b3"> ### Demo video https://github.com/Khan/perseus/assets/13231763/c39db9c4-380d-4e3f-a556-5542198046c8 Author: nishasy Reviewers: benchristel Required Reviewers: Approved By: benchristel Checks: ✅ codecov/project, ✅ codecov/patch, ✅ Upload Coverage (ubuntu-latest, 20.x), ✅ Publish npm snapshot (ubuntu-latest, 20.x), ✅ Check builds for changes in size (ubuntu-latest, 20.x), ✅ Cypress (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), ✅ Check for .changeset entries for all changed files (ubuntu-latest, 20.x), ✅ gerald Pull Request URL: #1372
- Loading branch information
Showing
3 changed files
with
180 additions
and
164 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@khanacademy/perseus-editor": patch | ||
--- | ||
|
||
[Storybook: Editor Page] Add a storybook-only preview for the questions and hints in the EditorPage component |
168 changes: 168 additions & 0 deletions
168
packages/perseus-editor/src/__stories__/editor-page-with-storybook-preview.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
import { | ||
Renderer, | ||
type APIOptions, | ||
type DeviceType, | ||
type Hint, | ||
type PerseusAnswerArea, | ||
type PerseusRenderer, | ||
} from "@khanacademy/perseus"; | ||
import Button from "@khanacademy/wonder-blocks-button"; | ||
import {View} from "@khanacademy/wonder-blocks-core"; | ||
import IconButton from "@khanacademy/wonder-blocks-icon-button"; | ||
import {Strut} from "@khanacademy/wonder-blocks-layout"; | ||
import {color, spacing} from "@khanacademy/wonder-blocks-tokens"; | ||
import {LabelLarge} from "@khanacademy/wonder-blocks-typography"; | ||
import xIcon from "@phosphor-icons/core/regular/x.svg"; | ||
import {action} from "@storybook/addon-actions"; | ||
import {StyleSheet} from "aphrodite"; | ||
import * as React from "react"; | ||
|
||
// eslint-disable-next-line import/no-relative-packages | ||
import {mockStrings} from "../../../perseus/src/strings"; | ||
import EditorPage from "../editor-page"; | ||
|
||
import {flags} from "./flags-for-api-options"; | ||
|
||
type Props = { | ||
apiOptions?: APIOptions; | ||
question?: PerseusRenderer; | ||
hints?: ReadonlyArray<Hint>; | ||
}; | ||
|
||
const onChangeAction = action("onChange"); | ||
|
||
function EditorPageWithStorybookPreview(props: Props) { | ||
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>( | ||
props.question, | ||
); | ||
const [hints, setHints] = React.useState<ReadonlyArray<Hint> | undefined>( | ||
props.hints, | ||
); | ||
|
||
const [panelOpen, setPanelOpen] = React.useState<boolean>(true); | ||
|
||
const apiOptions = props.apiOptions ?? { | ||
isMobile: false, | ||
flags, | ||
}; | ||
|
||
return ( | ||
<View> | ||
<EditorPage | ||
apiOptions={apiOptions} | ||
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); | ||
} | ||
}} | ||
/> | ||
|
||
{/* Button to open panel */} | ||
{!panelOpen && ( | ||
<Button | ||
onClick={() => setPanelOpen(!panelOpen)} | ||
style={styles.openPanelButton} | ||
> | ||
Open preview (storybook only) | ||
</Button> | ||
)} | ||
|
||
{/* Panel to show the question/hint previews */} | ||
{panelOpen && ( | ||
<View style={styles.panel}> | ||
{/* Close button */} | ||
<IconButton | ||
icon={xIcon} | ||
onClick={() => setPanelOpen(!panelOpen)} | ||
style={styles.closeButton} | ||
/> | ||
|
||
<View style={styles.panelInner}> | ||
{/* Question preview */} | ||
<Renderer | ||
strings={mockStrings} | ||
apiOptions={apiOptions} | ||
{...question} | ||
/> | ||
</View> | ||
|
||
{/* Hints preview */} | ||
{hints?.map((hint, index) => ( | ||
<View key={index} style={styles.panelInner}> | ||
<Strut size={spacing.medium_16} /> | ||
<LabelLarge>{`Hint ${index + 1}`}</LabelLarge> | ||
<Renderer | ||
strings={mockStrings} | ||
apiOptions={apiOptions} | ||
{...hint} | ||
/> | ||
</View> | ||
))} | ||
</View> | ||
)} | ||
</View> | ||
); | ||
} | ||
|
||
const styles = StyleSheet.create({ | ||
panel: { | ||
position: "fixed", | ||
right: 0, | ||
height: "90vh", | ||
overflow: "auto", | ||
flex: "none", | ||
backgroundColor: color.fadedBlue16, | ||
padding: spacing.medium_16, | ||
borderRadius: spacing.small_12, | ||
alignItems: "end", | ||
}, | ||
panelInner: { | ||
flex: "none", | ||
backgroundColor: color.white, | ||
borderRadius: spacing.xSmall_8, | ||
marginTop: spacing.medium_16, | ||
width: "100%", | ||
padding: spacing.xSmall_8, | ||
}, | ||
closeButton: { | ||
margin: 0, | ||
}, | ||
openPanelButton: { | ||
position: "fixed", | ||
right: spacing.medium_16, | ||
// Extra space so it doesn't get covered up by storybook's | ||
// "Style warnings" button. | ||
bottom: spacing.xxxLarge_64, | ||
}, | ||
}); | ||
|
||
export default EditorPageWithStorybookPreview; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters