feat(settings): search settings from the header and the command palette

The header search on the Settings page was shown but disabled. It now
searches a shared index of all 56 settings rows by translated title,
description and English synonyms, replaces the section page with ranked
results, and opens a result by scrolling to, focusing and briefly
highlighting its row. Enter opens the best match, and the section
navigation shows per-section match counts.

The command palette gains a "Settings" group that lists the best six
matches for a non-empty query, so any setting is one Ctrl/Cmd+K away.
Rows hidden by the current form state fall back to the control that
reveals them; rows the runtime cannot render are never returned.

The index ships through a new @iptvnator/workspace/shell/util/settings-search
sub-entrypoint so it stays out of the eager bundle, and a registry spec
keeps it in step with the section templates.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
4grayandClaude Opus 5.5 committed 2026-09-26 23:51:32 +02:00
1 parent 587e19541f
commit 3b3357713f
75 files changed
+3124 -311

No files matched your search

@@ -114,6 +114,56 @@
margin-bottom: 0;
}
// A row opened from settings search or the command palette. It receives
// programmatic focus (tabindex -1); the highlight is its focus indicator, so
// the default outline is dropped. The wash fills the row's own padding box
// and two offset shadows widen it past the flush-left row edges without
// shifting layout or painting over the separators above and below.
.setting-item[data-setting-id] {
scroll-margin: 96px 0 calc(96px + var(--settings-action-bar-space));
&:focus {
outline: none;
}
}
.setting-item--revealed {
--settings-reveal-wash: color-mix(
in srgb,
var(--app-selection-color) 12%,
transparent
);
background: var(--settings-reveal-wash);
box-shadow:
-12px 0 0 var(--settings-reveal-wash),
12px 0 0 var(--settings-reveal-wash);
animation: settings-reveal-fade 2.4s ease-out forwards;
}
@keyframes settings-reveal-fade {
0%,
60% {
background: var(--settings-reveal-wash);
box-shadow:
-12px 0 0 var(--settings-reveal-wash),
12px 0 0 var(--settings-reveal-wash);
}
100% {
background: transparent;
box-shadow:
-12px 0 0 transparent,
12px 0 0 transparent;
}
}
@media (prefers-reduced-motion: reduce) {
.setting-item--revealed {
animation: none;
}
}
.setting-item__meta {
h4 {
margin: 0;