fix: description unreadable in dark mode / OLED — swap disabled textarea for lt-markdown div
Root cause: disabled textarea gets opacity:0.45 + color:var(--text-muted) from base.css, making it near-invisible on OLED (true-black background). Fix: - TicketView: add #ticketDescriptionView (div.lt-markdown) alongside the textarea; textarea is now hidden by default (style="display:none"), view div is shown - ticket.js: renderDescriptionView() renders raw text via parseMarkdown() or nl2br; showDescriptionView() / showDescriptionEdit() swap between them; toggleEditMode() calls showDescriptionEdit() when entering edit, and renderDescriptionView() + showDescriptionView() when returning to read mode - ticket.css: .ticket-description-view sets full-contrast text-primary/secondary colors, min-height, and line-height for comfortable reading Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -269,3 +269,18 @@ kbd {
|
||||
.thread-depth-2 { margin-left: 1.5rem; }
|
||||
.thread-depth-3 { margin-left: 2.25rem; }
|
||||
}
|
||||
|
||||
/* ── Description read view ───────────────────────────────────── */
|
||||
/* Shown in read mode instead of a disabled (faded) textarea. */
|
||||
/* Uses lt-markdown typography for full contrast on dark/OLED. */
|
||||
.ticket-description-view {
|
||||
min-height: 8rem;
|
||||
padding: 0.5rem 0.25rem;
|
||||
line-height: 1.75;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.ticket-description-view p {
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 0.6rem;
|
||||
}
|
||||
.ticket-description-view p:last-child { margin-bottom: 0; }
|
||||
|
||||
+41
-2
@@ -77,6 +77,38 @@ function saveTicket() {
|
||||
});
|
||||
}
|
||||
|
||||
// ── Description read/edit helpers ────────────────────────────────────────────
|
||||
// Read mode: styled lt-markdown div (full contrast, even on OLED).
|
||||
// Edit mode: raw textarea (enabled for editing).
|
||||
|
||||
function renderDescriptionView() {
|
||||
var viewDiv = document.getElementById('ticketDescriptionView');
|
||||
var textarea = document.querySelector('textarea[data-field="description"]');
|
||||
if (!viewDiv || !textarea) return;
|
||||
var raw = textarea.value || '';
|
||||
if (!raw.trim()) {
|
||||
viewDiv.innerHTML = '<p class="lt-text-muted lt-text-sm"><em>No description provided.</em></p>';
|
||||
} else if (typeof parseMarkdown === 'function') {
|
||||
viewDiv.innerHTML = parseMarkdown(raw);
|
||||
} else {
|
||||
viewDiv.innerHTML = lt.escHtml(raw).replace(/\n/g, '<br>');
|
||||
}
|
||||
}
|
||||
|
||||
function showDescriptionView() {
|
||||
var v = document.getElementById('ticketDescriptionView');
|
||||
var t = document.querySelector('textarea[data-field="description"]');
|
||||
if (v) v.style.display = '';
|
||||
if (t) t.style.display = 'none';
|
||||
}
|
||||
|
||||
function showDescriptionEdit() {
|
||||
var v = document.getElementById('ticketDescriptionView');
|
||||
var t = document.querySelector('textarea[data-field="description"]');
|
||||
if (v) v.style.display = 'none';
|
||||
if (t) t.style.display = '';
|
||||
}
|
||||
|
||||
function toggleEditMode() {
|
||||
const editButton = document.getElementById('editButton');
|
||||
const titleField = document.querySelector('.title-input');
|
||||
@@ -94,8 +126,9 @@ function toggleEditMode() {
|
||||
titleField.focus();
|
||||
}
|
||||
|
||||
// Enable description (textarea)
|
||||
// Enable description (swap to textarea)
|
||||
if (descriptionField) {
|
||||
showDescriptionEdit();
|
||||
descriptionField.disabled = false;
|
||||
descriptionField.style.height = 'auto';
|
||||
descriptionField.style.height = descriptionField.scrollHeight + 'px';
|
||||
@@ -115,9 +148,11 @@ function toggleEditMode() {
|
||||
titleField.setAttribute('contenteditable', 'false');
|
||||
}
|
||||
|
||||
// Disable description
|
||||
// Disable description — re-render view div with latest content
|
||||
if (descriptionField) {
|
||||
descriptionField.disabled = true;
|
||||
renderDescriptionView();
|
||||
showDescriptionView();
|
||||
}
|
||||
|
||||
// Disable metadata fields
|
||||
@@ -259,6 +294,10 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
// Show description tab by default
|
||||
showTab('description');
|
||||
|
||||
// Populate and show description view div on page load
|
||||
renderDescriptionView();
|
||||
showDescriptionView();
|
||||
|
||||
// Auto-resize function for textareas
|
||||
function autoResizeTextarea(textarea) {
|
||||
// Reset height to auto to get the correct scrollHeight
|
||||
|
||||
@@ -320,12 +320,18 @@ include __DIR__ . '/layout_header.php';
|
||||
<div class="lt-section-body">
|
||||
<div class="lt-form-group">
|
||||
<label class="lt-sr-only lt-label" for="ticketDescription">Description</label>
|
||||
<!-- Read view: shown when not editing — uses lt-markdown for readable typography -->
|
||||
<div id="ticketDescriptionView"
|
||||
class="lt-markdown ticket-description-view"
|
||||
aria-label="Ticket description"></div>
|
||||
<!-- Edit view: shown only when editing -->
|
||||
<textarea id="ticketDescription"
|
||||
class="lt-input lt-textarea editable"
|
||||
data-field="description"
|
||||
disabled
|
||||
rows="18"
|
||||
aria-label="Ticket description"><?= htmlspecialchars($ticket['description'] ?? '') ?></textarea>
|
||||
style="display:none"
|
||||
aria-label="Ticket description (edit)"><?= htmlspecialchars($ticket['description'] ?? '') ?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user