diff --git a/.changeset/swift-apricots-double.md b/.changeset/swift-apricots-double.md new file mode 100644 index 000000000..a845151cc --- /dev/null +++ b/.changeset/swift-apricots-double.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/packages/wonder-blocks-modal/src/components/__docs__/modal-dialog.stories.js b/packages/wonder-blocks-modal/src/components/__docs__/modal-dialog.stories.js new file mode 100644 index 000000000..66bb7631c --- /dev/null +++ b/packages/wonder-blocks-modal/src/components/__docs__/modal-dialog.stories.js @@ -0,0 +1,287 @@ +// @flow +import * as React from "react"; +import {StyleSheet} from "aphrodite"; + +import Button from "@khanacademy/wonder-blocks-button"; +import Color from "@khanacademy/wonder-blocks-color"; +import {View} from "@khanacademy/wonder-blocks-core"; +import {Strut} from "@khanacademy/wonder-blocks-layout"; +import { + ModalLauncher, + ModalDialog, + ModalPanel, +} from "@khanacademy/wonder-blocks-modal"; +import Spacing from "@khanacademy/wonder-blocks-spacing"; +import {Body, Title} from "@khanacademy/wonder-blocks-typography"; + +import type {StoryComponentType} from "@storybook/react"; + +import ComponentInfo from "../../../../../.storybook/components/component-info.js"; +import {name, version} from "../../../package.json"; + +const customViewports = { + phone: { + name: "phone", + styles: { + width: "320px", + height: "568px", + }, + }, + tablet: { + name: "tablet", + styles: { + width: "640px", + height: "960px", + }, + }, + desktop: { + name: "desktop", + styles: { + width: "1024px", + height: "768px", + }, + }, +}; + +export default { + title: "Modal/Building Blocks/ModalDialog", + component: ModalDialog, + parameters: { + componentSubtitle: (( + + ): any), + viewport: { + viewports: customViewports, + defaultViewport: "desktop", + }, + chromatic: { + viewports: [320, 640, 1024], + }, + }, + // Make the following props null in the control panel + // because setting an object for a React node is + // not practical to do manually. + argTypes: { + children: { + control: {type: null}, + }, + above: { + control: {type: null}, + }, + below: { + control: {type: null}, + }, + }, +}; + +export const Default: StoryComponentType = (args) => ( + + + + + Modal Title + + Here is some text in the modal. + + } + /> + + + +); + +Default.args = { + style: { + maxWidth: 500, + maxHeight: 500, + }, +}; + +export const Simple: StoryComponentType = () => ( + + + + + Modal Title + + Here is some text in the modal. + + } + /> + + + +); + +Simple.parameters = { + docs: { + storyDescription: `This is a basic \`\` that wraps a + \`\` element. The \`\` is just a a wrapper + for the visual components of the overall modal. It sets + the modal's role to \`"dialog"\`. If it did not have another + element as a child here (a \`\` in this case), + nothing would be visible. If the \`\` were not given + a \`maxHeight\` or \`maxWidth\` style, it would take up the + entire viewport. To demonstrate the difference between + the \`\` and the \`\` elements, the panel + has been given a smaller height and width than \`\`, + and \`\` has been given a dark blue background.`, + }, +}; + +export const WithAboveAndBelow: StoryComponentType = () => { + const aboveStyle = { + background: "url(./modal-above.png)", + width: 874, + height: 551, + position: "absolute", + top: 40, + left: -140, + }; + + const belowStyle = { + background: "url(./modal-below.png)", + width: 868, + height: 521, + position: "absolute", + top: -100, + left: -300, + }; + + return ( + + + } + below={} + > + + Modal Title + + Here is some text in the modal. + + } + /> + + + + ); +}; + +WithAboveAndBelow.parameters = { + docs: { + storyDescription: `The \`above\` and \`below\` props work the same + for \`\` as they do for \`\`. + The element passed into the \`above\` prop is rendered in front + of the modal. The element passed into the \`below\` prop is + rendered behind the modal. In this example, a \`\` element + with a background image of a person and an orange blob is passed + into the \`below\` prop. A \`\` element with a background + image of an arc and a blue semicircle is passed into the \`above\` + prop. This results in the person's head and the orange blob + peeking out from behind the modal, and the arc and semicircle + going over the front of the modal.`, + }, +}; + +export const WithLauncher: StoryComponentType = () => { + type MyModalProps = {| + closeModal: () => void, + |}; + + const MyModal = ({ + closeModal, + }: MyModalProps): React.Element => ( + + + Modal Title + + Here is some text in the modal. + + } + /> + + ); + + return ( + + {({openModal}) => ( + + )} + + ); +}; + +WithLauncher.parameters = { + chromatic: { + // Don't take screenshots of this story since it would only show a + // button and not the actual modal. + disableSnapshot: true, + }, + docs: { + storyDescription: `A modal can be launched using a launcher. Here, + the launcher is a \`