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

docs: add edit mode for stories in docs page #2043

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion packages/core/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,11 @@ module.exports = {
}
},
{
files: ["*.stories.@(js|jsx|ts|tsx)", "*.stories.helpers.@(js|jsx|ts|tsx)"],
files: [
"*.stories.@(js|jsx|ts|tsx)",
"*.stories.helpers.@(js|jsx|ts|tsx)",
"src/storybook/decorators/**/with*.{js,jsx,ts,tsx}"
],
rules: {
...commonRules,
"react-hooks/rules-of-hooks": "off",
Expand Down
19 changes: 12 additions & 7 deletions packages/core/.storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@ import {
MultipleStoryElementsWrapper,
StorybookLink
} from "vibe-storybook-components";
import CanvasWrapper from "../src/storybook/components/canvas-wrapper/CanvasWrapper";
import withGlobalStyle from "../src/storybook/decorators/withGlobalStyle/withGlobalStyle";
import { ComponentNameDecorator, PropsTable, RelatedComponentsDecorator } from "../src/storybook";
import "monday-ui-style/dist/index.min.css";
import "vibe-storybook-components/dist/index.css";
import introCode from "../src/storybook/stand-alone-documentaion/playground/playground-helpers";
import withLiveEdit from "../src/storybook/decorators/withLiveEdit/withLiveEdit";

const fontLoader = async () => ({
fonts: await document.fonts.ready // Fixing Chromatic tests flakiness - taking snapshots after fonts are loaded
Expand All @@ -43,6 +46,12 @@ const preview: Preview = {
sort: "alpha"
},
docs: {
liveEdit: {
isEnabled: true
},
canvas: {
layout: "fullscreen"
},
container: ({ children, context }: { children: any; context: any }) => (
<DocsContainer context={context}>
<Unstyled>
Expand All @@ -53,6 +62,7 @@ const preview: Preview = {
),
page: DocsPage,
components: {
Canvas: CanvasWrapper,
Controls: PropsTable,
PropsTable,
h1: ComponentNameDecorator,
Expand Down Expand Up @@ -105,13 +115,8 @@ const preview: Preview = {
}
},
decorators: [
(Story, { className }: { className: string }) => {
return (
<MultipleStoryElementsWrapper className={className}>
<Story />
</MultipleStoryElementsWrapper>
);
},
withLiveEdit,
withGlobalStyle,
withMemoryStats,
// Should always be the last decorator (stories hooks issues otherwise) - bug in the addon
withThemeByClassName({
Expand Down
4 changes: 4 additions & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,9 @@
"@types/react-window": "^1.8.5",
"@typescript-eslint/eslint-plugin": "^5.36.1",
"@typescript-eslint/parser": "^5.36.1",
"@uiw/codemirror-extensions-langs": "^4.21.25",
"@uiw/codemirror-theme-vscode": "^4.21.25",
"@uiw/react-codemirror": "^4.21.25",
"acorn": "^8.7.1",
"autoprefixer": "^10.4.0",
"babel-core": "^6.26.3",
Expand Down Expand Up @@ -229,6 +232,7 @@
"prettier": "^2.5.1",
"react": "^16.14.0",
"react-dom": "^16.14.0",
"react-live": "^4.1.5",
"react-markdown": "^7.1.0",
"react-resizable": "^3.0.4",
"react-test-renderer": "^16.14.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Canvas, Meta } from "@storybook/blocks";
import { Meta } from "@storybook/blocks";
import { Link, UsageGuidelines } from "vibe-storybook-components";
import SplitButton from "../SplitButton";
import Button from "../../Button/Button";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ export const Overview = {
<MenuItem icon={Announcement} title="There" />
</SplitButtonMenu>
)
},
parameters: {
docs: {
liveEdit: { isEnabled: false }
}
}
};

Expand Down Expand Up @@ -89,7 +94,13 @@ export const Types = {
</>
),

name: "Types"
name: "Types",

parameters: {
docs: {
liveEdit: { scope: { Check, Announcement } }
}
}
};

export const Sizes = {
Expand Down Expand Up @@ -128,7 +139,12 @@ export const Sizes = {
</>
),

name: "Sizes"
name: "Sizes",
parameters: {
docs: {
liveEdit: { scope: { Check, Announcement } }
}
}
};

export const SplitButtonWithIcons = {
Expand Down Expand Up @@ -159,7 +175,12 @@ export const SplitButtonWithIcons = {
</>
),

name: "Split button with icons"
name: "Split button with icons",
parameters: {
docs: {
liveEdit: { scope: { Add, Check, Announcement } }
}
}
};

export const SplitButtonAsThePrimaryAction = {
Expand All @@ -176,7 +197,12 @@ export const SplitButtonAsThePrimaryAction = {
/>
),

name: "Split button as the primary action"
name: "Split button as the primary action",
parameters: {
docs: {
liveEdit: { scope: { Download, Upload } }
}
}
};

export const SecondarySplitButton = {
Expand Down Expand Up @@ -217,5 +243,10 @@ export const CustomMenu = {
</SplitButton>
),

name: "Custom menu"
name: "Custom menu",
parameters: {
docs: {
liveEdit: { scope: { Sun, Moon, Favorite } }
}
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
.editorContainer {
position: relative;
top: -40px;
width: 100%;
background: transparent;
max-height: 0;
opacity: 0;
transition: max-height 0.1s ease-out, opacity 0.1s ease-out;
overflow: auto;
border-radius: 0 0 4px 4px;
box-shadow: rgba(0, 0, 0, 0.1) 0 1px 3px 0;
border: 1px solid hsla(203, 50%, 30%, 0.15);
border-top: none;

&[data-editor-open="true"] {
max-height: 500px;
opacity: 1;
}

& :global(.cm-editor) {
padding: var(--sb-spacing-medium);
}
}

.canvas:has(+ [data-editor-open="true"]) {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Canvas, useOf } from "@storybook/blocks";
import { ComponentProps, FC, useMemo, useState } from "react";
import styles from "./CanvasWrapper.module.scss";

type CanvasWrapper = ComponentProps<typeof Canvas>;

const CanvasWrapper: FC<CanvasWrapper> = ({ of }) => {
const [open, setOpen] = useState<boolean>(false);

// resolve Storybook story module to get the story id and parameters of current rendered story
const { story } = useOf(of, ["story"]);

const toggleCodeAction = useMemo(
() => ({
title: "Toggle code editor",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: call it "Play"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just like that? Play?
It opens and shut the live editor, not sure about Play

onClick: () => setOpen(prev => !prev)
}),
[]
);

const liveEditEnabledForStory = story.parameters.docs?.liveEdit?.isEnabled;

return (
<>
<Canvas
of={of}
sourceState={liveEditEnabledForStory ? "none" : "hidden"}
additionalActions={liveEditEnabledForStory ? [toggleCodeAction] : []}
className={styles.canvas}
/>
{liveEditEnabledForStory && <div id={story.id} className={styles.editorContainer} data-editor-open={open} />}
</>
);
};

export default CanvasWrapper;
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React, { forwardRef } from "react";
import CodeMirror, { Extension, ReactCodeMirrorRef, BasicSetupOptions } from "@uiw/react-codemirror";

interface EditorProps {
code: string;
onChange: (newVal: string) => void;
placeholder?: string;
loading?: boolean;
theme?: "light" | "dark" | Extension;
style?: React.CSSProperties;
extensions?: Extension[];
setup?: BasicSetupOptions;
}

type EditorComponent = React.ForwardRefExoticComponent<EditorProps & React.RefAttributes<ReactCodeMirrorRef>>;

const LiveEditor: EditorComponent = forwardRef(
({ code, onChange, placeholder, theme = "light", style, extensions, setup }, ref) => {
return (
<CodeMirror
style={style}
ref={ref}
theme={theme}
value={code}
extensions={extensions}
onChange={onChange}
placeholder={placeholder}
basicSetup={setup}
/>
);
}
);

export default LiveEditor;
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from "react";
import { withLive } from "react-live";

interface LivePreview {
live?: {
// live injects more, currently unneeded, props
error?: string;
element?: React.ComponentType;
};
}

const LivePreview: React.FC<LivePreview> = ({ live = {} }) => {
const { error, element: Element } = live;
return <>{error ?? (Element && <Element />)}</>;
};
export default withLive(LivePreview);
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.storyWrapper {
padding: var(--spacing-xl) var(--spacing-large);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { MultipleStoryElementsWrapper } from "vibe-storybook-components";
import cx from "classnames";
import styles from "./withGlobalStyle.module.scss";
import { Decorator } from "@storybook/react";

const WithGlobalStyle: Decorator = (Story, { className, viewMode }) => {
return (
<MultipleStoryElementsWrapper className={cx({ [styles.storyWrapper]: viewMode === "docs" }, className)}>
<Story />
</MultipleStoryElementsWrapper>
);
};

export default WithGlobalStyle;
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { format, Options } from "prettier";
import parserHtml from "prettier/parser-html";
import parserTypeScript from "prettier/parser-typescript";

export function formatCode(code: string): string {
const options: Options = {
parser: "typescript",
arrowParens: "avoid",
trailingComma: "es5",
plugins: [parserHtml, parserTypeScript]
};
try {
return format(code, options).replace(/;\s*$/, "");
} catch (e) {
throw new Error(`[LiveEdit Error]: Error formatting code: ${e}`);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.modifiedVersionIndicator {
position: absolute;
top: 0;
left: calc(50% - var(--sb-spacing-large));
margin: 0;
border-radius: 0 0 4px 4px;
background: var(--sb-primary-color);
color: var(--sb-text-color-on-primary);
padding: var(--sb-spacing-xs);
font-size: 10px;
pointer-events: none;
user-select: none;
}
Loading