Update Radix deps (#22957)
CI / AMD64 Extra Build (push) Blocked by required conditions
CI / ARM Extra Build (push) Blocked by required conditions
CI / Synaptics Build (push) Blocked by required conditions
CI / Assemble and push default build (push) Blocked by required conditions
CI / AMD64 Build (push) Waiting to run
CI / ARM Build (push) Waiting to run
CI / Jetson Jetpack 6 (push) Waiting to run

* Bump radix-ui packages to align react-dismissable-layer version and fix nested overlay pointer-events bug

* remove workarounds for radix pointer events issues on dropdown and context menus

* remove disablePortal from popover

* remove modal on popovers

* remove workarounds in restart dialog

* keep onCloseAutoFocus for face, classification, and ptz

these are necessary to prevent tooltips from re-showing and from the arrow keys from reopening the ptz presets menu

* add tests
This commit is contained in:
Josh Hawkins
2026-04-21 08:48:48 -06:00
committed by GitHub
parent 7d315c5e6b
commit 3b81416299
32 changed files with 1056 additions and 345 deletions
+1 -1
View File
@@ -266,7 +266,7 @@ export function ExportCard({
)}
{!exportedRecording.in_progress && !selectionMode && (
<div className="absolute bottom-2 right-3 z-40">
<DropdownMenu modal={false}>
<DropdownMenu>
<DropdownMenuTrigger>
<BlurredIconButton
aria-label={t("tooltip.editName")}
+1 -1
View File
@@ -275,7 +275,7 @@ export default function ReviewCard({
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
<ContextMenu key={event.id} modal={false}>
<ContextMenu key={event.id}>
<ContextMenuTrigger asChild>{content}</ContextMenuTrigger>
<ContextMenuContent>
<ContextMenuItem>
@@ -322,7 +322,7 @@ export default function Step1NameAndDefine({
<FormLabel className="text-primary-variant">
{t("wizard.step1.classificationType")}
</FormLabel>
<Popover modal={true}>
<Popover>
<PopoverTrigger asChild>
<Button
variant="ghost"
@@ -405,7 +405,7 @@ export default function Step1NameAndDefine({
? t("wizard.step1.states")
: t("wizard.step1.classes")}
</FormLabel>
<Popover modal={true}>
<Popover>
<PopoverTrigger asChild>
<Button variant="ghost" size="sm" className="h-4 w-4 p-0">
<LuInfo className="size-3" />
@@ -238,11 +238,7 @@ export default function Step2StateArea({
<div className="flex items-center justify-between">
<h3 className="text-sm font-medium">{t("wizard.step2.cameras")}</h3>
{availableCameras.length > 0 ? (
<Popover
open={isPopoverOpen}
onOpenChange={setIsPopoverOpen}
modal={true}
>
<Popover open={isPopoverOpen} onOpenChange={setIsPopoverOpen}>
<PopoverTrigger asChild>
<Button
type="button"
@@ -592,7 +592,7 @@ export function CameraGroupRow({
{isMobile && !isReadOnly && (
<>
<DropdownMenu modal={!isDesktop}>
<DropdownMenu>
<DropdownMenuTrigger>
<HiOutlineDotsVertical className="size-5" />
</DropdownMenuTrigger>
@@ -136,7 +136,6 @@ export function CamerasFilterButton({
return (
<DropdownMenu
modal={false}
open={open}
onOpenChange={(open) => {
if (!open) {
+1 -1
View File
@@ -81,7 +81,7 @@ export default function AccountSettings({ className }: AccountSettingsProps) {
};
return (
<Container modal={!isDesktop}>
<Container>
<Tooltip>
<Trigger asChild>
<TooltipTrigger asChild>
+1 -1
View File
@@ -205,7 +205,7 @@ export default function GeneralSettings({ className }: GeneralSettingsProps) {
return (
<>
<Container modal={!isDesktop}>
<Container>
<Trigger>
<Tooltip>
<TooltipTrigger asChild>
+1 -1
View File
@@ -272,7 +272,7 @@ export default function LiveContextMenu({
return (
<div className={cn("w-full", className)}>
<ContextMenu key={camera} modal={false} onOpenChange={handleOpenChange}>
<ContextMenu key={camera} onOpenChange={handleOpenChange}>
<ContextMenuTrigger>{children}</ContextMenuTrigger>
<ContextMenuContent>
<div className="flex flex-col items-start gap-1 py-1 pl-2">
@@ -258,13 +258,13 @@ export default function SearchResultActions({
</AlertDialogContent>
</AlertDialog>
{isContextMenu ? (
<ContextMenu modal={false}>
<ContextMenu>
<ContextMenuTrigger>{children}</ContextMenuTrigger>
<ContextMenuContent>{menuItems}</ContextMenuContent>
</ContextMenu>
) : (
<>
<DropdownMenu modal={false}>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<BlurredIconButton aria-label={t("itemMenu.more.aria")}>
<FiMoreVertical className="size-5" />
@@ -22,7 +22,7 @@ export default function ActionsDropdown({
const { t } = useTranslation(["components/dialog", "views/replay", "common"]);
return (
<DropdownMenu modal={false}>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
className="flex items-center gap-2"
@@ -127,7 +127,7 @@ export function CustomTimeSelector({
{formattedStart}
</Button>
</PopoverTrigger>
<PopoverContent className="flex flex-col items-center" disablePortal>
<PopoverContent className="flex flex-col items-center">
<TimezoneAwareCalendar
timezone={config?.ui.timezone}
selectedDay={new Date(startTime * 1000)}
@@ -193,7 +193,7 @@ export function CustomTimeSelector({
{formattedEnd}
</Button>
</PopoverTrigger>
<PopoverContent className="flex flex-col items-center" disablePortal>
<PopoverContent className="flex flex-col items-center">
<TimezoneAwareCalendar
timezone={config?.ui.timezone}
selectedDay={new Date(endTime * 1000)}
@@ -14,7 +14,7 @@ import {
import useKeyboardListener from "@/hooks/use-keyboard-listener";
import { CameraPtzInfo } from "@/types/ptz";
import React, { useCallback } from "react";
import { isDesktop, isMobile } from "react-device-detect";
import { isMobile } from "react-device-detect";
import { BsThreeDotsVertical } from "react-icons/bs";
import {
FaAngleDown,
@@ -292,7 +292,7 @@ export default function PtzControlPanel({
</Tooltip>
)}
{(ptz?.presets?.length ?? 0) > 0 && (
<DropdownMenu modal={!isDesktop}>
<DropdownMenu>
<Tooltip>
<TooltipTrigger asChild>
<DropdownMenuTrigger asChild>
@@ -241,7 +241,7 @@ function AnnotationSettings({
return (
<div className="ml-2">
<Overlay modal={isDesktop} open={open} onOpenChange={handleOpenChange}>
<Overlay open={open} onOpenChange={handleOpenChange}>
<Trigger asChild>
<Button
type="button"
@@ -269,7 +269,6 @@ function AnnotationSettings({
: "mx-1 max-h-[75dvh] overflow-hidden rounded-t-2xl px-4 pb-4"
}
{...contentProps}
{...(isDesktop ? { disablePortal: true } : {})}
data-annotation-popover
>
<AnnotationSettingsPane
@@ -38,12 +38,6 @@ export default function RestartDialog({
const [restartingSheetOpen, setRestartingSheetOpen] = useState(false);
const [countdown, setCountdown] = useState(60);
const clearBodyPointerEvents = () => {
if (typeof document !== "undefined") {
document.body.style.pointerEvents = "";
}
};
useEffect(() => {
setRestartDialogOpen(isOpen);
}, [isOpen]);
@@ -85,16 +79,10 @@ export default function RestartDialog({
if (!open) {
setRestartDialogOpen(false);
onClose();
clearBodyPointerEvents();
}
}}
>
<AlertDialogContent
onCloseAutoFocus={(event) => {
event.preventDefault();
clearBodyPointerEvents();
}}
>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>{t("restart.title")}</AlertDialogTitle>
<AlertDialogDescription className="sr-only">
+1 -2
View File
@@ -1,6 +1,6 @@
import { useCallback, useMemo, useRef, useState } from "react";
import { LuFolderX } from "react-icons/lu";
import { isDesktop, isMobileOnly, isSafari } from "react-device-detect";
import { isMobileOnly, isSafari } from "react-device-detect";
import { LuPause, LuPlay } from "react-icons/lu";
import {
DropdownMenu,
@@ -246,7 +246,6 @@ export default function VideoControls({
)}
{features.playbackRate && (
<DropdownMenu
modal={!isDesktop}
onOpenChange={(open) => {
if (setControlsOpen) {
setControlsOpen(open);
+2 -2
View File
@@ -19,7 +19,7 @@ import { LuCopy, LuPencil } from "react-icons/lu";
import { FaDrawPolygon, FaObjectGroup } from "react-icons/fa";
import { BsPersonBoundingBox } from "react-icons/bs";
import { HiOutlineDotsVertical, HiTrash } from "react-icons/hi";
import { isDesktop, isMobile } from "react-device-detect";
import { isMobile } from "react-device-detect";
import { toRGBColorString } from "@/utils/canvasUtil";
import { Polygon, PolygonType } from "@/types/canvas";
import { useCallback, useMemo, useState } from "react";
@@ -524,7 +524,7 @@ export default function PolygonItem({
{isMobile && (
<>
<DropdownMenu modal={!isDesktop}>
<DropdownMenu>
<DropdownMenuTrigger>
<HiOutlineDotsVertical className="size-5" />
</DropdownMenuTrigger>
@@ -41,7 +41,7 @@ export function ProfileSectionDropdown({
: null;
return (
<DropdownMenu modal={false}>
<DropdownMenu>
<DropdownMenuTrigger asChild>
{iconOnly ? (
<Button variant="outline" size="sm">
@@ -377,7 +377,7 @@ export default function Step1NameCamera({
);
return selectedBrand &&
selectedBrand.value != "other" ? (
<Popover modal={true}>
<Popover>
<PopoverTrigger asChild>
<Button
variant="ghost"
@@ -415,10 +415,7 @@ export default function Step3StreamConfig({
</Button>
</div>
</PopoverTrigger>
<PopoverContent
className="w-[--radix-popover-trigger-width] p-2"
disablePortal
>
<PopoverContent className="w-[--radix-popover-trigger-width] p-2">
<Command>
<CommandInput
placeholder={t(
@@ -600,7 +597,7 @@ export default function Step3StreamConfig({
<Label className="text-sm font-medium text-primary-variant">
{t("cameraWizard.step3.roles")}
</Label>
<Popover modal={true}>
<Popover>
<PopoverTrigger asChild>
<Button variant="ghost" size="sm" className="h-4 w-4 p-0">
<LuInfo className="size-3" />
@@ -670,7 +667,7 @@ export default function Step3StreamConfig({
<Label className="text-sm font-medium text-primary-variant">
{t("cameraWizard.step3.featuresTitle")}
</Label>
<Popover modal={true}>
<Popover>
<PopoverTrigger asChild>
<Button variant="ghost" size="sm" className="h-4 w-4 p-0">
<LuInfo className="size-3" />
-2
View File
@@ -351,7 +351,6 @@ function TopicFilterButton({
return (
<DropdownMenu
modal={false}
open={open}
onOpenChange={(open) => {
if (!open) setCurrentTopics(selectedTopics);
@@ -517,7 +516,6 @@ function WsCamerasFilterButton({
return (
<DropdownMenu
modal={false}
open={open}
onOpenChange={(open) => {
if (!open) setCurrentCameras(selectedCameras);