From 49a2a5c51f7beb33935bcde84f5b4d5fbe438e5e Mon Sep 17 00:00:00 2001 From: tokarchyn Date: Mon, 1 Mar 2021 19:13:43 +0100 Subject: [PATCH 1/3] docs(v2): Add configuration parameter to allow putting Result before Editor in @docusaurus/theme-live-codeblock --- .../package.json | 1 + .../src/__tests__/validateThemeConfig.test.js | 71 +++++++++++++++++ .../src/index.js | 9 ++- .../src/theme/Playground/index.js | 79 +++++++++++++------ .../src/theme/Playground/styles.module.css | 9 +-- .../src/validateThemeConfig.js | 28 +++++++ .../markdown-features-code-blocks.mdx | 21 +++++ 7 files changed, 185 insertions(+), 33 deletions(-) create mode 100644 packages/docusaurus-theme-live-codeblock/src/__tests__/validateThemeConfig.test.js create mode 100644 packages/docusaurus-theme-live-codeblock/src/validateThemeConfig.js diff --git a/packages/docusaurus-theme-live-codeblock/package.json b/packages/docusaurus-theme-live-codeblock/package.json index ca0447d68d6f..797512dc7e2a 100644 --- a/packages/docusaurus-theme-live-codeblock/package.json +++ b/packages/docusaurus-theme-live-codeblock/package.json @@ -16,6 +16,7 @@ "@docusaurus/core": "2.0.0-alpha.70", "@philpl/buble": "^0.19.7", "clsx": "^1.1.1", + "joi": "^17.4.0", "parse-numeric-range": "^1.2.0", "prism-react-renderer": "^1.1.1", "react-live": "^2.2.3" diff --git a/packages/docusaurus-theme-live-codeblock/src/__tests__/validateThemeConfig.test.js b/packages/docusaurus-theme-live-codeblock/src/__tests__/validateThemeConfig.test.js new file mode 100644 index 000000000000..6824f9c31ac0 --- /dev/null +++ b/packages/docusaurus-theme-live-codeblock/src/__tests__/validateThemeConfig.test.js @@ -0,0 +1,71 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +const {validateThemeConfig, DEFAULT_CONFIG} = require('../validateThemeConfig'); + +function testValidateThemeConfig(themeConfig) { + function validate(schema, cfg) { + const {value, error} = schema.validate(cfg, { + convert: false, + }); + if (error) { + throw error; + } + return value; + } + + return validateThemeConfig({validate, themeConfig}); +} + +describe('validateThemeConfig', () => { + test('minimal config', () => { + const liveCodeblock = { + showResultBeforeEditor: true, + }; + expect(testValidateThemeConfig({liveCodeblock})).toEqual({ + liveCodeblock: { + ...DEFAULT_CONFIG, + ...liveCodeblock, + }, + }); + }); + + test('undefined config 1', () => { + const liveCodeblock = undefined; + expect(testValidateThemeConfig({liveCodeblock})).toEqual({ + liveCodeblock: { + ...DEFAULT_CONFIG, + }, + }); + }); + + test('unexist config', () => { + expect(testValidateThemeConfig({})).toEqual({ + liveCodeblock: { + ...DEFAULT_CONFIG, + }, + }); + }); + + test('empty config', () => { + const liveCodeblock = {}; + expect(testValidateThemeConfig({liveCodeblock})).toEqual({ + liveCodeblock: { + ...DEFAULT_CONFIG, + }, + }); + }); + + test('showResultBeforeEditor not a boolean', () => { + const liveCodeblock = {showResultBeforeEditor: 'invalid'}; + expect(() => + testValidateThemeConfig({liveCodeblock}), + ).toThrowErrorMatchingInlineSnapshot( + `"\\"liveCodeblock.showResultBeforeEditor\\" must be a boolean"`, + ); + }); +}); diff --git a/packages/docusaurus-theme-live-codeblock/src/index.js b/packages/docusaurus-theme-live-codeblock/src/index.js index d222af3d252a..052e75d0a0cd 100644 --- a/packages/docusaurus-theme-live-codeblock/src/index.js +++ b/packages/docusaurus-theme-live-codeblock/src/index.js @@ -6,8 +6,9 @@ */ const path = require('path'); +const {validateThemeConfig} = require('./validateThemeConfig'); -module.exports = function () { +function theme() { return { name: 'docusaurus-theme-live-codeblock', @@ -25,4 +26,8 @@ module.exports = function () { }; }, }; -}; +} + +module.exports = theme; + +theme.validateThemeConfig = validateThemeConfig; diff --git a/packages/docusaurus-theme-live-codeblock/src/theme/Playground/index.js b/packages/docusaurus-theme-live-codeblock/src/theme/Playground/index.js index 16f4eb3a9704..16fb61b0728d 100644 --- a/packages/docusaurus-theme-live-codeblock/src/theme/Playground/index.js +++ b/packages/docusaurus-theme-live-codeblock/src/theme/Playground/index.js @@ -9,43 +9,72 @@ import * as React from 'react'; import {LiveProvider, LiveEditor, LiveError, LivePreview} from 'react-live'; import clsx from 'clsx'; import Translate from '@docusaurus/Translate'; - +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import styles from './styles.module.css'; export default function Playground({children, theme, transformCode, ...props}) { + const { + siteConfig: { + themeConfig: {liveCodeblock: {showResultBeforeEditor} = {}}, + } = {}, + } = useDocusaurusContext(); + return ( `${code};`)} theme={theme} {...props}> -
- - Live Editor - -
- -
- - Result - -
+ {showResultBeforeEditor ? ( + <> + + + + ) : ( + <> + + + + )} +
+ ); +} + +function ResultWithHeader() { + return ( + <> +
- + + ); +} + +function EditorWithHeader() { + return ( + <> +
+ + + ); +} + +function Header({translateId, description, text}) { + return ( +
+ + {text} + +
); } diff --git a/packages/docusaurus-theme-live-codeblock/src/theme/Playground/styles.module.css b/packages/docusaurus-theme-live-codeblock/src/theme/Playground/styles.module.css index 50dc7f6553e6..0a96888c8011 100644 --- a/packages/docusaurus-theme-live-codeblock/src/theme/Playground/styles.module.css +++ b/packages/docusaurus-theme-live-codeblock/src/theme/Playground/styles.module.css @@ -10,18 +10,15 @@ padding: 0.75rem; text-transform: uppercase; font-weight: bold; + background: var(--ifm-color-emphasis-200); + color: var(--ifm-color-content); } -.playgroundEditorHeader { +.playgroundHeader:first-of-type { background: var(--ifm-color-emphasis-600); color: var(--ifm-color-content-inverse); } -.playgroundPreviewHeader { - background: var(--ifm-color-emphasis-200); - color: var(--ifm-color-content); -} - .playgroundEditor { font-family: var(--ifm-font-family-monospace) !important; /*rtl:ignore*/ diff --git a/packages/docusaurus-theme-live-codeblock/src/validateThemeConfig.js b/packages/docusaurus-theme-live-codeblock/src/validateThemeConfig.js new file mode 100644 index 000000000000..35720356a57f --- /dev/null +++ b/packages/docusaurus-theme-live-codeblock/src/validateThemeConfig.js @@ -0,0 +1,28 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +const Joi = require('joi'); + +const DEFAULT_CONFIG = { + showResultBeforeEditor: false, +}; +exports.DEFAULT_CONFIG = DEFAULT_CONFIG; + +const Schema = Joi.object({ + liveCodeblock: Joi.object({ + showResultBeforeEditor: Joi.boolean().default( + DEFAULT_CONFIG.showResultBeforeEditor, + ), + }) + .label('themeConfig.liveCodeblock') + .default(DEFAULT_CONFIG), +}); +exports.Schema = Schema; + +exports.validateThemeConfig = function ({validate, themeConfig}) { + return validate(Schema, themeConfig); +}; diff --git a/website/docs/guides/markdown-features/markdown-features-code-blocks.mdx b/website/docs/guides/markdown-features/markdown-features-code-blocks.mdx index 724f9dc98931..e0f90c7d83db 100644 --- a/website/docs/guides/markdown-features/markdown-features-code-blocks.mdx +++ b/website/docs/guides/markdown-features/markdown-features-code-blocks.mdx @@ -292,6 +292,8 @@ function Clock(props) { } ``` +### Imports + :::caution react-live and imports It is not possible to import components directly from the react-live code editor, you have to define available imports upfront. @@ -343,6 +345,25 @@ function MyPlayground(props) { } ``` +### Configuration + +You can also configurate `@docusaurus/theme-live-codeblock` plugin with the following parameters: + +```jsx title="docusaurus.config.js" +module.exports = { + // ... + themeConfig: { + // ... + // highlight-start + liveCodeblock: { + // Optional + showResultBeforeEditor: false, + }, + // highlight-end + }, +}; +``` + ## Multi-language support code blocks With MDX, you can easily create interactive components within your documentation, for example, to display code in multiple programming languages and switching between them using a tabs component. From daf62e436bb3595f3bfbd5c0b60d62504456b552 Mon Sep 17 00:00:00 2001 From: slorber Date: Thu, 4 Mar 2021 19:42:46 +0100 Subject: [PATCH 2/3] update doc --- .../docs/api/themes/theme-live-codeblock.md | 16 ++++++++++++++++ .../markdown-features-code-blocks.mdx | 19 ------------------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/website/docs/api/themes/theme-live-codeblock.md b/website/docs/api/themes/theme-live-codeblock.md index 9ee615cec084..63e9bcd4c6d2 100644 --- a/website/docs/api/themes/theme-live-codeblock.md +++ b/website/docs/api/themes/theme-live-codeblock.md @@ -9,3 +9,19 @@ This theme provides a `@theme/CodeBlock` component that is powered by react-live ```bash npm2yarn npm install --save @docusaurus/theme-live-codeblock ``` + +### Configuration + +```jsx title="docusaurus.config.js" +module.exports = { + plugins: ['@docusaurus/theme-live-codeblock'], + themeConfig: { + liveCodeBlock: { + /** + * Display the live playground before/above the code editor + */ + showResultBeforeEditor: false, + }, + }, +}; +``` diff --git a/website/docs/guides/markdown-features/markdown-features-code-blocks.mdx b/website/docs/guides/markdown-features/markdown-features-code-blocks.mdx index e0f90c7d83db..270f92d05a61 100644 --- a/website/docs/guides/markdown-features/markdown-features-code-blocks.mdx +++ b/website/docs/guides/markdown-features/markdown-features-code-blocks.mdx @@ -345,25 +345,6 @@ function MyPlayground(props) { } ``` -### Configuration - -You can also configurate `@docusaurus/theme-live-codeblock` plugin with the following parameters: - -```jsx title="docusaurus.config.js" -module.exports = { - // ... - themeConfig: { - // ... - // highlight-start - liveCodeblock: { - // Optional - showResultBeforeEditor: false, - }, - // highlight-end - }, -}; -``` - ## Multi-language support code blocks With MDX, you can easily create interactive components within your documentation, for example, to display code in multiple programming languages and switching between them using a tabs component. From 2aaa692357e9c5919679b5528796c34e36397797 Mon Sep 17 00:00:00 2001 From: slorber Date: Thu, 4 Mar 2021 20:12:49 +0100 Subject: [PATCH 3/3] refactor as playgroundPosition --- .../src/__tests__/validateThemeConfig.test.js | 64 ++++++++++++------- .../src/theme/Playground/index.js | 4 +- .../src/theme/Playground/styles.module.css | 5 +- .../src/validateThemeConfig.js | 12 ++-- .../docs/api/themes/theme-live-codeblock.md | 5 +- website/docusaurus.config.js | 4 +- 6 files changed, 59 insertions(+), 35 deletions(-) diff --git a/packages/docusaurus-theme-live-codeblock/src/__tests__/validateThemeConfig.test.js b/packages/docusaurus-theme-live-codeblock/src/__tests__/validateThemeConfig.test.js index 6824f9c31ac0..ce0fdf040050 100644 --- a/packages/docusaurus-theme-live-codeblock/src/__tests__/validateThemeConfig.test.js +++ b/packages/docusaurus-theme-live-codeblock/src/__tests__/validateThemeConfig.test.js @@ -22,50 +22,70 @@ function testValidateThemeConfig(themeConfig) { } describe('validateThemeConfig', () => { - test('minimal config', () => { - const liveCodeblock = { - showResultBeforeEditor: true, - }; - expect(testValidateThemeConfig({liveCodeblock})).toEqual({ - liveCodeblock: { + test('undefined config', () => { + const liveCodeBlock = undefined; + expect(testValidateThemeConfig({liveCodeBlock})).toEqual({ + liveCodeBlock: { ...DEFAULT_CONFIG, - ...liveCodeblock, }, }); }); - test('undefined config 1', () => { - const liveCodeblock = undefined; - expect(testValidateThemeConfig({liveCodeblock})).toEqual({ - liveCodeblock: { + test('unexist config', () => { + expect(testValidateThemeConfig({})).toEqual({ + liveCodeBlock: { ...DEFAULT_CONFIG, }, }); }); - test('unexist config', () => { - expect(testValidateThemeConfig({})).toEqual({ - liveCodeblock: { + test('empty config', () => { + const liveCodeBlock = {}; + expect(testValidateThemeConfig({liveCodeBlock})).toEqual({ + liveCodeBlock: { ...DEFAULT_CONFIG, }, }); }); - test('empty config', () => { - const liveCodeblock = {}; - expect(testValidateThemeConfig({liveCodeblock})).toEqual({ - liveCodeblock: { + test('playgroundPosition top', () => { + const liveCodeBlock = { + playgroundPosition: 'top', + }; + expect(testValidateThemeConfig({liveCodeBlock})).toEqual({ + liveCodeBlock: { + ...DEFAULT_CONFIG, + ...liveCodeBlock, + }, + }); + }); + + test('playgroundPosition bottom', () => { + const liveCodeBlock = { + playgroundPosition: 'bottom', + }; + expect(testValidateThemeConfig({liveCodeBlock})).toEqual({ + liveCodeBlock: { ...DEFAULT_CONFIG, + ...liveCodeBlock, }, }); }); - test('showResultBeforeEditor not a boolean', () => { - const liveCodeblock = {showResultBeforeEditor: 'invalid'}; + test('playgroundPosition invalid string', () => { + const liveCodeBlock = {playgroundPosition: 'invalid'}; + expect(() => + testValidateThemeConfig({liveCodeBlock}), + ).toThrowErrorMatchingInlineSnapshot( + `"\\"liveCodeBlock.playgroundPosition\\" must be one of [top, bottom]"`, + ); + }); + test('playgroundPosition invalid boolean', () => { + const liveCodeBlock = {playgroundPosition: true}; expect(() => - testValidateThemeConfig({liveCodeblock}), + testValidateThemeConfig({liveCodeBlock}), ).toThrowErrorMatchingInlineSnapshot( - `"\\"liveCodeblock.showResultBeforeEditor\\" must be a boolean"`, + `"\\"liveCodeBlock.playgroundPosition\\" must be one of [top, bottom]"`, ); }); }); diff --git a/packages/docusaurus-theme-live-codeblock/src/theme/Playground/index.js b/packages/docusaurus-theme-live-codeblock/src/theme/Playground/index.js index e976faee934f..882b07ff0e81 100644 --- a/packages/docusaurus-theme-live-codeblock/src/theme/Playground/index.js +++ b/packages/docusaurus-theme-live-codeblock/src/theme/Playground/index.js @@ -57,7 +57,7 @@ export default function Playground({children, transformCode, ...props}) { isClient, siteConfig: { themeConfig: { - liveCodeblock: {showResultBeforeEditor}, + liveCodeBlock: {playgroundPosition}, }, }, } = useDocusaurusContext(); @@ -71,7 +71,7 @@ export default function Playground({children, transformCode, ...props}) { transformCode={transformCode || ((code) => `${code};`)} theme={prismTheme} {...props}> - {showResultBeforeEditor ? ( + {playgroundPosition === 'top' ? ( <> diff --git a/packages/docusaurus-theme-live-codeblock/src/theme/Playground/styles.module.css b/packages/docusaurus-theme-live-codeblock/src/theme/Playground/styles.module.css index be268c7c62a9..675014232136 100644 --- a/packages/docusaurus-theme-live-codeblock/src/theme/Playground/styles.module.css +++ b/packages/docusaurus-theme-live-codeblock/src/theme/Playground/styles.module.css @@ -35,7 +35,10 @@ .playgroundPreview { border: 1px solid var(--ifm-color-emphasis-200); + padding: 1rem; +} + +.playgroundPreview:last-of-type, .playgroundEditor:last-of-type { border-bottom-left-radius: var(--ifm-global-radius); border-bottom-right-radius: var(--ifm-global-radius); - padding: 1rem; } diff --git a/packages/docusaurus-theme-live-codeblock/src/validateThemeConfig.js b/packages/docusaurus-theme-live-codeblock/src/validateThemeConfig.js index 35720356a57f..7b294874d60e 100644 --- a/packages/docusaurus-theme-live-codeblock/src/validateThemeConfig.js +++ b/packages/docusaurus-theme-live-codeblock/src/validateThemeConfig.js @@ -8,17 +8,17 @@ const Joi = require('joi'); const DEFAULT_CONFIG = { - showResultBeforeEditor: false, + playgroundPosition: 'bottom', }; exports.DEFAULT_CONFIG = DEFAULT_CONFIG; const Schema = Joi.object({ - liveCodeblock: Joi.object({ - showResultBeforeEditor: Joi.boolean().default( - DEFAULT_CONFIG.showResultBeforeEditor, - ), + liveCodeBlock: Joi.object({ + playgroundPosition: Joi.string() + .equal('top', 'bottom') + .default(DEFAULT_CONFIG.playgroundPosition), }) - .label('themeConfig.liveCodeblock') + .label('themeConfig.liveCodeBlock') .default(DEFAULT_CONFIG), }); exports.Schema = Schema; diff --git a/website/docs/api/themes/theme-live-codeblock.md b/website/docs/api/themes/theme-live-codeblock.md index 63e9bcd4c6d2..8a676646f4c0 100644 --- a/website/docs/api/themes/theme-live-codeblock.md +++ b/website/docs/api/themes/theme-live-codeblock.md @@ -18,9 +18,10 @@ module.exports = { themeConfig: { liveCodeBlock: { /** - * Display the live playground before/above the code editor + * The position of the live playground, above or under the editor + * Possible values: "top" | "bottom" */ - showResultBeforeEditor: false, + playgroundPosition: 'bottom', }, }, }; diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 80ba708c723f..cddd0d0a5301 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -281,8 +281,8 @@ const LocaleConfigs = isI18nStaging ], ], themeConfig: { - liveCodeblock: { - showResultBeforeEditor: true, + liveCodeBlock: { + playgroundPosition: 'bottom', }, hideableSidebar: true, colorMode: {