From 2d8b96589f17bad9988f54ac79ef241dfe001e7d Mon Sep 17 00:00:00 2001 From: Michael Taranto Date: Thu, 27 May 2021 09:44:37 +1000 Subject: [PATCH] feat(editor): Add line numbers (#224) --- cypress/support/utils.js | 15 +++++--- src/Playroom/CodeEditor/CodeEditor.less | 42 +++++++++++++++------ src/Playroom/CodeEditor/CodeEditor.tsx | 10 ++++- src/Playroom/SplashScreen/SplashScreen.less | 2 +- src/Playroom/variables.less | 14 ++++--- 5 files changed, 59 insertions(+), 24 deletions(-) diff --git a/cypress/support/utils.js b/cypress/support/utils.js index bc4597a9..218b7fa7 100644 --- a/cypress/support/utils.js +++ b/cypress/support/utils.js @@ -86,11 +86,16 @@ export const assertFirstFrameContains = (text) => { }; export const assertCodePaneContains = (text) => { - getCodeEditor().then(($el) => { - const code = $el.get(0).innerText; - // removes code mirrors invisible last line character placeholder - // which is inserted to preserve prettiers new line at end of string. - expect(code.replace(/[\u200b]$/, '')).to.eq(text); + getCodeEditor().within(() => { + const lines = []; + cy.get('.CodeMirror-line') + .each(($el) => lines.push($el.text())) + .then(() => { + const code = lines.join('\n'); + // removes code mirrors invisible last line character placeholder + // which is inserted to preserve prettiers new line at end of string. + expect(code.replace(/[\u200b]$/, '')).to.eq(text); + }); }); }; diff --git a/src/Playroom/CodeEditor/CodeEditor.less b/src/Playroom/CodeEditor/CodeEditor.less index 357c289b..21de005c 100644 --- a/src/Playroom/CodeEditor/CodeEditor.less +++ b/src/Playroom/CodeEditor/CodeEditor.less @@ -14,13 +14,29 @@ } .marker { - width: @code-marker-size; - height: @code-marker-size; - border-radius: (@code-marker-size / 2); - background-color: @code-marker-color; + @keyframes fadeIn { + 90% { + opacity: 0; + } + 100% { + opacity: 1; + } + } + + border-radius: @radius-large; + background-color: @critical-light; + color: @critical-dark; position: relative; - top: (@code-marker-size / 2); - left: 10px; + left: 4px; + margin-right: 4px; + text-align: right; + opacity: 0; + padding-right: 10px; + animation-name: fadeIn; + animation-duration: 1s; + animation-timing-function: ease; + animation-iteration-count: 1; + animation-fill-mode: forwards; } :global { @@ -41,10 +57,6 @@ width: @code-gutter-size; } - .CodeMirror-gutter-elt { - position: relative; - } - .CodeMirror pre, .CodeMirror-linenumber { font-size: 16px; @@ -102,7 +114,15 @@ background: @code-selection; } .CodeMirror-linenumber { - color: @white; + box-sizing: border-box; + width: @code-gutter-size !important; + padding-left: 8px; + padding-right: @code-line-gutter; + color: @gray-4; + transition: @transition-fast; + &:not(:hover) { + opacity: 0.4; + } } .cm-tag { color: @code-format-tag; diff --git a/src/Playroom/CodeEditor/CodeEditor.tsx b/src/Playroom/CodeEditor/CodeEditor.tsx index 105178fc..9f8dd42d 100644 --- a/src/Playroom/CodeEditor/CodeEditor.tsx +++ b/src/Playroom/CodeEditor/CodeEditor.tsx @@ -76,7 +76,14 @@ const validateCode = (editorInstance: Editor, code: string) => { if (lineNumber) { const marker = document.createElement('div'); marker.classList.add(styles.marker); - marker.setAttribute('title', err.message); + marker.setAttribute( + 'title', + // Remove our wrapping Fragment from error message + (err.message || '') + .replace(/\/, '') + .replace(/\<\/React\.Fragment\>$/, '') + ); + marker.innerText = String(lineNumber); editorInstance.setGutterMarker(lineNumber - 1, styles.gutter, marker); } } @@ -251,6 +258,7 @@ export const CodeEditor = ({ code, onChange, previewCode, hints }: Props) => { gutters: [styles.gutter], hintOptions: { schemaInfo: hints }, viewportMargin: 50, + lineNumbers: true, extraKeys: { Tab: (cm) => { if (cm.somethingSelected()) { diff --git a/src/Playroom/SplashScreen/SplashScreen.less b/src/Playroom/SplashScreen/SplashScreen.less index 9ff8bd03..7a94f82a 100644 --- a/src/Playroom/SplashScreen/SplashScreen.less +++ b/src/Playroom/SplashScreen/SplashScreen.less @@ -15,7 +15,7 @@ align-items: center; justify-content: center; text-align: center; - background: @gray-5; + background: @gray-6; color: @white; transition: @transition-speed-slow; } diff --git a/src/Playroom/variables.less b/src/Playroom/variables.less index cbb21979..7cee556d 100644 --- a/src/Playroom/variables.less +++ b/src/Playroom/variables.less @@ -12,7 +12,7 @@ @text-standard: normal 14px @typography-family; @text-small: normal 12px @typography-family; @text-xsmall: normal 10px @typography-family; -@text-neutral: @gray-4; +@text-neutral: @gray-5; // Weight @bold: 700; @@ -27,12 +27,14 @@ @green-2: #1da584; @red-1: #fed6e1; @red-2: #e52b50; +@red-3: #c3183a; @white: #fff; @gray-1: #f4f4f4; @gray-2: #e8e8e8; @gray-3: #a7a7a7; -@gray-4: #515151; -@gray-5: #1e1e1e; +@gray-4: #767676; +@gray-5: #515151; +@gray-6: #1e1e1e; @black: #000; // Tones @@ -40,6 +42,7 @@ @positive: @green-2; @critical-light: @red-1; @critical: @red-2; +@critical-dark: @red-3; @neutral: @gray-2; // Highlights @@ -76,9 +79,8 @@ // Code Editor @code-background: @white; @code-font-family: Source Code Pro, Firacode, Hasklig, Menlo, monospace; -@code-gutter-size: @gutter-width; -@code-marker-size: @grid * 3; -@code-marker-color: @highlight; +@code-gutter-size: @gutter-width * 1.75; +@code-line-gutter: 20px; @code-format-tag: @blue-4; @code-format-attribute: @blue-2; @code-format-string: @blue-3;