From 2c7d13d6adfd27e440cce2ed81d055ec5012dad5 Mon Sep 17 00:00:00 2001 From: Poff Poffenberger Date: Tue, 3 Mar 2020 12:22:11 -0600 Subject: [PATCH] Add storybook for Code Editor (#58900) * Add storybook for code editor component * Add dark mode story * Update code editor README with storybook instructions Co-authored-by: Elastic Machine --- src/dev/storybook/aliases.ts | 1 + .../kibana_react/public/code_editor/README.md | 7 +- .../code_editor/code_editor.examples.tsx | 235 ++++++++++++++++++ .../public/code_editor/scripts/storybook.ts | 26 ++ 4 files changed, 267 insertions(+), 2 deletions(-) create mode 100644 src/plugins/kibana_react/public/code_editor/code_editor.examples.tsx create mode 100644 src/plugins/kibana_react/public/code_editor/scripts/storybook.ts diff --git a/src/dev/storybook/aliases.ts b/src/dev/storybook/aliases.ts index fb91b865097fa..35ac4e27f9c8b 100644 --- a/src/dev/storybook/aliases.ts +++ b/src/dev/storybook/aliases.ts @@ -20,6 +20,7 @@ export const storybookAliases = { apm: 'x-pack/legacy/plugins/apm/scripts/storybook.js', canvas: 'x-pack/legacy/plugins/canvas/scripts/storybook_new.js', + codeeditor: 'src/plugins/kibana_react/public/code_editor/scripts/storybook.ts', drilldowns: 'x-pack/plugins/drilldowns/scripts/storybook.js', embeddable: 'src/plugins/embeddable/scripts/storybook.js', infra: 'x-pack/legacy/plugins/infra/scripts/storybook.js', diff --git a/src/plugins/kibana_react/public/code_editor/README.md b/src/plugins/kibana_react/public/code_editor/README.md index 887a9c9990915..811038b58c828 100644 --- a/src/plugins/kibana_react/public/code_editor/README.md +++ b/src/plugins/kibana_react/public/code_editor/README.md @@ -8,6 +8,9 @@ This editor component allows easy access to: * Function signature widget * [Hover widget](https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-hover-provider-example) -[_TODO: Examples of each_](https://github.com/elastic/kibana/issues/43812) +The Monaco editor doesn't automatically resize the editor area on window or container resize so this component includes a [resize detector](https://github.com/maslianok/react-resize-detector) to cause the Monaco editor to re-layout and adjust its size when the window or container size changes -The Monaco editor doesn't automatically resize the editor area on window or container resize so this component includes a [resize detector](https://github.com/maslianok/react-resize-detector) to cause the Monaco editor to re-layout and adjust its size when the window or container size changes \ No newline at end of file +## Storybook Examples +To run the CodeEditor storybook, from the root kibana directory, run `yarn storybook codeeditor` + +All stories for the component live in `code_editor.examples.tsx` \ No newline at end of file diff --git a/src/plugins/kibana_react/public/code_editor/code_editor.examples.tsx b/src/plugins/kibana_react/public/code_editor/code_editor.examples.tsx new file mode 100644 index 0000000000000..b6d5f2c5460f6 --- /dev/null +++ b/src/plugins/kibana_react/public/code_editor/code_editor.examples.tsx @@ -0,0 +1,235 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { action } from '@storybook/addon-actions'; +import { storiesOf } from '@storybook/react'; +import React from 'react'; +import { monaco as monacoEditor } from '@kbn/ui-shared-deps/monaco'; +import { CodeEditor } from './code_editor'; + +// A sample language definition with a few example tokens +// Taken from https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-custom-languages +const simpleLogLang: monacoEditor.languages.IMonarchLanguage = { + tokenizer: { + root: [ + [/\[error.*/, 'constant'], + [/\[notice.*/, 'variable'], + [/\[info.*/, 'string'], + [/\[[a-zA-Z 0-9:]+\]/, 'tag'], + ], + }, +}; + +monacoEditor.languages.register({ id: 'loglang' }); +monacoEditor.languages.setMonarchTokensProvider('loglang', simpleLogLang); + +const logs = `[Sun Mar 7 20:54:27 2004] [notice] [client xx.xx.xx.xx] This is a notice! +[Sun Mar 7 20:58:27 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed +[Sun Mar 7 21:16:17 2004] [error] [client xx.xx.xx.xx] File does not exist: /home/httpd/twiki/view/Main/WebHome +`; + +storiesOf('CodeEditor', module) + .addParameters({ + info: { + // CodeEditor has no PropTypes set so this table will show up + // as blank. I'm just disabling it to reduce confusion + propTablesExclude: [CodeEditor], + }, + }) + .add( + 'default', + () => ( +
+ +
+ ), + { + info: { + text: 'Plaintext Monaco Editor', + }, + } + ) + .add( + 'dark mode', + () => ( +
+ +
+ ), + { + info: { + text: 'The dark theme is automatically used when dark mode is enabled in Kibana', + }, + } + ) + .add( + 'custom log language', + () => ( +
+ +
+ ), + { + info: { + text: + 'Custom language example. Language definition taken from [here](https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-custom-languages)', + }, + } + ) + .add( + 'hide minimap', + () => ( +
+ +
+ ), + { + info: { + text: 'The minimap (on left side of editor) can be disabled to save space', + }, + } + ) + .add( + 'suggestion provider', + () => { + const provideSuggestions = ( + model: monacoEditor.editor.ITextModel, + position: monacoEditor.Position, + context: monacoEditor.languages.CompletionContext + ) => { + const wordRange = new monacoEditor.Range( + position.lineNumber, + position.column, + position.lineNumber, + position.column + ); + + return { + suggestions: [ + { + label: 'Hello, World', + kind: monacoEditor.languages.CompletionItemKind.Variable, + documentation: { + value: '*Markdown* can be used in autocomplete help', + isTrusted: true, + }, + insertText: 'Hello, World', + range: wordRange, + }, + { + label: 'You know, for search', + kind: monacoEditor.languages.CompletionItemKind.Variable, + documentation: { value: 'Thanks `Monaco`', isTrusted: true }, + insertText: 'You know, for search', + range: wordRange, + }, + ], + }; + }; + + return ( +
+ +
+ ); + }, + { + info: { + text: 'Example suggestion provider is triggered by the `.` character', + }, + } + ) + .add( + 'hover provider', + () => { + const provideHover = ( + model: monacoEditor.editor.ITextModel, + position: monacoEditor.Position + ) => { + const word = model.getWordAtPosition(position); + + if (!word) { + return { + contents: [], + }; + } + + return { + contents: [ + { + value: `You're hovering over **${word.word}**`, + }, + ], + }; + }; + + return ( +
+ +
+ ); + }, + { + info: { + text: 'Hover dialog example can be triggered by hovering over a word', + }, + } + ); diff --git a/src/plugins/kibana_react/public/code_editor/scripts/storybook.ts b/src/plugins/kibana_react/public/code_editor/scripts/storybook.ts new file mode 100644 index 0000000000000..4fe7286987397 --- /dev/null +++ b/src/plugins/kibana_react/public/code_editor/scripts/storybook.ts @@ -0,0 +1,26 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { join } from 'path'; + +// eslint-disable-next-line +require('@kbn/storybook').runStorybookCli({ + name: 'code-editor', + storyGlobs: [join(__dirname, '..', '*.examples.tsx')], +});