-
-
Notifications
You must be signed in to change notification settings - Fork 174
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Hide code highlight and cursor until interaction
By default, the code area displays line highlighting (active line and gutter indicators) and shows the cursor even before user interaction, which clutters the initial UI. This commit hides the highlighting and cursor until the user interacts with the code area, providing a cleaner initial UI similar to modern editors when code is first displayed. When code is generated automatically, the code is already highlighted with a custom marker. Therefore, indicating a specific line by default is unnecessary and clutters the view. Key changes: - Hide active line highlighting before user interaction. - Hide cursor before user interaction. Other supporting changes: - Refactor `TheCodeArea` to extract third-party component (`Ace`) related logic for better maintainability. - Simplify code editor theme setting by removing the component property. - Remove unnecessary `github` theme import for the code editor component as it's unused.
- Loading branch information
1 parent
2f31bc7
commit 6aaa843
Showing
5 changed files
with
141 additions
and
57 deletions.
There are no files selected for viewing
91 changes: 91 additions & 0 deletions
91
src/presentation/components/Code/Ace/AceCodeEditorFactory.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import ace from './ace-importer'; | ||
import type { CodeEditorFactory, SupportedSyntaxLanguage } from '../CodeEditorFactory'; | ||
|
||
const CodeEditorTheme = 'xcode'; | ||
|
||
export const initializeAceEditor: CodeEditorFactory = (options) => { | ||
const editor = ace.edit(options.editorContainerElementId); | ||
const mode = getAceModeName(options.language); | ||
editor.getSession().setMode(`ace/mode/${mode}`); | ||
editor.setTheme(`ace/theme/${CodeEditorTheme}`); | ||
editor.setReadOnly(true); | ||
editor.setAutoScrollEditorIntoView(true); | ||
editor.setShowPrintMargin(false); // Hide the vertical line | ||
editor.getSession().setUseWrapMode(true); // Make code readable on mobile | ||
hideActiveLineAndCursorUntilInteraction(editor); | ||
return { | ||
updateContent: (code) => editor.setValue(code, 1), | ||
destroy: () => editor.destroy(), | ||
scrollToLine: (lineNumber) => { | ||
const column = editor.session.getLine(lineNumber).length; | ||
if (column === undefined) { | ||
return; | ||
} | ||
editor.gotoLine(lineNumber, column, true); | ||
}, | ||
updateSize: () => editor?.resize(), | ||
applyStyleToLineRange: (start, end, className) => { | ||
const AceRange = ace.require('ace/range').Range; | ||
const markerId = editor.session.addMarker( | ||
new AceRange(start, 0, end, 0), | ||
className, | ||
'fullLine', | ||
); | ||
return { | ||
clearStyle: () => { | ||
editor.session.removeMarker(markerId); | ||
}, | ||
}; | ||
}, | ||
}; | ||
}; | ||
|
||
function getAceModeName(language: SupportedSyntaxLanguage): string { | ||
switch (language) { | ||
case 'batchfile': return 'batchfile'; | ||
case 'shellscript': return 'sh'; | ||
default: | ||
throw new Error(`Language not supported: ${language}`); | ||
} | ||
} | ||
|
||
function hideActiveLineAndCursorUntilInteraction(editor: ace.Ace.Editor) { | ||
hideActiveLineAndCursor(editor); | ||
editor.session.on('change', () => { | ||
editor.session.selection.clearSelection(); | ||
hideActiveLineAndCursor(editor); | ||
}); | ||
editor.session.selection.on('changeSelection', () => { | ||
showActiveLineAndCursor(editor); | ||
}); | ||
} | ||
|
||
function hideActiveLineAndCursor(editor: ace.Ace.Editor): void { | ||
editor.setHighlightGutterLine(false); // Remove highlighting on line number column | ||
editor.setHighlightActiveLine(false); // Remove highlighting throughout the line | ||
setCursorVisibility(false, editor); | ||
} | ||
|
||
function showActiveLineAndCursor(editor: ace.Ace.Editor): void { | ||
editor.setHighlightGutterLine(true); // Show highlighting on line number column | ||
editor.setHighlightActiveLine(true); // Show highlighting throughout the line | ||
setCursorVisibility(true, editor); | ||
} | ||
|
||
// Shows/removes vertical line after focused character | ||
function setCursorVisibility( | ||
isVisible: boolean, | ||
editor: ace.Ace.Editor, | ||
) { | ||
const cursor = editor.renderer.container.querySelector('.ace_cursor-layer') as HTMLElement; | ||
if (!cursor) { | ||
throw new Error('Cannot find Ace cursor, did Ace change its rendering?'); | ||
} | ||
cursor.style.display = isVisible ? '' : 'none'; | ||
// Implementation options for cursor visibility: | ||
// ❌ editor.renderer.showCursor() and hideCursor(): Not functioning as expected | ||
// ❌ editor.renderer.#cursorLayer: No longer part of the public API | ||
// ✅ .ace_hidden-cursors { opacity: 0; }: Hides cursor when not focused | ||
// Pros: Works more automatically | ||
// Cons: Provides less control over visibility toggling | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/** | ||
* Abstraction layer for code editor functionality. | ||
* Allows for flexible integration and easy switching of third-party editor implementations. | ||
*/ | ||
export interface CodeEditorFactory { | ||
(options: CodeEditorOptions): CodeEditor; | ||
} | ||
|
||
export interface CodeEditorOptions { | ||
readonly editorContainerElementId: string; | ||
readonly language: SupportedSyntaxLanguage; | ||
} | ||
|
||
export type SupportedSyntaxLanguage = 'batchfile' | 'shellscript'; | ||
|
||
export interface CodeEditor { | ||
destroy(): void; | ||
updateContent(code: string): void; | ||
scrollToLine(lineNumber: number): void; | ||
updateSize(): void; | ||
applyStyleToLineRange( | ||
startLineNumber: number, | ||
endLineNumber: number, | ||
className: string, | ||
): CodeEditorStyleHandle; | ||
} | ||
|
||
export interface CodeEditorStyleHandle { | ||
clearStyle(): void; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters