Start typing to see the preview...
@@ -167,6 +178,83 @@
justify-content: space-between;
align-items: center;
margin-bottom: 2rem;
+ position: relative;
+}
+
+.editor-actions {
+ display: flex;
+ align-items: center;
+ gap: 1rem;
+}
+
+.btn-icon {
+ width: 40px;
+ height: 40px;
+ border: 1px solid #dee2e6;
+ background: white;
+ border-radius: 6px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: all 0.2s ease;
+ padding: 0;
+}
+
+.btn-icon:hover {
+ background: #f8f9fa;
+ border-color: #adb5bd;
+}
+
+.btn-icon:active {
+ background: #e9ecef;
+}
+
+.btn-icon svg {
+ color: #666;
+}
+
+.settings-dropdown {
+ position: fixed;
+ width: 320px;
+ background: white;
+ border: 1px solid #dee2e6;
+ border-radius: 8px;
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15);
+ z-index: 1000;
+ display: none;
+ max-height: 80vh;
+ overflow-y: auto;
+}
+
+.settings-dropdown.show {
+ display: block;
+}
+
+.settings-content {
+ padding: 1.5rem;
+}
+
+.settings-content h3 {
+ margin: 0 0 1.5rem 0;
+ font-size: 1.1rem;
+ color: #333;
+}
+
+.settings-group {
+ margin-bottom: 1.25rem;
+}
+
+.settings-group:last-child {
+ margin-bottom: 0;
+}
+
+.settings-group label {
+ display: block;
+ margin-bottom: 0.5rem;
+ font-weight: 500;
+ color: #555;
+ font-size: 0.9rem;
}
.editor-layout {
@@ -174,6 +262,11 @@
grid-template-columns: 1fr 1fr;
gap: 2rem;
min-height: 600px;
+ transition: grid-template-columns 0.3s ease;
+}
+
+.editor-layout.preview-collapsed {
+ grid-template-columns: 1fr 60px;
}
.editor-panel, .preview-panel {
@@ -185,12 +278,68 @@
.preview-panel {
background: #f8f9fa;
+ position: relative;
+ overflow: hidden;
+ transition: all 0.3s ease;
}
-.preview-panel h3 {
- margin-top: 0;
+.preview-panel.collapsed {
+ cursor: pointer;
+}
+
+.preview-panel.collapsed .markdown-content {
+ display: none;
+}
+
+.preview-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
margin-bottom: 1rem;
+}
+
+.preview-header h3 {
+ margin: 0;
color: #666;
+ transition: transform 0.3s ease;
+}
+
+.preview-panel.collapsed .preview-header {
+ font-size: small;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%) rotate(-90deg);
+ width: max-content;
+}
+
+.preview-panel.collapsed .preview-header h3 {
+ margin: 0;
+}
+
+.collapse-btn {
+ transition: transform 0.3s ease;
+ z-index: 10;
+ position: relative;
+}
+
+.preview-panel.collapsed .collapse-btn {
+ display: none;
+}
+
+.collapse-icon {
+ font-size: 16px;
+ font-weight: normal;
+ font-family: monospace;
+ display: inline-block;
+ transition: transform 0.3s ease;
+ line-height: 1;
+ letter-spacing: -2px;
+ color: #666;
+}
+
+.editor-layout.preview-collapsed .collapse-icon {
+ transform: rotate(180deg);
}
.form-row {
@@ -416,21 +565,49 @@
font-style: italic;
}
+/* Form elements inside settings dropdown */
+.settings-dropdown .form-control {
+ font-size: 0.9rem;
+ padding: 0.5rem 0.75rem;
+}
+
/* Responsive design */
@media (max-width: 1024px) {
.editor-layout {
grid-template-columns: 1fr;
}
+ .editor-layout.preview-collapsed {
+ grid-template-columns: 1fr;
+ }
+
.preview-panel {
order: -1;
min-height: 300px;
max-height: 400px;
}
+ .preview-panel.collapsed {
+ min-height: 60px;
+ max-height: 60px;
+ }
+
+ .preview-panel.collapsed .preview-header {
+ position: static;
+ transform: none;
+ }
+
+ .preview-panel.collapsed .collapse-btn {
+ display: flex;
+ }
+
.form-row {
grid-template-columns: 1fr;
}
+
+ .settings-dropdown {
+ width: 300px;
+ }
}
@@ -476,12 +653,43 @@ function insertMarkdown(before, after) {
syncContentAndUpdatePreview();
}
+// Extract title from first line of content
+function extractTitleFromContent(content) {
+ const lines = content.split('\n');
+ let firstLine = '';
+
+ // Find the first non-empty line
+ for (let line of lines) {
+ const trimmed = line.trim();
+ if (trimmed) {
+ // Remove markdown headers if present
+ firstLine = trimmed.replace(/^#+\s*/, '');
+ break;
+ }
+ }
+
+ // If no non-empty line found, use default
+ return firstLine || 'Untitled Note';
+}
+
// Sync Ace Editor content with hidden textarea and update preview
function syncContentAndUpdatePreview() {
if (!aceEditor) return;
const content = aceEditor.getValue();
document.getElementById('content').value = content;
+
+ // Update title from first line
+ const title = extractTitleFromContent(content);
+ document.getElementById('title').value = title;
+
+ // Update the page header to show current title
+ const headerTitle = document.querySelector('.editor-header h2');
+ if (headerTitle) {
+ const isEdit = headerTitle.textContent.includes('Edit');
+ headerTitle.textContent = title ? (isEdit ? `Edit: ${title}` : title) : (isEdit ? 'Edit Note' : 'Create Note');
+ }
+
updatePreview();
}
@@ -549,6 +757,12 @@ function initializeAceEditor() {
const initialContent = document.getElementById('content').value;
aceEditor.setValue(initialContent, -1); // -1 moves cursor to start
+ // If editing and has content, extract title
+ if (initialContent) {
+ const title = extractTitleFromContent(initialContent);
+ document.getElementById('title').value = title;
+ }
+
// Listen for changes in Ace Editor
aceEditor.on('change', function() {
syncContentAndUpdatePreview();
@@ -562,8 +776,8 @@ function initializeAceEditor() {
submitBtn.textContent = 'Saving...';
});
- // Set focus to title field initially
- document.getElementById('title').focus();
+ // Set focus to ace editor
+ aceEditor.focus();
}
// Initialize when DOM is ready
@@ -594,6 +808,106 @@ document.addEventListener('DOMContentLoaded', function() {
exec: function() { insertMarkdown('[', '](url)'); }
});
}
+
+ // Settings dropdown toggle
+ const settingsBtn = document.getElementById('settings-toggle');
+ const settingsDropdown = document.getElementById('settings-dropdown');
+
+ function positionDropdown() {
+ const btnRect = settingsBtn.getBoundingClientRect();
+ const dropdownWidth = 320;
+ const dropdownHeight = settingsDropdown.offsetHeight;
+ const viewportWidth = window.innerWidth;
+ const viewportHeight = window.innerHeight;
+
+ // Calculate position
+ let left = btnRect.right - dropdownWidth;
+ let top = btnRect.bottom + 8;
+
+ // Adjust if it goes off the right edge
+ if (left + dropdownWidth > viewportWidth - 20) {
+ left = viewportWidth - dropdownWidth - 20;
+ }
+
+ // Adjust if it goes off the left edge
+ if (left < 20) {
+ left = 20;
+ }
+
+ // Adjust if it goes off the bottom
+ if (top + dropdownHeight > viewportHeight - 20) {
+ // Show above the button instead
+ top = btnRect.top - dropdownHeight - 8;
+ }
+
+ settingsDropdown.style.left = left + 'px';
+ settingsDropdown.style.top = top + 'px';
+ }
+
+ settingsBtn.addEventListener('click', function(e) {
+ e.stopPropagation();
+ const isShowing = settingsDropdown.classList.contains('show');
+
+ if (!isShowing) {
+ settingsDropdown.classList.add('show');
+ // Position after showing to get correct dimensions
+ positionDropdown();
+ } else {
+ settingsDropdown.classList.remove('show');
+ }
+ });
+
+ // Reposition on window resize
+ window.addEventListener('resize', function() {
+ if (settingsDropdown.classList.contains('show')) {
+ positionDropdown();
+ }
+ });
+
+ // Close settings dropdown when clicking outside
+ document.addEventListener('click', function(e) {
+ if (!settingsDropdown.contains(e.target) && !settingsBtn.contains(e.target)) {
+ settingsDropdown.classList.remove('show');
+ }
+ });
+
+ // Prevent dropdown from closing when clicking inside
+ settingsDropdown.addEventListener('click', function(e) {
+ e.stopPropagation();
+ });
+
+ // Preview panel collapse/expand
+ const previewToggle = document.getElementById('preview-toggle');
+ const previewPanel = document.getElementById('preview-panel');
+ const editorLayout = document.querySelector('.editor-layout');
+
+ previewToggle.addEventListener('click', function(e) {
+ e.stopPropagation(); // Prevent event bubbling
+ previewPanel.classList.toggle('collapsed');
+ editorLayout.classList.toggle('preview-collapsed');
+
+ // Resize Ace Editor after animation
+ setTimeout(function() {
+ if (aceEditor) {
+ aceEditor.resize();
+ }
+ }, 300);
+ });
+
+ // Click on collapsed preview to expand
+ previewPanel.addEventListener('click', function(e) {
+ if (this.classList.contains('collapsed')) {
+ this.classList.remove('collapsed');
+ editorLayout.classList.remove('preview-collapsed');
+
+ // Resize Ace Editor after animation
+ setTimeout(function() {
+ if (aceEditor) {
+ aceEditor.resize();
+ }
+ }, 300);
+ }
+ });
});