What I’m trying to do is create a code editor with a user interface similar to vscode. I used split.js to scale between the editor (codemirror editor inside tabs) and sidebars.
The problem is that when a number of lines or characters are entered, instead of the scroller appearing, the editor expands and its container expands with it beyond the size limits.
I am almost a beginner, so perhaps the problem is in the layout and I did not notice it.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My IDE</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/codemirror.min.css">
<!-- Custom CSS -->
<link rel="stylesheet" href="styles/styles.css">
</head>
<body>
<div class="main-container">
<!-- Title bar -->
<div class="title-bar">
<!-- Menus -->
<div class="menus">
<div class="menu-item">File</div>
<div class="menu-item">Edit</div>
<div class="menu-item">Selection</div>
<div class="menu-item">View</div>
<div class="menu-item">Go</div>
<div class="menu-item">Run</div>
<div class="menu-item">Terminal</div>
<div class="menu-item">Help</div>
</div>
<!-- Title -->
<div class="title">Title</div>
<!-- Window control buttons -->
<div class="window-controls">
<button class="minimize">-</button>
<button class="restore">+</button>
<button class="close">X</button>
</div>
</div>
<!-- Secondary container -->
<div class="secondary-container">
<!-- Activity bar items -->
<div class="activity-bar">
<div class="activity-bar-items">
<div class="activity-bar-item active" id="explorer">Explorer</div>
<div class="activity-bar-item" id="search">Search</div>
<div class="activity-bar-item" id="source-control">Source Control</div>
<div class="activity-bar-item" id="debug">Debug</div>
<div class="activity-bar-item" id="extensions">Extensions</div>
</div>
</div>
<!-- Split container -->
<div class="split-container">
<!-- Sidebar -->
<div class="sidebar">Sidebar</div>
<!-- Editor -->
<div class="editor"></div>
<!-- Secondary sidebar -->
<div class="secondary-sidebar">Secondary Sidebar</div>
</div>
</div>
<!-- Status bar -->
<div class="status-bar">Status Bar</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/codemirror.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/mode/javascript/javascript.min.js"></script>
<script src="https://unpkg.com/split.js/dist/split.min.js"></script>
<script src="scripts/javascript/activity_bar/activity_bar.js"></script>
<script src="scripts/javascript/editor/editor.js"></script>
<script src="scripts/javascript/split_container/split_container.js"></script>
<script src="scripts/javascript/status_bar/status_bar.js"></script>
<script src="scripts/javascript/title_bar/title_bar.js"></script>
</body>
</html>
editor.js:
document.addEventListener("DOMContentLoaded", function () {
const editorContainer = document.querySelector(".editor");
const tabBar = document.createElement("div");
tabBar.className = "tab-bar";
const addTabButton = document.createElement("button");
addTabButton.className = "add-tab-button";
addTabButton.innerHTML = "+";
tabBar.appendChild(addTabButton);
editorContainer.appendChild(tabBar);
const editors = {};
let activeTabId = null;
let tabCounter = 0;
function createEditor() {
const editorElement = document.createElement("div");
editorElement.className = "code-editor";
const textarea = document.createElement("textarea");
textarea.className = "text-area";
editorElement.appendChild(textarea);
editorContainer.appendChild(editorElement);
const editor = CodeMirror.fromTextArea(textarea, {
lineNumbers: true,
mode: "javascript",
theme: "default",
lineWrapping: false, // Disable line wrapping
matchBrackets: true,
autoCloseBrackets: true,
});
return { editorElement, editor };
}
function createTab() {
const tabId = `tab-${tabCounter++}`;
const tabButton = document.createElement("button");
tabButton.className = "tab-button";
tabButton.dataset.tabId = tabId;
tabButton.innerHTML = `Tab ${tabCounter} <span class="close-tab">x</span>`;
tabBar.insertBefore(tabButton, addTabButton);
const { editorElement, editor } = createEditor();
editors[tabId] = { tabButton, editorElement, editor };
tabButton.addEventListener("click", () => switchTab(tabId));
tabButton.querySelector(".close-tab").addEventListener("click", (e) => {
e.stopPropagation();
closeTab(tabId);
});
switchTab(tabId);
}
function switchTab(tabId) {
if (activeTabId) {
const { tabButton, editorElement } = editors[activeTabId];
tabButton.classList.remove("active");
editorElement.style.display = "none";
}
const { tabButton, editorElement, editor } = editors[tabId];
tabButton.classList.add("active");
editorElement.style.display = "block";
editor.refresh();
activeTabId = tabId;
}
function closeTab(tabId) {
const { tabButton, editorElement } = editors[tabId];
tabButton.remove();
editorElement.remove();
delete editors[tabId];
if (activeTabId === tabId) {
const remainingTabIds = Object.keys(editors);
if (remainingTabIds.length > 0) {
switchTab(remainingTabIds[0]);
} else {
activeTabId = null;
}
}
}
addTabButton.addEventListener("click", createTab);
createTab(); // Open an initial tab
});
split_container.js:
document.addEventListener("DOMContentLoaded", function () {
// Initialize Split.js for the split container
Split(['.sidebar', '.editor', '.secondary-sidebar'], {
sizes: [20, 60, 20], // Initial sizes of each panel
minSize: 100, // Minimum size of each panel
gutterSize: 5, // Size of the draggable gutter
cursor: 'col-resize', // Cursor style when dragging
direction: 'horizontal' // Direction of the split
});
});
css:
/* default.css */
/* Set html and body to take full viewport height */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
/* Main container styles */
.main-container {
background-color: #220055ff;
display: flex;
flex-direction: column;
height: 100vh;
max-height: 100%;
max-width: 100%;
}
/* Title bar styles */
.title-bar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 10px;
background-color: #333;
color: white;
}
.title {
font-size: 18px;
}
.window-controls {
display: flex;
}
.window-controls button {
margin-left: 5px;
cursor: pointer;
}
/* Menus styles */
.menus {
display: flex;
}
.menu-item {
padding: 5px 10px;
cursor: pointer;
}
/* Secondary container styles */
.secondary-container {
display: flex;
flex: 1;
}
/* Activity bar styles */
.activity-bar {
background-color: #444;
color: white;
width: 70px;
display: flex;
flex-direction: column;
}
.activity-bar-items {
display: flex;
flex-direction: column;
}
.activity-bar-item {
padding: 10px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.activity-bar-item.active {
background-color: #007acc;
color: white;
}
/* Split container styles */
.split-container {
background-color: #00ffffff;
display: flex;
flex: 1;
}
/* Sidebar styles */
.sidebar {
width: 200px;
background-color: #eee;
padding: 10px;
}
/* Editor styles */
.editor {
background-color: #ff00ffff;
display: flex;
flex:1;
flex-direction: column;
overflow: hidden;
/*height: 100%;*/
/*max-height: 600px;*/ /* Adjust the maximum height as needed */
}
.code-editor {
max-width: 100%;
max-height: 100%;
height: 100%;
width: 100%;
}
.CodeMirror {
border: 1px solid #ccc;
font-family: 'Fira Code', monospace;
height: 100%;
width: 100%;
max-width: 100%;
max-height: 100%;
}
.tab-bar {
display: flex;
background-color: #ddd;
padding: 0.5rem;
border-bottom: 1px solid #ccc;
}
.tab-button {
background-color: #eee;
border: 1px solid #ccc;
margin-right: 0.5rem;
padding: 0.5rem;
cursor: pointer;
position: relative;
}
.tab-button.active {
background-color: #fff;
border-bottom: none;
padding-bottom: 1rem;
}
.tab-button .close-tab {
position: absolute;
right: 5px;
top: 5px;
cursor: pointer;
}
.add-tab-button {
background-color: #ccc;
border: 1px solid #bbb;
padding: 0.5rem;
cursor: pointer;
}
/* Secondary sidebar styles */
.secondary-sidebar {
width: 150px;
background-color: #ddd;
padding: 10px;
}
/* Status bar styles */
.status-bar {
padding: 5px 10px;
background-color: #333;
color: white;
}