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:
@@ -12,6 +12,7 @@ import styles from "./mobile-menu.module.css"
|
|||||||
|
|
||||||
export function MobileMenu({ children }: React.PropsWithChildren) {
|
export function MobileMenu({ children }: React.PropsWithChildren) {
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
|
const [state, setState] = useState<"nav" | "user" | "closed">("closed")
|
||||||
|
|
||||||
const closeMsg = intl.formatMessage({
|
const closeMsg = intl.formatMessage({
|
||||||
id: "header.closeMenu",
|
id: "header.closeMenu",
|
||||||
@@ -22,24 +23,31 @@ export function MobileMenu({ children }: React.PropsWithChildren) {
|
|||||||
defaultMessage: "Open menu",
|
defaultMessage: "Open menu",
|
||||||
})
|
})
|
||||||
|
|
||||||
const [isOpen, setIsOpen] = useState(false)
|
const isOpen = state !== "closed"
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.mobileMenu}>
|
<div className={styles.mobileMenu}>
|
||||||
<UserMenu isMobile={true} />
|
<UserMenu
|
||||||
<Button
|
isMobile={true}
|
||||||
variant={"Text"}
|
isOpen={state === "user"}
|
||||||
type="button"
|
onOpenChange={(open) => {
|
||||||
className={`${styles.hamburger} ${isOpen ? styles.isExpanded : ""}`}
|
setState(open ? "user" : "closed")
|
||||||
aria-label={isOpen ? closeMsg : openMsg}
|
|
||||||
onPress={() => {
|
|
||||||
window.scrollTo(0, 0)
|
|
||||||
setIsOpen(!isOpen)
|
|
||||||
}}
|
}}
|
||||||
>
|
/>
|
||||||
<span className={styles.bar} />
|
<div id="close-menu-container" style={{ position: "relative" }}>
|
||||||
</Button>
|
<Button
|
||||||
<Modal className={styles.modal} isOpen={isOpen}>
|
variant={"Text"}
|
||||||
|
type="button"
|
||||||
|
className={`${styles.hamburger} ${isOpen ? styles.isExpanded : ""}`}
|
||||||
|
aria-label={isOpen ? closeMsg : openMsg}
|
||||||
|
onPress={() => {
|
||||||
|
window.scrollTo(0, 0)
|
||||||
|
setState(isOpen ? "closed" : "nav")
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span className={styles.bar} />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<Modal className={styles.modal} isOpen={state === "nav"}>
|
||||||
<Dialog
|
<Dialog
|
||||||
className={styles.dialog}
|
className={styles.dialog}
|
||||||
aria-label={intl.formatMessage({
|
aria-label={intl.formatMessage({
|
||||||
|
|||||||
@@ -24,7 +24,15 @@ import { getInitials } from "../utils"
|
|||||||
|
|
||||||
import styles from "./user-menu.module.css"
|
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 intl = useIntl()
|
||||||
const lang = useLang()
|
const lang = useLang()
|
||||||
const session = useSession()
|
const session = useSession()
|
||||||
@@ -76,8 +84,8 @@ export function UserMenu({ isMobile = false }: { isMobile?: boolean }) {
|
|||||||
</a>
|
</a>
|
||||||
)}
|
)}
|
||||||
{session.status === "authenticated" && isSuccess && profileData && (
|
{session.status === "authenticated" && isSuccess && profileData && (
|
||||||
<div className={styles.loggedInMenu}>
|
<div>
|
||||||
<DialogTrigger>
|
<DialogTrigger onOpenChange={onOpenChange} isOpen={isOpen}>
|
||||||
<Button className={styles.userName} variant={"Text"}>
|
<Button className={styles.userName} variant={"Text"}>
|
||||||
<Avatar
|
<Avatar
|
||||||
className={styles.avatar}
|
className={styles.avatar}
|
||||||
@@ -100,28 +108,12 @@ export function UserMenu({ isMobile = false }: { isMobile?: boolean }) {
|
|||||||
<ModalOverlay isDismissable>
|
<ModalOverlay isDismissable>
|
||||||
<Modal className={styles.modal}>
|
<Modal className={styles.modal}>
|
||||||
<Dialog className={styles.dialog}>
|
<Dialog className={styles.dialog}>
|
||||||
{({ close }) => (
|
<UserMenuContent
|
||||||
<>
|
firstName={firstName}
|
||||||
<Button
|
lastName={lastName}
|
||||||
variant={"Text"}
|
points={profileData.points.total}
|
||||||
type="button"
|
isMobile={true}
|
||||||
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>
|
</Dialog>
|
||||||
</Modal>
|
</Modal>
|
||||||
</ModalOverlay>
|
</ModalOverlay>
|
||||||
|
|||||||
@@ -65,56 +65,6 @@
|
|||||||
padding: var(--Space-x3) var(--Space-x2) var(--Space-x4);
|
padding: var(--Space-x3) var(--Space-x2) var(--Space-x4);
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: var(--Space-x2);
|
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 {
|
@keyframes openUpAfter {
|
||||||
|
|||||||
Reference in New Issue
Block a user