+ + + + +
@@ -1403,8 +1445,9 @@
+
- +
Ready Words: 0 | Characters: 0 diff --git a/src/renderer.js b/src/renderer.js index 39dfe77..4959a40 100644 --- a/src/renderer.js +++ b/src/renderer.js @@ -10,6 +10,7 @@ const DOMPurify = require('dompurify'); const hljs = require('highlight.js'); const { createEditor } = require('./editor/codemirror-setup'); const { undo, redo } = require('@codemirror/commands'); +const { SidebarManager } = require('./sidebar/sidebar-manager'); // Configure marked with highlight extension marked.use(markedHighlight({ @@ -1006,6 +1007,25 @@ let tabManager; document.addEventListener('DOMContentLoaded', () => { tabManager = new TabManager(); + // Initialize sidebar + const sidebarManager = new SidebarManager(); + sidebarManager.registerPanel('explorer', { + title: 'Explorer', + render: (container) => { container.innerHTML = '

File explorer coming soon...

'; } + }); + sidebarManager.registerPanel('git', { + title: 'Git', + render: (container) => { container.innerHTML = '

Git panel coming soon...

'; } + }); + sidebarManager.registerPanel('snippets', { + title: 'Snippets', + render: (container) => { container.innerHTML = '

Snippets coming soon...

'; } + }); + sidebarManager.registerPanel('templates', { + title: 'Templates', + render: (container) => { container.innerHTML = '

Templates coming soon...

'; } + }); + // Initialize CodeMirror for the initial tab (tab 1) const editorContainer = document.getElementById('editor-cm-1'); if (editorContainer) { diff --git a/src/sidebar/sidebar-manager.js b/src/sidebar/sidebar-manager.js new file mode 100644 index 0000000..237878e --- /dev/null +++ b/src/sidebar/sidebar-manager.js @@ -0,0 +1,50 @@ +class SidebarManager { + constructor() { + this.sidebar = document.getElementById('sidebar'); + this.panelContent = document.getElementById('sidebar-panel-content'); + this.panelTitle = document.querySelector('.sidebar-panel-title'); + this.activePanel = null; + this.panels = new Map(); + this.setupEventListeners(); + } + + setupEventListeners() { + document.querySelectorAll('.sidebar-icon').forEach(btn => { + btn.addEventListener('click', () => this.togglePanel(btn.dataset.panel)); + }); + document.querySelector('.sidebar-panel-close')?.addEventListener('click', () => this.collapse()); + } + + registerPanel(name, { title, render }) { + this.panels.set(name, { title, render }); + } + + togglePanel(name) { + if (this.activePanel === name) { + this.collapse(); + } else { + this.expand(name); + } + } + + expand(name) { + const panel = this.panels.get(name); + if (!panel) return; + this.sidebar.classList.remove('collapsed'); + this.panelTitle.textContent = panel.title; + this.panelContent.innerHTML = ''; + panel.render(this.panelContent); + this.activePanel = name; + document.querySelectorAll('.sidebar-icon').forEach(btn => { + btn.classList.toggle('active', btn.dataset.panel === name); + }); + } + + collapse() { + this.sidebar.classList.add('collapsed'); + this.activePanel = null; + document.querySelectorAll('.sidebar-icon').forEach(btn => btn.classList.remove('active')); + } +} + +module.exports = { SidebarManager }; diff --git a/src/styles-sidebar.css b/src/styles-sidebar.css new file mode 100644 index 0000000..533fbdd --- /dev/null +++ b/src/styles-sidebar.css @@ -0,0 +1,132 @@ +/* Sidebar */ +.main-content { + display: flex; + flex: 1; + overflow: hidden; + min-height: 0; +} + +.sidebar { + display: flex; + flex-shrink: 0; + height: 100%; + transition: width 0.2s ease; +} + +.sidebar.collapsed { + width: 48px; +} + +.sidebar:not(.collapsed) { + width: 328px; /* 48px icons + 280px panel */ +} + +.sidebar-icons { + display: flex; + flex-direction: column; + width: 48px; + background: var(--gray-100, #f3f4f6); + border-right: 1px solid var(--gray-200, #e5e7eb); + padding: 8px 0; + gap: 4px; + align-items: center; +} + +.sidebar-icon { + width: 36px; + height: 36px; + display: flex; + align-items: center; + justify-content: center; + border: none; + background: transparent; + border-radius: 8px; + cursor: pointer; + color: var(--gray-500, #6b7280); + transition: all 0.15s ease; +} + +.sidebar-icon:hover { + background: var(--gray-200, #e5e7eb); + color: var(--gray-700, #374151); +} + +.sidebar-icon.active { + background: var(--gray-200, #e5e7eb); + color: var(--primary-dark, #5661b3); + box-shadow: inset 3px 0 0 var(--primary-dark, #5661b3); +} + +.sidebar-panel { + width: 280px; + background: var(--gray-50, #f9fafb); + border-right: 1px solid var(--gray-200, #e5e7eb); + display: flex; + flex-direction: column; + overflow: hidden; +} + +.sidebar.collapsed .sidebar-panel { + display: none; +} + +.sidebar-panel-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 12px 16px; + border-bottom: 1px solid var(--gray-200, #e5e7eb); + font-weight: 600; + font-size: 13px; + text-transform: uppercase; + letter-spacing: 0.05em; + color: var(--gray-600, #4b5563); +} + +.sidebar-panel-close { + background: none; + border: none; + font-size: 18px; + cursor: pointer; + color: var(--gray-400, #9ca3af); + padding: 0 4px; + border-radius: 4px; +} + +.sidebar-panel-close:hover { + background: var(--gray-200, #e5e7eb); + color: var(--gray-600, #4b5563); +} + +.sidebar-panel-content { + flex: 1; + overflow-y: auto; + padding: 12px; +} + +/* Dark theme support */ +body[class*="dark"] .sidebar-icons, +body[class*="dark"] .sidebar-panel { + background: #1e1e1e; + border-color: #333; +} + +body[class*="dark"] .sidebar-icon { + color: #888; +} + +body[class*="dark"] .sidebar-icon:hover { + background: #333; + color: #ccc; +} + +body[class*="dark"] .sidebar-icon.active { + background: #333; + color: #8b9aff; + box-shadow: inset 3px 0 0 #8b9aff; +} + +body[class*="dark"] .sidebar-panel-header { + border-color: #333; + color: #ccc; +}