diff --git a/dev-test/config.yml b/dev-test/config.yml index 26f27a07..68fd2034 100644 --- a/dev-test/config.yml +++ b/dev-test/config.yml @@ -33,7 +33,7 @@ collections: # A list of collections the CMS should be able to edit required: false tagname: '' - - { label: 'Body', name: 'body', widget: 'markdown', hint: 'Main content goes here.' } + - { editorComponents: ['youtube'], label: 'Body', name: 'body', widget: 'markdown', hint: 'Main content goes here.' } meta: - { label: 'SEO Description', name: 'description', widget: 'text' } diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/RawEditor.js b/packages/netlify-cms-widget-markdown/src/MarkdownControl/RawEditor.js index 86d246bb..1c5a721d 100644 --- a/packages/netlify-cms-widget-markdown/src/MarkdownControl/RawEditor.js +++ b/packages/netlify-cms-widget-markdown/src/MarkdownControl/RawEditor.js @@ -13,19 +13,17 @@ import { markdownToHtml } from '../serializers'; import { editorStyleVars, EditorControlBar } from '../styles'; import Toolbar from './Toolbar'; -const styleStrings = { - slateRaw: ` - position: relative; - overflow: hidden; - overflow-x: auto; - min-height: ${lengths.richTextEditorMinHeight}; - font-family: ${fonts.mono}; - border-top-left-radius: 0; - border-top-right-radius: 0; - border-top: 0; - margin-top: -${editorStyleVars.stickyDistanceBottom}; - `, -}; +const rawEditorStyles = ({ minimal }) => ` + position: relative; + overflow: hidden; + overflow-x: auto; + min-height: ${minimal ? 'auto' : lengths.richTextEditorMinHeight}; + font-family: ${fonts.mono}; + border-top-left-radius: 0; + border-top-right-radius: 0; + border-top: 0; + margin-top: -${editorStyleVars.stickyDistanceBottom}; +`; const RawEditorContainer = styled.div` position: relative; @@ -118,7 +116,7 @@ export default class RawEditor extends React.Component { className={cx( className, css` - ${styleStrings.slateRaw} + ${rawEditorStyles({ minimal: field.get('minimal') })} `, )} value={this.state.value} diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/Toolbar.js b/packages/netlify-cms-widget-markdown/src/MarkdownControl/Toolbar.js index 5d805376..ddf5b7a9 100644 --- a/packages/netlify-cms-widget-markdown/src/MarkdownControl/Toolbar.js +++ b/packages/netlify-cms-widget-markdown/src/MarkdownControl/Toolbar.js @@ -70,6 +70,7 @@ const headingOptions = { export default class Toolbar extends React.Component { static propTypes = { buttons: ImmutablePropTypes.list, + editorComponents: ImmutablePropTypes.list, onToggleMode: PropTypes.func.isRequired, rawMode: PropTypes.bool, plugins: ImmutablePropTypes.map, @@ -86,9 +87,9 @@ export default class Toolbar extends React.Component { t: PropTypes.func.isRequired, }; - isHidden = button => { + isVisible = button => { const { buttons } = this.props; - return List.isList(buttons) ? !buttons.includes(button) : false; + return !List.isList(buttons) || buttons.includes(button); }; handleBlockClick = (event, type) => { @@ -114,52 +115,59 @@ export default class Toolbar extends React.Component { hasMark = () => {}, hasInline = () => {}, hasBlock = () => {}, + editorComponents, t, } = this.props; + const isVisible = this.isVisible; + const showEditorComponents = !editorComponents || editorComponents.size >= 1; + const showPlugin = ({ id }) => (editorComponents ? editorComponents.includes(id) : true); + const pluginsList = plugins ? plugins.toList().filter(showPlugin) : List(); return (
- - - - + {isVisible('bold') && ( + + )} + {isVisible('italic') && ( + + )} + {isVisible('code') && ( + + )} + {isVisible('link') && ( + + )} {/* Show dropdown if at least one heading is not hidden */} - {Object.keys(headingOptions).some(optionKey => { - return !this.isHidden(optionKey); - }) && ( + {Object.keys(headingOptions).some(isVisible) && ( { - return hasBlock(optionKey); - }) - } + isActive={!disabled && Object.keys(headingOptions).some(hasBlock)} /> )} @@ -183,7 +186,7 @@ export default class Toolbar extends React.Component { {!disabled && Object.keys(headingOptions).map( (optionKey, idx) => - !this.isHidden(optionKey) && ( + isVisible(optionKey) && ( )} - - - - - ( - - - - )} - > - {plugins && - plugins - .toList() - .map((plugin, idx) => ( - onSubmit(plugin)} /> - ))} - - + {isVisible('quote') && ( + + )} + {isVisible('bulleted-list') && ( + + )} + {isVisible('numbered-list') && ( + + )} + {showEditorComponents && ( + + ( + + + + )} + > + {pluginsList.map((plugin, idx) => ( + onSubmit(plugin)} /> + ))} + + + )}
diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/ToolbarButton.js b/packages/netlify-cms-widget-markdown/src/MarkdownControl/ToolbarButton.js index 6491533c..8e8ac5f5 100644 --- a/packages/netlify-cms-widget-markdown/src/MarkdownControl/ToolbarButton.js +++ b/packages/netlify-cms-widget-markdown/src/MarkdownControl/ToolbarButton.js @@ -23,22 +23,16 @@ const StyledToolbarButton = styled.button` } `; -const ToolbarButton = ({ type, label, icon, onClick, isActive, isHidden, disabled }) => { - if (isHidden) { - return null; - } - - return ( - onClick && onClick(e, type)} - title={label} - disabled={disabled} - > - {icon ? : label} - - ); -}; +const ToolbarButton = ({ type, label, icon, onClick, isActive, disabled }) => ( + onClick && onClick(e, type)} + title={label} + disabled={disabled} + > + {icon ? : label} + +); ToolbarButton.propTypes = { type: PropTypes.string, @@ -46,7 +40,6 @@ ToolbarButton.propTypes = { icon: PropTypes.string, onClick: PropTypes.func, isActive: PropTypes.bool, - isHidden: PropTypes.bool, disabled: PropTypes.bool, }; diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/VisualEditor.js b/packages/netlify-cms-widget-markdown/src/MarkdownControl/VisualEditor.js index e80ff024..3053b577 100644 --- a/packages/netlify-cms-widget-markdown/src/MarkdownControl/VisualEditor.js +++ b/packages/netlify-cms-widget-markdown/src/MarkdownControl/VisualEditor.js @@ -15,12 +15,12 @@ import { renderBlock, renderInline, renderMark } from './renderers'; import plugins from './plugins/visual'; import schema from './schema'; -const visualEditorStyles = ` +const visualEditorStyles = ({ minimal }) => ` position: relative; overflow: hidden; overflow-x: auto; font-family: ${fonts.primary}; - min-height: ${lengths.richTextEditorMinHeight}; + min-height: ${minimal ? 'auto' : lengths.richTextEditorMinHeight}; border-top-left-radius: 0; border-top-right-radius: 0; border-top: 0; @@ -195,6 +195,7 @@ export default class Editor extends React.Component { onAddAsset={onAddAsset} getAsset={getAsset} buttons={field.get('buttons')} + editorComponents={field.get('editorComponents')} hasMark={this.hasMark} hasInline={this.hasInline} hasBlock={this.hasBlock} @@ -207,7 +208,7 @@ export default class Editor extends React.Component { className={cx( className, css` - ${visualEditorStyles} + ${visualEditorStyles({ minimal: field.get('minimal') })} `, )} > diff --git a/website/content/docs/widgets/markdown.md b/website/content/docs/widgets/markdown.md index 31af6e0d..b822c556 100644 --- a/website/content/docs/widgets/markdown.md +++ b/website/content/docs/widgets/markdown.md @@ -12,7 +12,9 @@ _Please note:_ If you want to use your markdown editor to fill a markdown file c - **Data type:** markdown - **Options:** - `default`: accepts markdown content - - `buttons`: an array of strings representing the formatting buttons to display, all buttons shown by default. Buttons include: `bold`, `italic`, `code`, `link`, `heading-one`, `heading-two`, `heading-three`, `heading-four`, `heading-five`, `heading-six`, `quote`, `code-block`, `bulleted-list`, and `numbered-list`. + - `minimal`: accepts a boolean value, `false` by default. Sets the widget height to minimum possible. + - `buttons`: an array of strings representing the formatting buttons to display (all shown by default). Buttons include: `bold`, `italic`, `code`, `link`, `heading-one`, `heading-two`, `heading-three`, `heading-four`, `heading-five`, `heading-six`, `quote`, `bulleted-list`, and `numbered-list`. + - `editorComponents`: an array of strings representing the names of editor components to display (all shown by default). The `image` and `code-block` editor components are included with Netlify CMS by default, but others may be [created and registered](/docs/custom-widgets/#registereditorcomponent). - **Example:** ```yaml