(fix): a few mobile related bugs #17

Merged
alois merged 3 commits from dev into main 2026-06-03 10:14:14 +03:00
Showing only changes of commit 2f9b6edf8c - Show all commits

(fix): react rerendered the mobile drawer multiple times causing the drawer to pop out multiple times
All checks were successful
/ build-web (push) Successful in 1m23s
/ build-desktop (linux) (push) Successful in 5m14s
/ build-mobile (push) Successful in 11m54s
/ release (push) Successful in 28s

Alois 2026-06-03 08:51:31 +02:00

View file

@ -11,6 +11,8 @@ import {
ContextMenuTrigger, ContextMenuTrigger,
Drawer, Drawer,
DrawerContent, DrawerContent,
DrawerDescription,
DrawerTitle,
DrawerTrigger, DrawerTrigger,
useIsMobile, useIsMobile,
} from "@tensamin/ui"; } from "@tensamin/ui";
@ -41,6 +43,12 @@ type MenuComponents = {
SubContent: (props: { children: ReactNode }) => ReactElement; SubContent: (props: { children: ReactNode }) => ReactElement;
}; };
function blurActiveElement() {
if (document.activeElement instanceof HTMLElement) {
document.activeElement.blur();
}
}
const desktopMenuComponents: MenuComponents = { const desktopMenuComponents: MenuComponents = {
Content: ContextMenuContent, Content: ContextMenuContent,
Group: ContextMenuGroup, Group: ContextMenuGroup,
@ -51,10 +59,20 @@ const desktopMenuComponents: MenuComponents = {
SubContent: ContextMenuSubContent, SubContent: ContextMenuSubContent,
}; };
function getMobileMenuComponents(onClose: () => void): MenuComponents { function getMobileMenuComponents({
description,
onClose,
title,
}: {
description: string;
onClose: () => void;
title: string;
}): MenuComponents {
return { return {
Content: ({ className, children }) => ( Content: ({ className, children }) => (
<DrawerContent> <DrawerContent>
<DrawerTitle className="sr-only">{title}</DrawerTitle>
<DrawerDescription className="sr-only">{description}</DrawerDescription>
<div className={cn("p-3!", className)}>{children}</div> <div className={cn("p-3!", className)}>{children}</div>
</DrawerContent> </DrawerContent>
), ),
@ -62,6 +80,7 @@ function getMobileMenuComponents(onClose: () => void): MenuComponents {
Item: ({ children, className, disabled, onClick, variant = "default" }) => { Item: ({ children, className, disabled, onClick, variant = "default" }) => {
async function handleClick() { async function handleClick() {
await onClick?.(); await onClick?.();
blurActiveElement();
onClose(); onClose();
} }
@ -86,8 +105,9 @@ function getMobileMenuComponents(onClose: () => void): MenuComponents {
Sub: ({ children }) => <div>{children}</div>, Sub: ({ children }) => <div>{children}</div>,
SubTrigger: ({ children, onClick }) => { SubTrigger: ({ children, onClick }) => {
async function handleClick() { async function handleClick() {
await onClick?.(); blurActiveElement();
onClose(); onClose();
await onClick?.();
} }
return ( return (
@ -198,11 +218,23 @@ export default function MessageContextMenu({
); );
const [mainDrawerOpen, setMainDrawerOpen] = useState(false); const [mainDrawerOpen, setMainDrawerOpen] = useState(false);
const [reactionDrawerOpen, setReactionDrawerOpen] = useState(false); const [reactionDrawerOpen, setReactionDrawerOpen] = useState(false);
const mainDrawerComponents = getMobileMenuComponents(() => const mainDrawerComponents = useMemo(
setMainDrawerOpen(false), () =>
getMobileMenuComponents({
description: "Actions available for this message.",
onClose: () => setMainDrawerOpen(false),
title: "Message actions",
}),
[],
); );
const reactionDrawerComponents = getMobileMenuComponents(() => const reactionDrawerComponents = useMemo(
setReactionDrawerOpen(false), () =>
getMobileMenuComponents({
description: "Choose a reaction to add to this message.",
onClose: () => setReactionDrawerOpen(false),
title: "Add reaction",
}),
[],
); );
if (isMobile) { if (isMobile) {
@ -221,7 +253,13 @@ export default function MessageContextMenu({
</Drawer> </Drawer>
<Drawer open={reactionDrawerOpen} onOpenChange={setReactionDrawerOpen}> <Drawer open={reactionDrawerOpen} onOpenChange={setReactionDrawerOpen}>
<DrawerContent> <DrawerContent>
<DrawerTitle className="sr-only">Add reaction</DrawerTitle>
<DrawerDescription className="sr-only">
Choose a reaction to add to this message.
</DrawerDescription>
<div className="p-3!">
<ReactionItems Item={reactionDrawerComponents.Item} /> <ReactionItems Item={reactionDrawerComponents.Item} />
</div>
</DrawerContent> </DrawerContent>
</Drawer> </Drawer>
</> </>