Merged in fix/sw-3645-mobile-menu-overlap (pull request #3260)

fix(SW-3645): Use same close button for mobile menus

* Use same close button for mobile menus


Approved-by: Linus Flood
This commit is contained in:
Anton Gunnarsson
2025-12-02 12:27:57 +00:00
parent 5da3e457cb
commit 7c247d7100
3 changed files with 40 additions and 90 deletions

View File

@@ -12,6 +12,7 @@ import styles from "./mobile-menu.module.css"
export function MobileMenu({ children }: React.PropsWithChildren) {
const intl = useIntl()
const [state, setState] = useState<"nav" | "user" | "closed">("closed")
const closeMsg = intl.formatMessage({
id: "header.closeMenu",
@@ -22,11 +23,17 @@ export function MobileMenu({ children }: React.PropsWithChildren) {
defaultMessage: "Open menu",
})
const [isOpen, setIsOpen] = useState(false)
const isOpen = state !== "closed"
return (
<div className={styles.mobileMenu}>
<UserMenu isMobile={true} />
<UserMenu
isMobile={true}
isOpen={state === "user"}
onOpenChange={(open) => {
setState(open ? "user" : "closed")
}}
/>
<div id="close-menu-container" style={{ position: "relative" }}>
<Button
variant={"Text"}
type="button"
@@ -34,12 +41,13 @@ export function MobileMenu({ children }: React.PropsWithChildren) {
aria-label={isOpen ? closeMsg : openMsg}
onPress={() => {
window.scrollTo(0, 0)
setIsOpen(!isOpen)
setState(isOpen ? "closed" : "nav")
}}
>
<span className={styles.bar} />
</Button>
<Modal className={styles.modal} isOpen={isOpen}>
</div>
<Modal className={styles.modal} isOpen={state === "nav"}>
<Dialog
className={styles.dialog}
aria-label={intl.formatMessage({

View File

@@ -24,7 +24,15 @@ import { getInitials } from "../utils"
import styles from "./user-menu.module.css"
export function UserMenu({ isMobile = false }: { isMobile?: boolean }) {
export function UserMenu({
isMobile = false,
onOpenChange,
isOpen,
}: {
isMobile?: boolean
onOpenChange?: (isOpen: boolean) => void
isOpen?: boolean
}) {
const intl = useIntl()
const lang = useLang()
const session = useSession()
@@ -76,8 +84,8 @@ export function UserMenu({ isMobile = false }: { isMobile?: boolean }) {
</a>
)}
{session.status === "authenticated" && isSuccess && profileData && (
<div className={styles.loggedInMenu}>
<DialogTrigger>
<div>
<DialogTrigger onOpenChange={onOpenChange} isOpen={isOpen}>
<Button className={styles.userName} variant={"Text"}>
<Avatar
className={styles.avatar}
@@ -100,28 +108,12 @@ export function UserMenu({ isMobile = false }: { isMobile?: boolean }) {
<ModalOverlay isDismissable>
<Modal className={styles.modal}>
<Dialog className={styles.dialog}>
{({ close }) => (
<>
<Button
variant={"Text"}
type="button"
className={styles.closeModalBtn}
aria-label={intl.formatMessage({
id: "header.closeMenu",
defaultMessage: "Close menu",
})}
onPress={close}
>
<span className={styles.bar} />
</Button>
<UserMenuContent
firstName={firstName}
lastName={lastName}
points={profileData.points.total}
isMobile={true}
/>
</>
)}
</Dialog>
</Modal>
</ModalOverlay>

View File

@@ -65,56 +65,6 @@
padding: var(--Space-x3) var(--Space-x2) var(--Space-x4);
flex-direction: column;
gap: var(--Space-x2);
.closeModalBtn {
position: fixed;
top: calc(var(--Space-x2) + var(--alert-and-banner-height));
right: var(--Space-x15);
background-color: var(--SAS-Default);
border: none;
padding: var(--Space-x05);
color: white;
justify-self: flex-start;
padding: 19px 8px 18px;
user-select: none;
&:hover,
&:hover:not(:disabled) {
background-color: var(--SAS-Default);
}
.bar,
.bar::after,
.bar::before {
background: white;
border-radius: 2.3px;
display: block;
height: 3px;
position: relative;
width: 32px;
}
.bar {
background-color: transparent;
}
.bar::after,
.bar::before {
content: "";
left: 0;
position: absolute;
transform-origin: 2.286px center;
}
.bar::after {
top: -8px;
animation: openUpAfter 0.3s ease forwards;
}
.bar::before {
top: 8px;
animation: openUpBefore 0.3s ease forwards;
}
}
}
@keyframes openUpAfter {