diff --git a/index.html b/index.html index d6904b7..17ae609 100644 --- a/index.html +++ b/index.html @@ -80,7 +80,12 @@ 0 0 20px 5px rgba(34, 197, 94, .3), 0 0 50px 10px rgba(34, 197, 94, .12); } - #card-text { margin: 0 0 .9rem; } + #card-text { + margin: 0 0 .4rem; cursor: text; + border-bottom: 1px dashed transparent; transition: border-color .15s; + } + #card-text:hover { border-bottom-color: var(--border); } + #card-dblclick-hint { color: var(--meta); font-size: .68rem; margin-bottom: .7rem; } #card-meta { color: var(--meta); font-size: .72rem; margin-bottom: .7rem; min-height: 1rem; } .card-actions { display: flex; gap: .5rem; justify-content: flex-end; } .card-btn { @@ -98,15 +103,14 @@ .card-btn:disabled { opacity: .4; cursor: default; } .card-btn-danger { color: #f57c7c; border-color: rgba(245,124,124,.3); } .card-btn-danger:hover { background: rgba(245,124,124,.1); } - #edit-form { display: none; flex-direction: column; gap: .6rem; margin-top: .5rem; } - #edit-form.open { display: flex; } + #edit-wrap { display: none; flex-direction: column; gap: .5rem; margin-bottom: .4rem; } + #edit-wrap.open { display: flex; } #edit-input { - width: 100%; min-height: 90px; background: var(--input-bg); color: var(--fg); - border: 1px solid var(--border); border-radius: 8px; padding: .55rem .7rem; - font-family: inherit; font-size: .9rem; resize: vertical; outline: none; - transition: border-color .15s; + width: 100%; min-height: 80px; background: var(--input-bg); color: var(--fg); + border: 1px solid var(--accent); border-radius: 8px; padding: .55rem .7rem; + font-family: inherit; font-size: inherit; line-height: 1.6; resize: vertical; outline: none; } - #edit-input:focus { border-color: var(--accent); } + .edit-hint { font-size: .72rem; color: var(--meta); } #card-status { font-size: .75rem; color: var(--meta); min-height: 1rem; text-align: right; } @@ -116,18 +120,14 @@

Loading…

-
-
- - -
-
+
-
- - - -
+ Ctrl+Enter to save · Esc to cancel +
+
+
+ +
@@ -153,15 +153,13 @@ // ── CRUD card ────────────────────────────────────────────────────────── (function() { var BASE = '/test'; - var textEl = document.getElementById('card-text'); - var metaEl = document.getElementById('card-meta'); - var editForm = document.getElementById('edit-form'); + var textEl = document.getElementById('card-text'); + var editWrap = document.getElementById('edit-wrap'); var editInput = document.getElementById('edit-input'); - var statusEl = document.getElementById('card-status'); - var editBtn = document.getElementById('edit-btn'); - var saveBtn = document.getElementById('save-btn'); - var cancelBtn = document.getElementById('cancel-btn'); - var resetBtn = document.getElementById('reset-btn'); + var metaEl = document.getElementById('card-meta'); + var statusEl = document.getElementById('card-status'); + var resetBtn = document.getElementById('reset-btn'); + var editing = false; function setMeta(updated_at) { metaEl.textContent = updated_at @@ -179,52 +177,58 @@ function load() { fetch(BASE + '/api/text') .then(function(r) { return r.json(); }) - .then(function(d) { - textEl.textContent = d.content || ''; - setMeta(d.updated_at); - }) + .then(function(d) { textEl.textContent = d.content || ''; setMeta(d.updated_at); }) .catch(function() { textEl.textContent = '(failed to load)'; }); } load(); - // Edit mode toggle - editBtn.addEventListener('click', function() { + // Enter edit mode on double-click + textEl.addEventListener('dblclick', function() { + if (editing) return; + editing = true; editInput.value = textEl.textContent; - editForm.classList.add('open'); - editBtn.style.display = 'none'; - resetBtn.style.display = 'none'; + textEl.style.display = 'none'; + editWrap.classList.add('open'); + // Auto-size textarea to content + editInput.style.height = 'auto'; + editInput.style.height = editInput.scrollHeight + 'px'; editInput.focus(); + editInput.select(); }); - cancelBtn.addEventListener('click', function() { - editForm.classList.remove('open'); - editBtn.style.display = ''; - resetBtn.style.display = ''; + // Cancel on Escape, save on Ctrl+Enter + editInput.addEventListener('keydown', function(e) { + if (e.key === 'Escape') { cancelEdit(); } + if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') { e.preventDefault(); saveEdit(); } }); + function cancelEdit() { + editing = false; + editWrap.classList.remove('open'); + textEl.style.display = ''; + } + // UPDATE - saveBtn.addEventListener('click', function() { + function saveEdit() { var content = editInput.value.trim(); if (!content) { setStatus('Cannot be empty.', '#f57c7c'); return; } - saveBtn.disabled = true; + setStatus('Saving…', ''); fetch(BASE + '/api/text', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ content: content }) }).then(function(r) { return r.json(); }).then(function(d) { - if (d.error) { setStatus('Error: ' + d.error, '#f57c7c'); saveBtn.disabled = false; return; } + if (d.error) { setStatus('Error: ' + d.error, '#f57c7c'); return; } textEl.textContent = d.content; setMeta(d.updated_at); - editForm.classList.remove('open'); - editBtn.style.display = ''; - resetBtn.style.display = ''; - setStatus('Saved!', '#6fcf6f'); - saveBtn.disabled = false; - }).catch(function() { setStatus('Network error.', '#f57c7c'); saveBtn.disabled = false; }); - }); + setStatus('Saved ✓', '#6fcf6f'); + cancelEdit(); + }).catch(function() { setStatus('Network error.', '#f57c7c'); }); + } // DELETE (reset) resetBtn.addEventListener('click', function() { + if (editing) cancelEdit(); if (!confirm('Reset to default text?')) return; resetBtn.disabled = true; fetch(BASE + '/api/text', { method: 'DELETE' }) @@ -232,7 +236,7 @@ .then(function(d) { textEl.textContent = d.content; setMeta(d.updated_at); - setStatus('Reset!', '#6fcf6f'); + setStatus('Reset ✓', '#6fcf6f'); resetBtn.disabled = false; }).catch(function() { setStatus('Network error.', '#f57c7c'); resetBtn.disabled = false; }); });