Skip to content

Make EmergencyBadge tooltip work on touch devices and simplify#442

Merged
mindmonk merged 8 commits intodevelopfrom
feature/emergency-badge-popover-mobile-tooltip
May 4, 2026
Merged

Make EmergencyBadge tooltip work on touch devices and simplify#442
mindmonk merged 8 commits intodevelopfrom
feature/emergency-badge-popover-mobile-tooltip

Conversation

@mindmonk
Copy link
Copy Markdown
Contributor

@mindmonk mindmonk commented Apr 27, 2026

Summary

  • Tooltip opens on tap on touch devices, not just on hover.
  • Positioning moved to CSS Anchor Positioning, with viewport clamping and auto-flip below the badge.
  • Reduced type union to warning / error, dropped the position prop.
  • Removed the inner arrow.
  • Updated callsites in VaultList.vue and EmergencyAccessVaultList.vue.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 27, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

EmergencyBadge.vue narrows its type prop to only "warning" or "error", removes the position prop and related positioning/arrow logic, and replaces conditional wrapper rendering with a button-trigger and always-present tooltip whose visibility is controlled by CSS states. Tooltip placement is driven by a useId()-generated anchor and scoped CSS with flip fallback. VaultList.vue and EmergencyAccessVaultList.vue update EmergencyBadge usages to the new "warning"/"error" types and drop explicit position props.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • overheadhunter
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main changes: improving EmergencyBadge tooltip functionality for touch devices and simplifying the component.
Description check ✅ Passed The description is directly related to the changeset, providing clear details about the tooltip improvements, positioning changes, prop simplification, and updated callsites.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/emergency-badge-popover-mobile-tooltip

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/src/components/emergencyaccess/EmergencyBadge.vue`:
- Around line 9-12: The popover dismisses when the cursor crosses the 0.5rem gap
because only the trigger handles mouseenter/mouseleave; update
EmergencyBadge.vue to also track hover on the popover panel by attaching the
same handlers (showIfHover, hideIfHover) to the panel element and implement a
short close delay in hideIfHover using a timeout (store e.g.
this.hoverCloseTimer) that is cleared in showIfHover so brief exits (traversing
the gap) don't immediately close the panel; alternatively remove the margin gap
if adding panel listeners is undesirable.
- Around line 3-16: The popover panel in EmergencyBadge.vue is not associated
with the trigger button, so screen readers won't read the popover message; add a
stable unique id for the popover (e.g., computed/constant like popoverId) and
ensure the popover DOM node renders with that id, then when showing the popover
(in methods that call showIfHover/showPopover/toggleOnTouch) set the button's
aria-describedby to that id and remove it when hiding (hideIfHover/hide popover)
so assistive tech can link the trigger to the panel; update any showPopover/hide
logic to manage this aria attribute lifecycle and ensure the template binds
:aria-describedby="isOpen ? popoverId : null" (or equivalent) so the association
is always correct.
- Line 13: The button with `@click.stop`="toggleOnTouch" is not recognized as the
popover invoker on touch devices, causing a light-dismiss race; fix by adding a
popovertarget attribute on that button pointing to the popover's id (ensure the
popover element has the same id) so the browser recognizes the invoker
declaratively, OR modify the event flow by capturing pointerdown on the button
to track the current open state and have toggleOnTouch consult that flag (update
toggleOnTouch and add a pointerdown handler) to avoid reopening after
light-dismiss.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0a27d8a9-9060-4fb4-bde7-e55ac8548fca

📥 Commits

Reviewing files that changed from the base of the PR and between 5757ec9 and ae9f0d9.

📒 Files selected for processing (1)
  • frontend/src/components/emergencyaccess/EmergencyBadge.vue

Comment thread frontend/src/components/emergencyaccess/EmergencyBadge.vue
Comment thread frontend/src/components/emergencyaccess/EmergencyBadge.vue Outdated
Comment thread frontend/src/components/emergencyaccess/EmergencyBadge.vue Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/src/components/emergencyaccess/EmergencyAccessVaultList.vue`:
- Around line 100-105: The "broken" badge condition is inverted: change the
EmergencyBadge usage so it renders when isBroken(vault) (not !isBroken(vault))
and set its type to "error" to match VaultList.vue; keep the same i18n keys
(emergencyAccess.badge.broken.title and …broken.message) and update the
EmergencyBadge props (type, v-if) accordingly so the badge shows only for vaults
where isBroken(vault) is true (i.e., vault.requiredEmergencyKeyShares >
emergencyAccessMembers(vault).length).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: de8c3a35-469c-4326-8d82-74f4ea6fa969

📥 Commits

Reviewing files that changed from the base of the PR and between ae9f0d9 and 39935ac.

📒 Files selected for processing (3)
  • frontend/src/components/VaultList.vue
  • frontend/src/components/emergencyaccess/EmergencyAccessVaultList.vue
  • frontend/src/components/emergencyaccess/EmergencyBadge.vue

@mindmonk mindmonk changed the title Switch EmergencyBadge tooltip to Popover API for mobile tap support Make EmergencyBadge tooltip work on touch devices and simplify Apr 27, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
frontend/src/components/emergencyaccess/EmergencyBadge.vue (1)

13-21: ⚠️ Potential issue | 🟠 Major

Tooltip not announced to assistive technology — add aria-describedby linking trigger to panel.

The panel correctly carries role="tooltip", but nothing on the trigger references it. The trigger only exposes aria-label="title", so screen readers announce the title but never the message. Generate an id for the panel and reference it from the trigger's aria-describedby.

♿ Suggested fix
 <script setup lang="ts">
 import { computed, useId } from 'vue';
 import { ExclamationTriangleIcon } from '@heroicons/vue/24/solid';

 const props = defineProps<{
   type: 'warning' | 'error';
   title: string;
   message: string;
 }>();

-const anchor = `--ea-anchor-${useId()}`;
+const id = useId();
+const anchor = `--ea-anchor-${id}`;
+const panelId = `ea-tooltip-${id}`;
 const isError = computed(() => props.type === 'error');
 </script>
     <div
+      :id="panelId"
       class="tooltip-panel px-2 py-1 rounded shadow-sm border text-xs hyphens-auto"

(plus :aria-describedby="panelId" on the trigger as shown in the previous comment)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/emergencyaccess/EmergencyBadge.vue` around lines 13 -
21, Add a unique id for the tooltip panel and wire it to the trigger via
aria-describedby: create a component-level panelId (e.g. in data() / setup() or
a computed using the component _uid) and bind it as :id="panelId" on the div
that has role="tooltip" (the element showing title/message and using props
title, message, isError, anchor), then update the trigger element (the element
that currently only has aria-label="title") to include
:aria-describedby="panelId" so assistive tech will read the tooltip message.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/src/components/emergencyaccess/EmergencyBadge.vue`:
- Around line 3-11: Replace the non-semantic span used as the interactive
trigger in EmergencyBadge.vue with a proper <button type="button">: remove the
tabindex attribute, keep the same class list but drop or change cursor-default
to a pointer (or omit it) so iOS Safari can focus on tap, preserve :class
binding for isError, keep :style="{ anchorName: anchor }" and
:aria-label="title", and continue rendering the ExclamationTriangleIcon inside
the button so existing styling and focus-visible/ring behavior remain intact;
ensure the component still exports/uses isError, anchor, and title props as
before.

---

Duplicate comments:
In `@frontend/src/components/emergencyaccess/EmergencyBadge.vue`:
- Around line 13-21: Add a unique id for the tooltip panel and wire it to the
trigger via aria-describedby: create a component-level panelId (e.g. in data() /
setup() or a computed using the component _uid) and bind it as :id="panelId" on
the div that has role="tooltip" (the element showing title/message and using
props title, message, isError, anchor), then update the trigger element (the
element that currently only has aria-label="title") to include
:aria-describedby="panelId" so assistive tech will read the tooltip message.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d9b181b5-7361-48bb-9aa7-e1a00d18574b

📥 Commits

Reviewing files that changed from the base of the PR and between 39935ac and aace846.

📒 Files selected for processing (2)
  • frontend/src/components/emergencyaccess/EmergencyAccessVaultList.vue
  • frontend/src/components/emergencyaccess/EmergencyBadge.vue

Comment thread frontend/src/components/emergencyaccess/EmergencyBadge.vue Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
frontend/src/components/emergencyaccess/EmergencyBadge.vue (1)

3-20: ⚠️ Potential issue | 🟠 Major

Associate the tooltip panel with the trigger for screen readers.

role="tooltip" on Line 17 is currently disconnected from the button on Line 3, so message (Line 20) is not reliably announced when the trigger receives focus.

♿ Proposed fix
 import { computed, useId } from 'vue';
 import { ExclamationTriangleIcon } from '@heroicons/vue/24/solid';
@@
-const anchor = `--ea-anchor-${useId()}`;
+const id = useId();
+const anchor = `--ea-anchor-${id}`;
+const tooltipId = `ea-tooltip-${id}`;
 const isError = computed(() => props.type === 'error');
     <button
       type="button"
       class="inline-flex items-center gap-2 rounded-full p-2 text-xs font-medium cursor-default ring-1 outline-none focus-visible:ring-2"
       :class="isError ? 'bg-red-100 ring-red-300/70 text-red-800' : 'bg-yellow-50 ring-yellow-300/70 text-yellow-800'"
       :style="{ anchorName: anchor }"
       :aria-label="title"
+      :aria-describedby="tooltipId"
     >
@@
     <div
+      :id="tooltipId"
       class="tooltip-panel fixed mb-2 z-20 px-2 py-1 rounded shadow-sm border text-xs hyphens-auto invisible opacity-0 transition-[opacity,visibility] duration-150 group-hover:visible group-hover:opacity-100 group-has-focus-visible:visible group-has-focus-visible:opacity-100 pointer-coarse:group-focus-within:visible pointer-coarse:group-focus-within:opacity-100"

Also applies to: 26-36

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/emergencyaccess/EmergencyBadge.vue` around lines 3 -
20, The tooltip (the div with class "tooltip-panel" and role="tooltip") is not
associated with its trigger button so screen readers won't announce message;
generate a stable id (e.g., computed property tooltipId using the existing
anchor prop or a UID) and add that id to the tooltip div and set the button's
aria-describedby (or aria-labelledby if you prefer the title element) to the
same tooltipId; ensure the binding uses :id="tooltipId" on the tooltip-panel and
:aria-describedby="tooltipId" on the button and keep visibility logic unchanged
so assistive tech can reference the tooltip content reliably.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@frontend/src/components/emergencyaccess/EmergencyBadge.vue`:
- Around line 3-20: The tooltip (the div with class "tooltip-panel" and
role="tooltip") is not associated with its trigger button so screen readers
won't announce message; generate a stable id (e.g., computed property tooltipId
using the existing anchor prop or a UID) and add that id to the tooltip div and
set the button's aria-describedby (or aria-labelledby if you prefer the title
element) to the same tooltipId; ensure the binding uses :id="tooltipId" on the
tooltip-panel and :aria-describedby="tooltipId" on the button and keep
visibility logic unchanged so assistive tech can reference the tooltip content
reliably.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d0f1944a-a090-4c3a-935e-1e83e33c663d

📥 Commits

Reviewing files that changed from the base of the PR and between bc3dd54 and a4f27a7.

📒 Files selected for processing (1)
  • frontend/src/components/emergencyaccess/EmergencyBadge.vue

@mindmonk mindmonk requested a review from overheadhunter April 29, 2026 08:42
@mindmonk mindmonk merged commit 83cc61b into develop May 4, 2026
8 checks passed
@mindmonk mindmonk deleted the feature/emergency-badge-popover-mobile-tooltip branch May 4, 2026 10:35
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