├── README.md ├── icon.png ├── index.html ├── index.js ├── screenshot.png └── style.css /README.md: -------------------------------------------------------------------------------- 1 | ![screenshot](screenshot.png) 2 | 3 | # Code Editor 4 | 5 | - You can change the editor theme by editing index.html file in line 17 -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milanlizriadi/code-editor/434cb20994559d74dcf41a95b6fee8fa8009a863/icon.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 11 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | Code Editor | Milanz 29 | 30 | 31 | 32 |
33 |
34 |
35 |
Code Editor
36 |
37 | # 38 | Milanz 41 |
42 |
43 |
44 | 45 |
46 |
47 |
HTML
48 |
49 |
50 |
CSS
51 |
52 |
53 |
JavaScript
54 |
55 |
56 | 57 |
58 | 59 |
60 |
61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const livePreviewFrame = document.getElementById('live-preview'); 2 | const htmlEditor = document.getElementById('html'); 3 | const cssEditor = document.getElementById('css'); 4 | const jsEditor = document.getElementById('js'); 5 | 6 | function initializeLivePreview() { 7 | livePreviewFrame.contentWindow.document.body.innerHTML = ''; 8 | const styleElement = document.createElement('style'); 9 | styleElement.setAttribute('id', 'live-preview-style'); 10 | livePreviewFrame.contentWindow.document.head.appendChild(styleElement); 11 | 12 | const pagedJsScript = document.createElement('script'); 13 | pagedJsScript.src = 'https://unpkg.com/pagedjs/dist/paged.legacy.polyfill.js'; 14 | livePreviewFrame.contentWindow.document.head.appendChild(pagedJsScript); 15 | } 16 | 17 | function updateLiveHTMLPreview(codeEditors) { 18 | livePreviewFrame.contentWindow.document.body.innerHTML = codeEditors.html.getValue(); 19 | } 20 | 21 | function updateLiveCSSPreview(codeEditors) { 22 | const styleElement = livePreviewFrame.contentWindow.document.getElementById('live-preview-style'); 23 | styleElement.innerHTML = codeEditors.css.getValue(); 24 | } 25 | 26 | function updateLiveJSPreview(codeEditors) { 27 | const scriptElement = document.createElement('script'); 28 | scriptElement.innerHTML = codeEditors.js.getValue(); 29 | livePreviewFrame.contentWindow.document.body.appendChild(scriptElement); 30 | } 31 | 32 | function initializeCodeEditors() { 33 | function getDefaultOptions(object) { 34 | const defaultOptions = { 35 | lineNumbers: true, 36 | autoCloseTags: true, 37 | autoCloseBrackets: true, 38 | theme: 'panda-syntax' 39 | }; 40 | if (object) { 41 | const keys = Object.keys(object); 42 | for (const key of keys) { 43 | defaultOptions[key] = object[key]; 44 | } 45 | } 46 | return defaultOptions; 47 | } 48 | 49 | const codeEditors = { 50 | html: CodeMirror(htmlEditor, getDefaultOptions({ 51 | mode: 'text/html', 52 | value: '', 53 | })), 54 | css: CodeMirror(cssEditor, getDefaultOptions({ 55 | mode: 'css', 56 | value: '', 57 | extraKeys: { 'Ctrl-Space': 'autocomplete' }, 58 | hintOptions: { 59 | completeSingle: false, 60 | closeOnUnfocus: false 61 | } 62 | })), 63 | js: CodeMirror(jsEditor, getDefaultOptions({ 64 | mode: 'javascript', 65 | value: '' 66 | })), 67 | }; 68 | return codeEditors; 69 | } 70 | 71 | function setupLivePreviewStudio() { 72 | const codeEditors = initializeCodeEditors(); 73 | 74 | CodeMirror.on(codeEditors.html, 'change', () => { 75 | updateLiveHTMLPreview(codeEditors); 76 | }); 77 | 78 | CodeMirror.on(codeEditors.css, 'change', () => { 79 | updateLiveCSSPreview(codeEditors); 80 | }); 81 | 82 | CodeMirror.on(codeEditors.js, 'change', () => { 83 | updateLiveJSPreview(codeEditors); 84 | }); 85 | } 86 | 87 | document.addEventListener('DOMContentLoaded', () => { 88 | initializeLivePreview(); 89 | setupLivePreviewStudio(); 90 | }); -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milanlizriadi/code-editor/434cb20994559d74dcf41a95b6fee8fa8009a863/screenshot.png -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Source+Sans+3:wght@300;400;500;600;700&display=swap"); 2 | 3 | body { 4 | margin: 0; 5 | } 6 | 7 | a { 8 | color: white; 9 | text-decoration: none; 10 | } 11 | 12 | .container { 13 | font-family: "Source Sans 3", sans-serif; 14 | } 15 | 16 | .header { 17 | background: #000; 18 | color: #fff; 19 | padding: 1rem 0.5rem; 20 | border-bottom: 5px solid #333; 21 | } 22 | 23 | .header .title { 24 | padding: 0.5rem; 25 | } 26 | 27 | .header .title .main-title { 28 | font-size: 22px; 29 | font-weight: 600; 30 | margin-bottom: 0.2rem; 31 | } 32 | 33 | .header .title .sub-title { 34 | font-size: 15px; 35 | } 36 | 37 | .header .title .sub-title span { 38 | color: #999; 39 | } 40 | 41 | .editor { 42 | width: 33.33%; 43 | height: 100%; 44 | float: left; 45 | box-sizing: border-box; 46 | position: relative; 47 | } 48 | 49 | .editor #html { 50 | border-right: 1px solid #777; 51 | } 52 | 53 | .editor #css { 54 | border-left: 20px solid #333; 55 | border-right: 1px solid #777; 56 | } 57 | 58 | .editor #js { 59 | border-left: 20px solid #333; 60 | } 61 | 62 | .editor-title { 63 | padding: 0.5rem; 64 | font-size: 1.2rem; 65 | padding-left: 2rem; 66 | transition: 150ms; 67 | } 68 | 69 | .editor-title-html:hover { 70 | color: #dd4b25; 71 | font-weight: bold; 72 | cursor: default; 73 | } 74 | 75 | .editor-title-css:hover { 76 | color: #254bdd; 77 | font-weight: bold; 78 | cursor: default; 79 | } 80 | 81 | .editor-title-js:hover { 82 | color: #f0dc55; 83 | font-weight: bold; 84 | cursor: default; 85 | } 86 | 87 | .code-box { 88 | position: relative; 89 | height: calc(50vh - 4.6rem); 90 | border-top: 1px solid #000; 91 | border-bottom: 10px solid #333; 92 | overflow: hidden; 93 | } 94 | 95 | .preview { 96 | position: relative; 97 | height: calc(90vh - 30px); 98 | background: #fff; 99 | border-top: 15px ridge #333; 100 | } 101 | 102 | .preview iframe { 103 | width: 100%; 104 | height: 100%; 105 | } 106 | 107 | ::-webkit-scrollbar { 108 | width: 8px; 109 | height: 8px; 110 | } 111 | 112 | ::-webkit-scrollbar-track { 113 | background: transparent; 114 | } 115 | 116 | ::-webkit-scrollbar-thumb { 117 | background: #555; 118 | border-radius: 20px; 119 | } 120 | 121 | ::-webkit-scrollbar-thumb:hover { 122 | background: #666; 123 | border-radius: 20px; 124 | } 125 | --------------------------------------------------------------------------------