| 1 |
/** |
| 2 |
* External dependencies |
| 3 |
*/ |
| 4 |
import styled from "@emotion/styled"; |
| 5 |
|
| 6 |
/** |
| 7 |
* WordPress dependencies |
| 8 |
*/ |
| 9 |
import { __ } from "@wordpress/i18n"; |
| 10 |
import { useEffect, useRef } from "@wordpress/element"; |
| 11 |
|
| 12 |
/** |
| 13 |
* Internal dependencies |
| 14 |
*/ |
| 15 |
import { LabelHelpControl } from "../label-help-control"; |
| 16 |
import { labels } from "../../utils/labels"; |
| 17 |
|
| 18 |
const CodeEditorStyled = styled.div` |
| 19 |
width: 100%; |
| 20 |
|
| 21 |
.boldblocks-editor__code { |
| 22 |
margin-top: 8px; |
| 23 |
margin-right: -16px; |
| 24 |
margin-left: -16px; |
| 25 |
overflow: auto; |
| 26 |
border: 1px solid #ddd; |
| 27 |
|
| 28 |
> .CodeMirror { |
| 29 |
width: var(--cbb-editor-width, 600px); |
| 30 |
} |
| 31 |
} |
| 32 |
`; |
| 33 |
|
| 34 |
export const CodeEditor = ({ value, id, label, help, mode = "text/css" }) => { |
| 35 |
// The element |
| 36 |
let ref = useRef(null); |
| 37 |
let editorRef = useRef(null); |
| 38 |
|
| 39 |
if (!label) { |
| 40 |
label = mode === "text/css" ? labels.customCSS : labels.customJS; |
| 41 |
} |
| 42 |
|
| 43 |
if (!help) { |
| 44 |
help = mode === "text/css" ? labels.customCSSHelp : labels.customJSHelp; |
| 45 |
} |
| 46 |
|
| 47 |
useEffect(() => { |
| 48 |
if (!ref.current || editorRef.current) { |
| 49 |
return; |
| 50 |
} |
| 51 |
|
| 52 |
editorRef.current = wp.CodeMirror(ref.current, { |
| 53 |
mode, |
| 54 |
value, |
| 55 |
readOnly: "nocursor", |
| 56 |
lineNumbers: true, |
| 57 |
lineWrapping: true, |
| 58 |
matchBrackets: true, |
| 59 |
lint: true, |
| 60 |
tabSize: 2, |
| 61 |
styleActiveLine: true, |
| 62 |
styleActiveSelected: true, |
| 63 |
extraKeys: { |
| 64 |
"Shift-Ctrl-[": "fold", |
| 65 |
"Shift-Ctrl-]": "unfold", |
| 66 |
}, |
| 67 |
}); |
| 68 |
|
| 69 |
let longestLine = ""; |
| 70 |
const lineCount = editorRef.current.lineCount(); |
| 71 |
|
| 72 |
// Loop through all lines to find the longest one by character length. |
| 73 |
for (let i = 0; i < lineCount; i++) { |
| 74 |
const currentLine = editorRef.current.getLine(i); |
| 75 |
if (currentLine.length > longestLine.length) { |
| 76 |
longestLine = currentLine; |
| 77 |
} |
| 78 |
} |
| 79 |
|
| 80 |
const width = (longestLine ? longestLine.length : 0) * 9; |
| 81 |
ref.current.style.setProperty( |
| 82 |
"--cbb-editor-width", |
| 83 |
`${Math.min(Math.max(width, 270), 1800)}px`, |
| 84 |
); |
| 85 |
}, [ref.current]); |
| 86 |
|
| 87 |
return ( |
| 88 |
<CodeEditorStyled className="boldblocks-editor"> |
| 89 |
{label && ( |
| 90 |
<LabelHelpControl label={label} helpControls={help} isAtTop={false} /> |
| 91 |
)} |
| 92 |
<div ref={ref} id={id} className="boldblocks-editor__code"></div> |
| 93 |
</CodeEditorStyled> |
| 94 |
); |
| 95 |
}; |
| 96 |
|