From 2cdbf1b47407bd54d4a3b7fd9dd5bd928a0c5abf Mon Sep 17 00:00:00 2001 From: Ivan Miskovic Date: Mon, 17 Jun 2024 15:43:09 +1200 Subject: [PATCH 1/2] feat: add editor options and wrapping component prop --- README.md | 29 +++++++++++++++++++++++------ example/src/intro.mdx | 23 +++++++++++++++++++++++ src/Editor/Editor.tsx | 13 +++++++++++-- src/index.tsx | 17 ++++++++++++++--- 4 files changed, 71 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 486c564..3c6f45b 100644 --- a/README.md +++ b/README.md @@ -72,20 +72,37 @@ const config: StorybookConfig = { Use the `Playground` component in [MDX format](https://storybook.js.org/docs/writing-docs/mdx). -```jsx +```mdx // MyComponent.stories.mdx +import { Playground } from 'storybook-addon-code-editor' + + +``` + +
+Example with a wrapping component and modified editor options + +```mdx import { Playground } from 'storybook-addon-code-editor'; - + ( +
{props.children}
+ )} + code="export default () =>

Hello

;" +/> ``` +
+
More advanced example -```jsx +```mdx // MyComponent.stories.mdx import { Playground } from 'storybook-addon-code-editor'; -import * as MyLibrary from './index'; +import \* as MyLibrary from './index'; import storyCode from './MyStory.source.tsx?raw'; // TypeScript might complain about not finding this import or @@ -106,10 +123,10 @@ import MyLibraryTypes from '../dist/types.d.ts?raw'; monaco.editor.setTheme('vs-dark'); monaco.languages.typescript.typescriptDefaults.addExtraLib( MyLibraryTypes, - 'file:///node_modules/my-library/index.d.ts' + 'file:///node_modules/my-library/index.d.ts', ); }} -/>; +/> ```
diff --git a/example/src/intro.mdx b/example/src/intro.mdx index ca5a924..df89819 100644 --- a/example/src/intro.mdx +++ b/example/src/intro.mdx @@ -99,6 +99,29 @@ ${code} --- +{(() => { + const code = `export default () => ( +

+ Wrapped in a custom component with editor options (no minimap) +

+);`; + return ( + (
{props.children}
)} + code={` +/\* MDX: +import { Playground } from 'storybook-addon-code-editor'; + +*/ +${code} + `.trim()} + /> + ); +})()} + +--- + {(() => { const code = ` /\* MDX: diff --git a/src/Editor/Editor.tsx b/src/Editor/Editor.tsx index 7e5091a..5ef9086 100644 --- a/src/Editor/Editor.tsx +++ b/src/Editor/Editor.tsx @@ -7,6 +7,8 @@ import { getMonacoSetup } from './setupMonaco'; let monacoPromise: Promise | undefined; +export type EditorOptions = Monaco.editor.IEditorOptions; + function loadMonacoEditor() { const monacoSetup = getMonacoSetup(); @@ -38,7 +40,12 @@ function loadMonacoEditor() { let fileCount = 1; -function createEditor(monaco: typeof Monaco, code: string, container: HTMLElement) { +function createEditor( + monaco: typeof Monaco, + code: string, + container: HTMLElement, + editorOptions?: EditorOptions, +) { const uri = monaco.Uri.parse(`file:///index${fileCount++}.tsx`); return monaco.editor.create(container, { @@ -47,6 +54,7 @@ function createEditor(monaco: typeof Monaco, code: string, container: HTMLElemen model: monaco.editor.createModel(code, 'typescript', uri), overflowWidgetsDomNode: getMonacoOverflowContainer('monacoOverflowContainer'), tabSize: 2, + ...editorOptions, }); } @@ -55,6 +63,7 @@ interface EditorProps { value: string; modifyEditor?: (monaco: typeof Monaco, editor: Monaco.editor.IStandaloneCodeEditor) => any; parentSize?: string; + editorOptions?: EditorOptions; } interface EditorState { @@ -76,7 +85,7 @@ export default function Editor(props: EditorProps) { Promise.all([containerPromise, loadMonacoEditor()]).then(([editorContainer, monaco]) => { stateRef.monaco = monaco; - stateRef.editor = createEditor(monaco, props.value, editorContainer); + stateRef.editor = createEditor(monaco, props.value, editorContainer, props.editorOptions); stateRef.editor.onDidChangeModelContent(() => { const currentValue = stateRef.editor?.getValue(); diff --git a/src/index.tsx b/src/index.tsx index d4781b3..2c72122 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { createStore } from './createStore'; -import Editor from './Editor/Editor'; +import Editor, { EditorOptions } from './Editor/Editor'; import ErrorBoundary from './ErrorBoundary'; import Preview from './Preview'; export { setupMonaco } from './Editor/setupMonaco'; @@ -9,6 +9,7 @@ export interface StoryState { code: string; availableImports?: Record>; modifyEditor?: React.ComponentProps['modifyEditor']; + editorOptions?: EditorOptions; } const store = createStore(); @@ -80,8 +81,14 @@ export function Playground({ code, height = '200px', id, + wrappingComponent: WrappingComponent, ...editorProps -}: Partial & { height?: string; id?: string }) { +}: Partial & { + height?: string; + id?: string; + wrappingComponent?: React.JSXElementConstructor<{ children: React.ReactNode }>; +}) { + console.log(editorProps); let initialCode = code ?? ''; if (id !== undefined) { savedCode[id] ??= initialCode; @@ -93,11 +100,15 @@ export function Playground({ ? currentCode : "import * as React from 'react';" + currentCode; + const preview = ( + + ); + return (
- + {WrappingComponent ? {preview} : preview}
Date: Mon, 1 Jul 2024 16:42:10 +1200 Subject: [PATCH 2/2] fix: implement pr feedback --- README.md | 4 ++-- example/src/intro.mdx | 16 +++++++++++++--- src/Editor/Editor.tsx | 13 +++++++++---- src/index.tsx | 7 +++---- 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 3c6f45b..cd66652 100644 --- a/README.md +++ b/README.md @@ -86,8 +86,8 @@ import { Playground } from 'storybook-addon-code-editor' import { Playground } from 'storybook-addon-code-editor'; ( + defaultEditorOptions={{ minimap: { enabled: false } }} + WrappingComponent={(props) => (
{props.children}
)} code="export default () =>

Hello

;" diff --git a/example/src/intro.mdx b/example/src/intro.mdx index df89819..64be0b0 100644 --- a/example/src/intro.mdx +++ b/example/src/intro.mdx @@ -105,14 +105,24 @@ ${code} Wrapped in a custom component with editor options (no minimap) );`; + const Wrapper = (props) => ( +
{props.children}
+ ); return ( (
{props.children}
)} + defaultEditorOptions={{minimap: { enabled: false }}} + WrappingComponent={Wrapper} code={` /\* MDX: import { Playground } from 'storybook-addon-code-editor'; - +const Wrapper = (props) => ( +
{props.children}
+); + */ ${code} `.trim()} diff --git a/src/Editor/Editor.tsx b/src/Editor/Editor.tsx index 5ef9086..2f10b16 100644 --- a/src/Editor/Editor.tsx +++ b/src/Editor/Editor.tsx @@ -44,7 +44,7 @@ function createEditor( monaco: typeof Monaco, code: string, container: HTMLElement, - editorOptions?: EditorOptions, + defaultEditorOptions?: EditorOptions, ) { const uri = monaco.Uri.parse(`file:///index${fileCount++}.tsx`); @@ -54,7 +54,7 @@ function createEditor( model: monaco.editor.createModel(code, 'typescript', uri), overflowWidgetsDomNode: getMonacoOverflowContainer('monacoOverflowContainer'), tabSize: 2, - ...editorOptions, + ...defaultEditorOptions, }); } @@ -63,7 +63,7 @@ interface EditorProps { value: string; modifyEditor?: (monaco: typeof Monaco, editor: Monaco.editor.IStandaloneCodeEditor) => any; parentSize?: string; - editorOptions?: EditorOptions; + defaultEditorOptions?: EditorOptions; } interface EditorState { @@ -85,7 +85,12 @@ export default function Editor(props: EditorProps) { Promise.all([containerPromise, loadMonacoEditor()]).then(([editorContainer, monaco]) => { stateRef.monaco = monaco; - stateRef.editor = createEditor(monaco, props.value, editorContainer, props.editorOptions); + stateRef.editor = createEditor( + monaco, + props.value, + editorContainer, + props.defaultEditorOptions, + ); stateRef.editor.onDidChangeModelContent(() => { const currentValue = stateRef.editor?.getValue(); diff --git a/src/index.tsx b/src/index.tsx index 2c72122..cf85e43 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -9,7 +9,7 @@ export interface StoryState { code: string; availableImports?: Record>; modifyEditor?: React.ComponentProps['modifyEditor']; - editorOptions?: EditorOptions; + defaultEditorOptions?: EditorOptions; } const store = createStore(); @@ -81,14 +81,13 @@ export function Playground({ code, height = '200px', id, - wrappingComponent: WrappingComponent, + WrappingComponent: WrappingComponent, ...editorProps }: Partial & { height?: string; id?: string; - wrappingComponent?: React.JSXElementConstructor<{ children: React.ReactNode }>; + WrappingComponent?: React.ComponentType<{ children: React.ReactNode }>; }) { - console.log(editorProps); let initialCode = code ?? ''; if (id !== undefined) { savedCode[id] ??= initialCode;