fix(ui): address code review feedback for settings page

- Replace   with CSS spacing classes for accessibility
- Use |tojson filter for search index to prevent XSS
- Add IntersectionObserver cleanup via Alpine $cleanup
- Add sr-only setting key text for mobile screen readers
- Respect prefers-reduced-motion for smooth scrolling

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-03-02 18:13:41 +00:00
parent 6ff1da2496
commit b8bd049dff
+12 -6
View File
@@ -34,8 +34,8 @@
/* Search highlight */
.settings-match-highlight { background-color: #fef08a; border-radius: 2px; padding: 0 2px; }
html.dark .settings-match-highlight { background-color: #854d0e; }
/* Smooth scroll */
html { scroll-behavior: smooth; }
/* Smooth scroll respect reduced-motion preference (WCAG) */
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
/* No-results state */
.settings-no-results { text-align: center; padding: 3rem 1rem; color: #9ca3af; }
</style>
@@ -50,9 +50,9 @@
<h1 class="text-3xl font-bold mb-1">Application Settings</h1>
<p class="text-gray-500 text-sm">
Manage configuration. Priority: <span class="inline-flex items-center px-1.5 py-0.5 rounded text-xs font-medium bg-green-100 text-green-800">DB</span> &gt;
<span class="inline-flex items-center px-1.5 py-0.5 rounded text-xs font-medium bg-blue-100 text-blue-800">ENV</span> &gt;
<span class="inline-flex items-center px-1.5 py-0.5 rounded text-xs font-medium bg-gray-100 text-gray-800">DEFAULT</span>
&nbsp;·&nbsp; <span class="text-red-600">*</span> = restart required &nbsp;·&nbsp; <i class="fas fa-lock text-xs" aria-hidden="true"></i> = encrypted at rest
<span class="inline-flex items-center px-1.5 py-0.5 rounded text-xs font-medium bg-blue-100 text-blue-800 ml-1">ENV</span> &gt;
<span class="inline-flex items-center px-1.5 py-0.5 rounded text-xs font-medium bg-gray-100 text-gray-800 ml-1">DEFAULT</span>
<span class="mx-1.5">·</span> <span class="text-red-600">*</span> = restart required <span class="mx-1.5">·</span> <i class="fas fa-lock text-xs" aria-hidden="true"></i> = encrypted at rest
</p>
</div>
<div class="flex items-center gap-2 flex-shrink-0">
@@ -232,6 +232,7 @@
{{ setting.source_label }}
</span>
<code class="text-xs text-gray-400 hidden sm:inline">{{ setting.key }}</code>
<span class="sr-only sm:hidden">Key: {{ setting.key }}</span>
</div>
<p class="text-xs text-gray-500 mb-2">{{ setting.metadata.description }}</p>
@@ -463,7 +464,7 @@ function settingsApp() {
this.visibleSettings['{{ setting.key }}'] = true;
this.settingSearchIndex['{{ setting.key }}'] = {
category: '{{ category|e }}',
searchText: '{{ setting.key }} {{ setting.key.replace("_", " ") }} {{ setting.metadata.description|lower|replace("'", "\\'") }}'.toLowerCase()
searchText: {{ (setting.key ~ ' ' ~ setting.key.replace('_', ' ') ~ ' ' ~ setting.metadata.description)|lower|tojson }}
};
{% endfor %}
{% endfor %}
@@ -482,6 +483,11 @@ function settingsApp() {
}, { rootMargin: '-20% 0px -70% 0px' });
document.querySelectorAll('[data-category]').forEach(el => observer.observe(el));
// Clean up observer when component is destroyed
if (this.$cleanup) {
this.$cleanup(() => observer.disconnect());
}
});
},