photoprism/photoprism

Frontend: Clear stale .v-field--focused on v-autocomplete after focus moves

Open

#5.556 geöffnet am 4. Mai 2026

Auf GitHub ansehen
 (0 Kommentare) (0 Reaktionen) (0 zugewiesene Personen)Go (39.670 Stars) (2.263 Forks)batch import
frontendhelp wantedlow-priorityux

Beschreibung

As a user editing photo metadata, I want only the v-autocomplete I am currently typing in to appear focused, so that the UI unambiguously indicates where my next interaction will land.

The .v-field--focused CSS class can linger on a v-autocomplete input after focus has moved to another input. document.activeElement is correct (only one input is actually focused), but Vuetify's internal isFocused flag — which drives the class — clears too late on the previously focused autocomplete, so both fields end up styled as focused at the same time.

Reproduce

  1. Open the photo edit dialog → Details tab in Chrome (or any browser).
  2. Click the Country autocomplete (do not pick anything — leave the menu open).
  3. Click the Time Zone autocomplete.
  4. Inspect both inputs in DevTools: both .v-field wrappers have the v-field--focused class even though document.activeElement is the Time Zone input only.

Background

Identified during the investigation of #5538. PhotoPrism is pinned to vuetify@3.12.2 because Vuetify 3.12.3 introduced a regression that closes long autocomplete menus on open (commit 3d33e2f, Vuetify upstream #22697). The lingering focus class is the inverse symptom of #22697: 3.12.2 is under-aggressive about clearing isFocused, while 3.12.3 over-corrected and broke menu opening.

Why it is currently invisible

  • In the photo edit dialog the affected fields are not on screen together at the moment the user notices a focused field — Country sits above Time Zone, attention follows the click.
  • The solo-filled variant we use renders the focused/unfocused states with very similar visuals, so the lingering class is hard to spot.
  • The actual interaction (typing, arrow keys, Enter) routes to the correct input because real DOM focus is right.

Why it could get worse

  • A future form layout with two v-autocomplete inputs side-by-side would expose the dual-focused styling immediately.
  • If we change the v-text-field / v-autocomplete theming to make .v-field--focused more distinct (e.g., colored border, glow), this becomes obvious.
  • Users with custom or high-contrast themes may already see it.

Technical considerations

  • CSS-only fix: scope the .v-field--focused rule with :has(:focus-within) so the class only paints when the field actually contains a focused element. Browser support: Chrome 105+, Safari 15.4+, Firefox 121+ — within our stated baseline.
  • JS fix: v-autocomplete exposes isFocused via forwardRefs (see node_modules/vuetify/lib/components/VAutocomplete/VAutocomplete.js). A small composable could listen on @update:focused from each autocomplete and force-clear the ref when document.activeElement is no longer inside the input. More invasive than CSS.
  • Wait for migration: likely fixed naturally when PhotoPrism moves off the vuetify@3.12.2 pin (a future fixed v3.12.x patch or v4). Re-test then.

Whichever fix is chosen, it MUST NOT re-introduce #5538 — verify Country and Time Zone menus still open and stay open in Chrome.

Acceptance Criteria

  • SHOULD reproduce the dual .v-field--focused state in DevTools using the steps above.
  • SHOULD pick one of the three approaches above (CSS scoping, JS wrapper, or defer to Vuetify upgrade) with a short rationale.
  • SHOULD verify the fix does not re-introduce #5538 (Country and Time Zone menus must stay open on click in Chrome).
  • MAY add a Vitest regression that asserts only one v-autocomplete has the v-field--focused class after a Country → Time Zone click sequence.

References

  • #5538 (the regression that motivated the vuetify@3.12.2 pin)
  • Vuetify upstream #22697 (the bug 3.12.3 was trying to fix)
  • frontend/package.json //vuetify annotation (records the pin and this caveat)
  • frontend/CODEMAP.md "Runtime & Plugins" section (Vuetify pin notes)

Contributor Guide