Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .Jules/palette.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 2026-06-27 - No Custom CSS Classes Allowed for UI State
**Learning:** When making UX improvements (like disabled button states), adding new custom classes (e.g., `.btn-disabled`) violates the design constraints. Native pseudo-classes (`:disabled`) and combining selectors (`:not(:disabled)`) must be used instead to leverage standard browser behavior without expanding the design system.
**Action:** Use native HTML state attributes (like `disabled="true"`) and corresponding CSS pseudo-classes to manage visual state instead of creating new utility classes.
9 changes: 7 additions & 2 deletions src/main/resources/static/assets/viewer/viewer.css
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ a:hover {
color: #ffffff;
}

.btn-primary:hover {
.btn-primary:hover:not(:disabled) {
filter: brightness(0.95);
}

Expand All @@ -205,10 +205,15 @@ a:hover {
color: var(--ink);
}

.btn-secondary:hover {
.btn-secondary:hover:not(:disabled) {
background: #fbfcfe;
}

.btn:disabled {
opacity: 0.6;
cursor: not-allowed;
}

.preview {
border-radius: 12px;
border: 1px dashed rgba(16, 32, 50, 0.26);
Expand Down
5 changes: 5 additions & 0 deletions src/main/resources/static/assets/viewer/viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ function setLoading(message) {
el.error.hidden = true;
el.liveStatus.textContent = message;
el.preview.setAttribute("aria-busy", "true");
el.retryBtn.disabled = true;
}

function showError(message) {
Expand All @@ -53,6 +54,7 @@ function showError(message) {
el.liveStatus.textContent = "";
el.preview.setAttribute("aria-busy", "false");
el.errorTitle.focus();
el.retryBtn.disabled = false;
}

function clearPreview() {
Expand All @@ -73,6 +75,8 @@ function renderPreviewLink(path) {
link.textContent = "Open artifact";
link.className = "btn btn-secondary";
link.rel = "noopener";
link.target = "_blank";
link.setAttribute("aria-label", "Open artifact in a new tab");
el.preview.appendChild(link);
}

Expand Down Expand Up @@ -156,6 +160,7 @@ async function poll(docId, abortSignal) {

el.preview.setAttribute("aria-busy", "false");
el.liveStatus.textContent = "Ready.";
el.retryBtn.disabled = false;

clearPreview();
const path = bootstrap.data.previewResourcePath;
Expand Down
Loading