ui: replace inline state styles with css classes

This commit is contained in:
a.tolmachev
2026-04-12 02:30:24 +03:00
parent b92350a6ac
commit 4d7b11ec96
8 changed files with 56 additions and 22 deletions
+5 -5
View File
@@ -2,18 +2,18 @@
## Current
### `feat/frontend-css-state-cleanup`
### `feat/frontend-performance-polish`
Status: in_progress
DoD:
- button and control state visuals move from inline `element.style` mutations into CSS classes
- wizard navigation and similar interactive UI use semantic state classes instead of manual style strings
- existing UI e2e coverage stays green after the CSS-state cleanup
- repeated O(n) filtering in hot render paths is removed
- tab counts and similar derived UI metrics use cached/derived snapshots instead of recomputing the same filters
- existing UI e2e coverage stays green after the performance polish
## Next
- `feat/frontend-performance-polish`
- `feat/frontend-observability-and-testability`
## Backlog
+13
View File
@@ -69,6 +69,19 @@
box-shadow: 0 0 0 3px var(--accent-ring);
}
.btn-primary:disabled,
.btn-primary.is-disabled {
opacity: 0.5;
cursor: not-allowed;
box-shadow: none;
}
.btn-primary:disabled:hover,
.btn-primary.is-disabled:hover {
background: var(--accent);
box-shadow: none;
}
.btn-secondary {
display: inline-flex;
align-items: center;
+25
View File
@@ -989,6 +989,17 @@
border-color: var(--bg-muted);
}
.btn-back:disabled {
opacity: 0.35;
cursor: not-allowed;
}
.btn-back:disabled:hover {
background: var(--bg-overlay);
color: var(--text-secondary);
border-color: var(--border);
}
.btn-save-draft {
background: none;
color: var(--text-muted);
@@ -1044,6 +1055,20 @@
box-shadow: 0 1px 4px rgba(13, 148, 136, 0.3);
}
.btn-continue.is-final-step {
background: #3fb950;
border-color: #2ea043;
box-shadow: 0 1px 4px rgba(63, 185, 80, 0.4);
}
.btn-continue.is-final-step:hover {
background: #2ea043;
border-color: transparent;
box-shadow:
0 2px 10px rgba(63, 185, 80, 0.45),
0 0 0 3px rgba(63, 185, 80, 0.18);
}
/* ── Code editor ── */
.code-block {
border: 1px solid var(--border);
+5
View File
@@ -203,6 +203,11 @@
gap: 10px;
margin-top: 24px;
}
.ws-submit-btn {
padding: 9px 22px;
font-size: 13px;
}
.ws-setup-footer-note {
font-size: 12px;
color: var(--text-muted);
+1 -1
View File
@@ -201,7 +201,7 @@
<div class="action-bar" role="toolbar" aria-label="Wizard navigation">
<div class="action-bar-inner">
<button class="btn btn-back" type="button" disabled style="opacity: 0.35; cursor: not-allowed;">
<button class="btn btn-back" type="button" disabled>
<svg width="13" height="13" viewBox="0 0 16 16" fill="currentColor">
<path d="M9.78 12.78a.75.75 0 01-1.06 0L4.47 8.53a.75.75 0 010-1.06l4.25-4.25a.75.75 0 011.06 1.06L6.06 8l3.72 3.72a.75.75 0 010 1.06z"/>
</svg>
+1 -1
View File
@@ -286,7 +286,7 @@
<!-- ── Actions ── -->
<div class="ws-setup-actions">
<a href="javascript:history.back()" class="btn-ghost-sm" style="padding:9px 18px;font-size:13px;text-decoration:none;color:var(--text-secondary);" data-i18n="btn.cancel">Cancel</a>
<button class="btn-primary" id="submit-btn" type="button" onclick="submitForm()" style="padding:9px 22px;font-size:13px;" data-i18n="workspace_setup.actions.save">Save changes</button>
<button class="btn-primary ws-submit-btn" id="submit-btn" type="button" onclick="submitForm()" data-i18n="workspace_setup.actions.save">Save changes</button>
</div>
<div class="ws-setup-footer-note" id="footer-note" style="display:none;">
+3 -11
View File
@@ -84,15 +84,7 @@
var backButton = document.querySelector('.btn-back');
if (backButton) {
if (step === 1) {
backButton.disabled = true;
backButton.style.opacity = '0.35';
backButton.style.cursor = 'not-allowed';
} else {
backButton.disabled = false;
backButton.style.opacity = '';
backButton.style.cursor = '';
}
backButton.disabled = step === 1;
}
var continueButton = document.querySelector('.btn-continue');
@@ -100,10 +92,10 @@
if (step === TOTAL_STEPS) {
var finalLabel = window.wizardMode === 'edit' ? tKey('wizard.button.save_changes') : tKey('wizard.button.create');
continueButton.innerHTML = finalLabel + ' ' + ARROW_SVG;
continueButton.style.cssText = 'background:#3fb950;border-color:#2ea043;box-shadow:0 1px 4px rgba(63,185,80,0.4);';
continueButton.classList.add('is-final-step');
} else {
continueButton.innerHTML = tKey('wizard.button.continue') + ' ' + ARROW_SVG;
continueButton.style.cssText = '';
continueButton.classList.remove('is-final-step');
}
}
+3 -4
View File
@@ -231,12 +231,12 @@ function updatePageMode() {
document.getElementById('footer-note').style.display = '';
submit.textContent = tKey('workspace_setup.actions.create');
submit.disabled = true;
submit.style.opacity = '0.5';
submit.style.cursor = 'not-allowed';
submit.classList.add('is-disabled');
} else {
document.getElementById('section-members').style.display = '';
document.getElementById('section-danger').style.display = '';
submit.textContent = tKey('workspace_setup.actions.save');
submit.classList.remove('is-disabled');
}
}
@@ -276,8 +276,7 @@ function validateCreateForm() {
var elements = formElements();
var valid = Boolean(elements.name.value.trim() && elements.slug.value.trim());
elements.submit.disabled = !valid;
elements.submit.style.opacity = valid ? '1' : '0.5';
elements.submit.style.cursor = valid ? 'pointer' : 'not-allowed';
elements.submit.classList.toggle('is-disabled', !valid);
}
function inviteRows() {