Skip to content

refactor: apparat popover - #299

Open
domsteinbach wants to merge 1 commit into
mainfrom
aparat-popover
Open

refactor: apparat popover#299
domsteinbach wants to merge 1 commit into
mainfrom
aparat-popover

Conversation

@domsteinbach

Copy link
Copy Markdown
Collaborator

This PR fixes some bugs, adjusts the positioning of the popover and gets rid of a warning.

A) fixes:

  1. click on an apparat anchor (verse number) does keep the popover open (correctly so), but
  • a click on a second anchor does destroy/replace the first popover.
  • hovering over other anchors does not trigger popovers anymore.

Pinning a popover does not make sense when we can not pin several popovers at once by click or deactivating other popovers.

How it should be instead:

  • clicking a popover does pin it. All other anchors/popovers are still active and working no difference in behaviour
  • closing a pinned popover does only close the one and keep other pinned popovers open.
  1. The unpinned popovers which are triggered by hover have a certain delay at unhover and closing (which is correct and needed). It has the effect that hovering over several popovers one after each otherdoes not destroy the already active popover, it does simply replace its content. As a result the popover stays at the first popovers position.

How it should be instead:
A unpinned popover should be destroyed when hovering over another anchor/trigger. A new popover should appear at the right position.

B) Positioning of the popovers

The placement was always on top of the anchor which overlapped the content/text before.
Now it is always below the triggering anchor - except when there is not enough space below. In that case it switches the position

  • to the top for the first column
  • to the left for 2nd to n column

C) get rid of a warning, make better accessible

.fassungen_popover :global(.note) resulted in a warning as there was no component in scope.
changed to { into :global(.fassungen_popover .note) { does not throw a warning but keeps the style the same.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors the “Apparat” popover behavior in the Fassungen page to support multiple pinned popovers alongside a single transient hover popover, while improving positioning logic and addressing an accessibility/CSS scoping warning.

Changes:

  • Split popover state into one transient hover popover (apparatHover) and multiple pinned popovers (apparatPinned), with page-level Escape handling.
  • Updated popover positioning to prefer bottom placement with configurable flip fallbacks per column.
  • Adjusted focus behavior so only pinned (click-opened) popovers autofocus; refined global CSS selector to avoid Svelte warning.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/routes/fassungen/[thirties=thirties]/ApparatPopover.svelte Updates Floating UI placement/flip behavior, adds optional autofocus action, and fixes global selector usage.
src/routes/fassungen/[thirties=thirties]/+page.svelte Refactors popover state/events to support pinned + hover popovers, adds Escape dismiss logic, and computes per-column fallback placement.
Suppressed comments (1)

src/routes/fassungen/[thirties=thirties]/+page.svelte:376

  • onMouseEnterApparatTrigger also relies on ev.target. If the trigger anchor contains nested elements, ev.target can be that nested element and the transient popover will attach to the wrong node (or have empty content). Use ev.currentTarget to reliably read the anchor’s data-* attributes and compute its position.
	const onMouseEnterApparatTrigger = (/** @type { Event } */ ev) => {
		clearTimeouts();
		if (!(ev.target instanceof HTMLElement)) return;
		// A pinned popover already covers this anchor; no transient one needed.
		if (apparatPinned.some((p) => p.elTrigger === ev.target)) return;
		apparatHover = readApparatData(ev.target);

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines 361 to 369
const onClickApparatTrigger = (/** @type { Event } */ ev) => {
ignoreApparatLeave = true;
if (ev.target instanceof HTMLElement) {
fillApparatStore(ev.target, false);
if (!(ev.target instanceof HTMLElement)) return;
clearTimeouts();
// The pinned popover supersedes the transient one for this trigger.
if (apparatHover?.elTrigger === ev.target) apparatHover = undefined;
// Don't pin the same anchor twice.
if (!apparatPinned.some((p) => p.elTrigger === ev.target)) {
apparatPinned.push(readApparatData(ev.target));
}
Comment on lines +633 to +639
<ApparatPopover
resetPopup={closeApparatOnInteraction}
onMouseEnter={onMouseEnterApparatPopover}
onMouseLeave={onMouseLeaveApparatPopover}
elTrigger={apparatHover.elTrigger}
fallback={apparatFallback(apparatHover.elTrigger)}
dreissiger={apparatHover.dreissiger}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants