Fix popovers not open in form for older Safari
Some checks failed
E2E Tests / e2e (push) Has been cancelled
Tests and checks on push / run-checks-and-tests (push) Has been cancelled
Updates translation progress / update-translation-progress-issue (push) Has been cancelled

This commit is contained in:
Kalle
2026-09-24 22:18:07 +03:00
parent 6ab7c52245
commit ef540fe8c1
4 changed files with 19 additions and 10 deletions

View File

@@ -12,7 +12,7 @@ import styles from "./Menu.module.css";
import {
focusLeftTo,
isOwnToggle,
usePopoverTargetOnceHydrated,
usePopoverTriggerPropsOnceHydrated,
useShowPopoverOnOpen,
} from "./Popover";
import { useFloatingLayer } from "./useFloatingLayer";
@@ -44,7 +44,7 @@ export function SendouMenu({
eager,
}: SendouMenuProps) {
const popoverId = `${React.useId()}-menu`;
const popoverTarget = usePopoverTargetOnceHydrated(popoverId);
const popoverTriggerProps = usePopoverTriggerPropsOnceHydrated(popoverId);
const topLayerStyle = useTopLayerViewTransitionStyle();
const [open, setOpen] = React.useState(false);
@@ -114,7 +114,7 @@ export function SendouMenu({
onBlur={onBlur}
>
{React.cloneElement(trigger, {
popoverTarget,
...popoverTriggerProps,
"aria-expanded": open,
"aria-haspopup": "menu",
})}

View File

@@ -19,8 +19,13 @@ export function isOwnToggle(event: React.ToggleEvent<HTMLElement>) {
return event.target === event.currentTarget;
}
export function usePopoverTargetOnceHydrated(popoverId: string) {
return useHydrated() ? popoverId : undefined;
/**
* Props making the trigger open the popover natively once hydrated. `form=""`
* detaches the trigger from a surrounding form, as Safari before 18.2 ignores
* `popovertarget` on a button that has a form owner.
*/
export function usePopoverTriggerPropsOnceHydrated(popoverId: string) {
return useHydrated() ? { popoverTarget: popoverId, form: "" } : {};
}
/**
@@ -106,7 +111,7 @@ export function SendouPopover({
eager?: boolean;
}) {
const popoverId = `${React.useId()}-popover`;
const popoverTarget = usePopoverTargetOnceHydrated(popoverId);
const popoverTriggerProps = usePopoverTriggerPropsOnceHydrated(popoverId);
const [isControlled] = React.useState(isOpen !== undefined);
const [uncontrolledOpen, setUncontrolledOpen] = React.useState(false);
@@ -190,7 +195,7 @@ export function SendouPopover({
onBlur={onBlur}
>
{React.cloneElement(trigger, {
popoverTarget,
...popoverTriggerProps,
"aria-haspopup": "dialog",
})}
</span>

View File

@@ -10,7 +10,7 @@ import { useTopLayerViewTransitionStyle } from "~/utils/view-transition";
import {
focusLeftTo,
isOwnToggle,
usePopoverTargetOnceHydrated,
usePopoverTriggerPropsOnceHydrated,
useShowPopoverOnOpen,
} from "./Popover";
import styles from "./Select.module.css";
@@ -146,7 +146,7 @@ export function SendouSelect<T extends object>({
const uid = React.useId();
const topLayerStyle = useTopLayerViewTransitionStyle();
const popoverId = `${uid}-select-popover`;
const popoverTarget = usePopoverTargetOnceHydrated(popoverId);
const popoverTriggerProps = usePopoverTriggerPropsOnceHydrated(popoverId);
const listboxId = `${uid}-select-listbox`;
const labelId = label ? `${uid}-select-label` : undefined;
const valueId = `${uid}-select-value`;
@@ -536,7 +536,7 @@ export function SendouSelect<T extends object>({
: undefined
}
data-required={isRequired || undefined}
popoverTarget={popoverTarget}
{...popoverTriggerProps}
onKeyDown={onTriggerKeyDown}
>
<span

View File

@@ -0,0 +1,4 @@
---
type: bug
---
Dropdowns inside forms (e.g. weapon and gear pickers) not opening on Safari older than 18.2