import { jsxs, jsx } from 'react/jsx-runtime'; import * as React from 'react'; import CodeMirror from 'codemirror5'; import { styled } from 'styled-components'; import { PreviewWysiwyg } from './PreviewWysiwyg.mjs'; import { newlineAndIndentContinueMarkdownList } from './utils/continueList.mjs'; import 'codemirror5/addon/display/placeholder'; const Editor = /*#__PURE__*/ React.forwardRef(({ disabled, editorRef, error, isPreviewMode, isExpandMode, name, onChange, placeholder, textareaRef, value }, forwardedRef)=>{ const onChangeRef = React.useRef(onChange); React.useEffect(()=>{ onChangeRef.current = onChange; }, [ onChange ]); React.useEffect(()=>{ if (editorRef.current) { // Ensure the editor and its wrapper are cleaned up whenever this view is re-rendered // e.g. in case of re-ordering wysiwyg components in a DynamicZone editorRef.current.toTextArea(); } editorRef.current = CodeMirror.fromTextArea(textareaRef.current, { lineWrapping: true, extraKeys: { Enter: 'newlineAndIndentContinueMarkdownList', Tab: false, 'Shift-Tab': false }, readOnly: false, smartIndent: false, placeholder, spellcheck: true, inputStyle: 'contenteditable' }); // @ts-expect-error – doesn't think command exists? CodeMirror.commands.newlineAndIndentContinueMarkdownList = newlineAndIndentContinueMarkdownList; editorRef.current.on('change', (cm, change)=>{ // setValue (prop sync) must not notify the form — parent already has the value. if (change.origin === 'setValue') { return; } onChangeRef.current(name, cm.getValue()); }); }, [ editorRef, textareaRef, name, placeholder ]); React.useEffect(()=>{ if (editorRef.current.hasFocus()) { return; } const nextValue = value ?? ''; if (editorRef.current.getValue() !== nextValue) { editorRef.current.setValue(nextValue); } }, [ editorRef, value ]); React.useEffect(()=>{ if (isPreviewMode || disabled) { editorRef.current.setOption('readOnly', 'nocursor'); } else { editorRef.current.setOption('readOnly', false); } }, [ disabled, isPreviewMode, editorRef ]); React.useEffect(()=>{ if (error) { editorRef.current.setOption('screenReaderLabel', error); } else { // to replace with translation editorRef.current.setOption('screenReaderLabel', 'Editor'); } }, [ editorRef, error ]); React.useImperativeHandle(forwardedRef, ()=>({ focus () { editorRef.current.getInputField().focus(); }, scrollIntoView (args) { editorRef.current.getInputField().scrollIntoView(args); } }), [ editorRef ]); return /*#__PURE__*/ jsxs(EditorAndPreviewWrapper, { children: [ /*#__PURE__*/ jsx(EditorStylesContainer, { $isExpandMode: isExpandMode, $disabled: disabled || isPreviewMode, children: /*#__PURE__*/ jsx("textarea", { ref: textareaRef }) }), isPreviewMode && /*#__PURE__*/ jsx(PreviewWysiwyg, { data: value }) ] }); }); const EditorAndPreviewWrapper = styled.div` position: relative; height: calc(100%); ${({ theme })=>theme.breakpoints.medium} { height: calc(100% - 48px); } `; const EditorStylesContainer = styled.div` cursor: ${({ $disabled })=>$disabled ? 'not-allowed !important' : 'auto'}; height: 100%; /* BASICS */ .CodeMirror-placeholder { color: ${({ theme })=>theme.colors.neutral600} !important; } .CodeMirror { /* Set height, width, borders, and global font properties here */ font-size: 1.6rem; height: ${({ $isExpandMode })=>$isExpandMode ? '100%' : '410px'}; // 512px(total height) - 48px (header) - 52px(footer) - 2px border color: ${({ theme })=>theme.colors.neutral800}; direction: ltr; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; ${({ theme })=>theme.breakpoints.medium} { font-size: 1.4rem; } } /* PADDING */ .CodeMirror-lines { padding: ${({ theme })=>`${theme.spaces[3]} ${theme.spaces[4]}`}; /* Vertical padding around content */ } .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { /* The little square between H and V scrollbars */ background-color: ${({ theme })=>`${theme.colors.neutral0}`}; } /* GUTTER */ .CodeMirror-gutters { border-right: 1px solid #ddd; background-color: #f7f7f7; white-space: nowrap; } .CodeMirror-linenumbers { } .CodeMirror-linenumber { padding: 0 3px 0 5px; min-width: 20px; text-align: right; color: #999; white-space: nowrap; } .CodeMirror-guttermarker { color: black; } .CodeMirror-guttermarker-subtle { color: #999; } /* CURSOR */ .CodeMirror-cursor { border-left: 1px solid black; border-right: none; width: 0; } /* Shown when moving in bi-directional text */ .CodeMirror div.CodeMirror-secondarycursor { border-left: 1px solid silver; } .cm-fat-cursor .CodeMirror-cursor { width: auto; border: 0 !important; background: #7e7; } .cm-fat-cursor div.CodeMirror-cursors { /* z-index: 1; */ } .cm-fat-cursor-mark { background-color: rgba(20, 255, 20, 0.5); -webkit-animation: blink 1.06s steps(1) infinite; -moz-animation: blink 1.06s steps(1) infinite; animation: blink 1.06s steps(1) infinite; } .cm-animate-fat-cursor { width: auto; border: 0; -webkit-animation: blink 1.06s steps(1) infinite; -moz-animation: blink 1.06s steps(1) infinite; animation: blink 1.06s steps(1) infinite; background-color: #7e7; } /* Can style cursor different in overwrite (non-insert) mode */ .CodeMirror-overwrite .CodeMirror-cursor { } .cm-tab { display: inline-block; text-decoration: inherit; } .CodeMirror-rulers { position: absolute; left: 0; right: 0; top: -50px; bottom: 0; overflow: hidden; } .CodeMirror-ruler { border-left: 1px solid #ccc; top: 0; bottom: 0; position: absolute; } /* DEFAULT THEME */ .cm-header, .cm-strong { font-weight: bold; } .cm-em { font-style: italic; } .cm-link { text-decoration: underline; } .cm-strikethrough { text-decoration: line-through; } .CodeMirror-composing { border-bottom: 2px solid; } /* Default styles for common addons */ div.CodeMirror span.CodeMirror-matchingbracket { color: #0b0; } div.CodeMirror span.CodeMirror-nonmatchingbracket { color: #a22; } .CodeMirror-matchingtag { background: rgba(255, 150, 0, 0.3); } .CodeMirror-activeline-background { background: #e8f2ff; } /* STOP */ /* The rest of this file contains styles related to the mechanics of the editor. You probably shouldn't touch them. */ .CodeMirror { position: relative; overflow: hidden; border-radius: ${({ theme })=>theme.borderRadius}; background: ${({ theme })=>`${theme.colors.neutral0}`}; } .CodeMirror-scroll { overflow: scroll !important; /* Things will break if this is overridden */ /* 50px is the magic margin used to hide the element's real scrollbars */ /* See overflow: hidden in .CodeMirror */ margin-bottom: -50px; margin-right: -50px; padding-bottom: 50px; height: 100%; outline: none; /* Prevent dragging from highlighting the element */ position: relative; } .CodeMirror-sizer { position: relative; border-right: 50px solid transparent; } /* The fake, visible scrollbars. Used to force redraw during scrolling before actual scrolling happens, thus preventing shaking and flickering artifacts. */ .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { position: absolute; z-index: 1; display: none; outline: none; } .CodeMirror-vscrollbar { right: 0; top: 0; overflow-x: hidden; overflow-y: scroll; } .CodeMirror-hscrollbar { bottom: 0; left: 0; overflow-y: hidden; overflow-x: scroll; } .CodeMirror-scrollbar-filler { right: 0; bottom: 0; } .CodeMirror-lines { cursor: text; min-height: 1px; /* prevents collapsing before first draw */ } /* Reset some styles that the rest of the page might have set */ .CodeMirror pre.CodeMirror-line, .CodeMirror pre.CodeMirror-line-like { -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; border-width: 0; background: transparent; font-family: inherit; font-size: inherit; margin: 0; white-space: pre; word-wrap: normal; line-height: 1.5; color: inherit; /* z-index: 2; */ position: relative; overflow: visible; -webkit-tap-highlight-color: transparent; -webkit-font-variant-ligatures: contextual; font-variant-ligatures: contextual; } .CodeMirror pre.CodeMirror-line-like { z-index: 2; } .CodeMirror-wrap pre.CodeMirror-line, .CodeMirror-wrap pre.CodeMirror-line-like { word-wrap: break-word; white-space: pre-wrap; word-break: break-word; } .CodeMirror-linebackground { position: absolute; left: 0; right: 0; top: 0; bottom: 0; z-index: 0; } .CodeMirror-linewidget { position: relative; /* z-index: 2; */ padding: 0.1px; /* Force widget margins to stay inside of the container */ } .CodeMirror-widget { } .CodeMirror-rtl pre { direction: rtl; } .CodeMirror-code { outline: none; } /* Force content-box sizing for the elements where we expect it */ .CodeMirror-scroll, .CodeMirror-sizer, .CodeMirror-gutter, .CodeMirror-gutters, .CodeMirror-linenumber { -moz-box-sizing: content-box; box-sizing: content-box; } .CodeMirror-measure { position: absolute; width: 100%; height: 0; overflow: hidden; visibility: hidden; } .CodeMirror-cursor { position: absolute; pointer-events: none; border-color: ${({ theme })=>`${theme.colors.neutral800}`}; } .CodeMirror-measure pre { position: static; } div.CodeMirror-cursors { visibility: hidden; position: relative; + div { z-index: 0 !important; } } div.CodeMirror-dragcursors { visibility: visible; } .CodeMirror-focused div.CodeMirror-cursors { visibility: visible; } .CodeMirror-selected { background: ${({ theme })=>theme.colors.neutral200}; /* z-index: -10; */ } .CodeMirror-crosshair { cursor: crosshair; } /* Used to force a border model for a node */ .cm-force-border { padding-right: 0.1px; } /* See issue #2901 */ .cm-tab-wrap-hack:after { content: ''; } /* Help users use markselection to safely style text background */ span.CodeMirror-selectedtext { background: none; } span { color: ${({ theme })=>theme.colors.neutral800} !important; } `; export { Editor }; //# sourceMappingURL=Editor.mjs.map