Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions extension/src/popup/components/SlideupModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@ export const SlideupModal = ({
<LoadingBackground
onClick={() => {
setIsOpen(false);
// our dismiss transition is 200ms long
// our dismiss transition is 150ms long
setTimeout(() => {
setIsModalOpen(false);
}, 200);
}, 150);
}}
Comment on lines 70 to 75
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

The close timeout is hard-coded and now shorter than the LoadingBackground fade-out (transition: all var(--dropdown-animation) + transition-delay: 0.1s), so when the parent unmounts the modal after 150ms the backdrop transition is cut off mid-animation. Consider waiting for transitionend (modal and/or backdrop) before calling setIsModalOpen(false), or at least deriving a single shared duration (incl. delay) so the JS unmount timing can’t drift from CSS.

Copilot uses AI. Check for mistakes.
isActive={isOpen}
/>
Expand Down
14 changes: 6 additions & 8 deletions extension/src/popup/components/SlideupModal/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,15 @@
width: 100%;
z-index: var(--z-index-modal);

/* Start hidden/offscreen and invisible */
transform: translateY(100%);
transform: scale(0.98);
opacity: 0;
pointer-events: none;
overflow: hidden;

Comment on lines +11 to 15
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

When the modal is “closed”, it’s still in the DOM and opacity: 0/pointer-events: none won’t stop keyboard focus on any focusable descendants. Consider pairing the visual hide with visibility: hidden (or inert/aria-hidden at the component level) so users can’t tab into an invisible slideup modal.

Copilot uses AI. Check for mistakes.
transition:
transform 0.2s cubic-bezier(0.4, 0, 0.2, 1),
opacity 0.2s cubic-bezier(0.4, 0, 0.2, 1),
height 0.2s cubic-bezier(0.4, 0, 0.2, 1);
will-change: transform, opacity, height;
transform 0.15s cubic-bezier(0.16, 1, 0.3, 1),
opacity 0.15s cubic-bezier(0.16, 1, 0.3, 1);
will-change: transform, opacity;

.View__inset {
border: 0;
Expand All @@ -27,13 +25,13 @@
}

.SlideupModal.open {
transform: translateY(0);
transform: scale(1);
opacity: 1;
pointer-events: auto;
}

.SlideupModal.closed {
transform: translateY(100%);
transform: scale(0.98);
opacity: 0;
pointer-events: none;
}
35 changes: 11 additions & 24 deletions extension/src/popup/components/account/AccountHeaderModal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useRef } from "react";
import React from "react";

import "./styles.scss";

Expand All @@ -14,26 +14,13 @@ export const AccountHeaderModal = ({
isDropdownOpen,
icon,
className,
}: AccountHeaderModalProps) => {
const dropdownRef = useRef<HTMLDivElement>(null);

useEffect(() => {
if (dropdownRef.current != null) {
dropdownRef.current.style.maxHeight = isDropdownOpen
? `calc(100vh - 1rem)`
: "0";
}
}, [isDropdownOpen]);

return (
<>
{icon}
<div
ref={dropdownRef}
className={`AccountHeaderModal ${className || ""}`}
>
<div className="AccountHeaderModal__content">{children}</div>
</div>
</>
);
};
}: AccountHeaderModalProps) => (
<>
{icon}
<div
className={`AccountHeaderModal ${isDropdownOpen ? "AccountHeaderModal--open" : ""} ${className || ""}`}
>
<div className="AccountHeaderModal__content">{children}</div>
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

The modal stays mounted even when closed; adding/removing a CSS class won’t prevent keyboard focus on descendants (links/buttons inside children). Consider adding aria-hidden={!isDropdownOpen} and/or inert when closed (or unmounting after the fade-out) so hidden menu items aren’t reachable via Tab / screen readers.

Suggested change
<div className="AccountHeaderModal__content">{children}</div>
<div
className="AccountHeaderModal__content"
aria-hidden={!isDropdownOpen}
inert={!isDropdownOpen ? "" : undefined}
>
{children}
</div>

Copilot uses AI. Check for mistakes.
</div>
</>
);
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
@use "../../../styles/utils.scss" as *;

.AccountHeaderModal {
overflow: hidden;
position: absolute;
left: 0;
top: 0;
z-index: calc(var(--z-index-tooltip) + 1);
transition: max-height var(--dropdown-animation);

// default max-height on page load
max-height: 0;
/* Fade animation */
opacity: 0;
transform: scale(0.95);
pointer-events: none;
transition:
opacity 0.15s cubic-bezier(0.16, 1, 0.3, 1),
transform 0.15s cubic-bezier(0.16, 1, 0.3, 1);
Comment on lines +14 to +15
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

This file previously used the shared --dropdown-animation timing, but the new transition hard-codes 0.15s and a custom easing. To keep animation timings consistent and avoid future drift, consider using var(--dropdown-animation) (defined in popup/styles/global.scss) or introducing a new shared CSS variable for modal fade transitions.

Suggested change
opacity 0.15s cubic-bezier(0.16, 1, 0.3, 1),
transform 0.15s cubic-bezier(0.16, 1, 0.3, 1);
opacity var(--dropdown-animation),
transform var(--dropdown-animation);

Copilot uses AI. Check for mistakes.

Comment on lines +9 to +16
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

With only opacity: 0/pointer-events: none, the dropdown remains focusable to keyboard and present to assistive tech when closed (e.g., the hidden items can still be tabbed to). Consider also toggling visibility: hidden (and/or applying inert/aria-hidden from the component) when closed so the content is removed from the tab order and accessibility tree.

Copilot uses AI. Check for mistakes.
&--open {
opacity: 1;
transform: scale(1);
pointer-events: auto;
}

&__content {
background: var(--sds-clr-gray-01);
border-radius: #{pxToRem(6px)};
border: 1px solid var(--sds-clr-gray-06);
max-height: calc(100vh - 1rem);
padding: pxToRem(4px);
overflow: auto;
}
}