Skip to content

Commit 7bacf23

Browse files
committed
[core] Refine OpenChangeReason
1 parent 89ee0e7 commit 7bacf23

34 files changed

+88
-71
lines changed

docs/reference/generated/alert-dialog-root.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"description": "Whether the dialog is currently open."
1313
},
1414
"onOpenChange": {
15-
"type": "((open: boolean, event: Event | undefined, reason: OpenChangeReason | undefined) => void)",
15+
"type": "((open: boolean, event: Event | undefined, reason: {} | undefined) => void)",
1616
"description": "Event handler called when the dialog is opened or closed."
1717
},
1818
"actionsRef": {

docs/reference/generated/dialog-root.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"description": "Whether the dialog is currently open."
1313
},
1414
"onOpenChange": {
15-
"type": "((open: boolean, event: Event | undefined, reason: OpenChangeReason | undefined) => void)",
15+
"type": "((open: boolean, event: Event | undefined, reason: {} | undefined) => void)",
1616
"description": "Event handler called when the dialog is opened or closed."
1717
},
1818
"actionsRef": {

docs/reference/generated/menu-root.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"description": "Whether the menu is currently open."
1313
},
1414
"onOpenChange": {
15-
"type": "((open: boolean, event: Event | undefined, reason: OpenChangeReason | undefined) => void)",
15+
"type": "((open: boolean, event: Event | undefined, reason: {} | undefined) => void)",
1616
"description": "Event handler called when the menu is opened or closed."
1717
},
1818
"actionsRef": {

docs/reference/generated/popover-root.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"description": "Whether the popover is currently open."
1313
},
1414
"onOpenChange": {
15-
"type": "((open: boolean, event: Event | undefined, reason: OpenChangeReason | undefined) => void)",
15+
"type": "((open: boolean, event: Event | undefined, reason: {} | undefined) => void)",
1616
"description": "Event handler called when the popover is opened or closed."
1717
},
1818
"actionsRef": {

docs/reference/generated/preview-card-root.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"description": "Whether the preview card is currently open."
1313
},
1414
"onOpenChange": {
15-
"type": "((open: boolean, event: Event | undefined, reason: OpenChangeReason | undefined) => void)",
15+
"type": "((open: boolean, event: Event | undefined, reason: BaseOpenChangeReason | undefined) => void)",
1616
"description": "Event handler called when the preview card is opened or closed."
1717
},
1818
"actionsRef": {

docs/reference/generated/select-root.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
"description": "Whether the select menu is currently open."
3030
},
3131
"onOpenChange": {
32-
"type": "((open: boolean, event: Event | undefined, reason: OpenChangeReason | undefined) => void)",
32+
"type": "((open: boolean, event: Event | undefined, reason: {} | undefined) => void)",
3333
"description": "Event handler called when the select menu is opened or closed."
3434
},
3535
"actionsRef": {

docs/reference/generated/tooltip-root.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"description": "Whether the tooltip is currently open."
1313
},
1414
"onOpenChange": {
15-
"type": "((open: boolean, event: Event | undefined, reason: OpenChangeReason | undefined) => void)",
15+
"type": "((open: boolean, event: Event | undefined, reason: {} | undefined) => void)",
1616
"description": "Event handler called when the tooltip is opened or closed."
1717
},
1818
"actionsRef": {

packages/react/src/dialog/close/useDialogClose.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22
import * as React from 'react';
33
import { useButton } from '../../use-button/useButton';
44
import { mergeProps } from '../../merge-props';
5-
import { OpenChangeReason } from '../../utils/translateOpenChangeReason';
65
import type { GenericHTMLProps } from '../../utils/types';
76
import { useEventCallback } from '../../utils/useEventCallback';
7+
import { OpenChangeReason } from '../root/useDialogRoot';
88

99
export function useDialogClose(params: useDialogClose.Parameters): useDialogClose.ReturnValue {
1010
const { open, setOpen, rootRef: externalRef, disabled } = params;
1111

1212
const handleClick = useEventCallback((event: React.MouseEvent) => {
1313
if (open) {
14-
setOpen(false, event.nativeEvent, 'click');
14+
setOpen(false, event.nativeEvent, 'close-button');
1515
}
1616
});
1717

packages/react/src/dialog/popup/useDialogPopup.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
import * as React from 'react';
33
import { useForkRef } from '../../utils/useForkRef';
44
import { mergeProps } from '../../merge-props';
5-
import { type InteractionType } from '../../utils/useEnhancedClickHandler';
6-
import { GenericHTMLProps } from '../../utils/types';
7-
import { type OpenChangeReason } from '../../utils/translateOpenChangeReason';
5+
import type { InteractionType } from '../../utils/useEnhancedClickHandler';
6+
import type { GenericHTMLProps } from '../../utils/types';
7+
import type { OpenChangeReason } from '../root/useDialogRoot';
88

99
export function useDialogPopup(parameters: useDialogPopup.Parameters): useDialogPopup.ReturnValue {
1010
const {

packages/react/src/dialog/root/useDialogRoot.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ import { useOpenInteractionType } from '../../utils/useOpenInteractionType';
2020
import { mergeProps } from '../../merge-props';
2121
import { useOpenChangeComplete } from '../../utils/useOpenChangeComplete';
2222
import {
23-
type OpenChangeReason,
23+
type BaseOpenChangeReason,
2424
translateOpenChangeReason,
2525
} from '../../utils/translateOpenChangeReason';
2626
import { useIOSKeyboardSlideFix } from '../../utils/useIOSKeyboardSlideFix';
2727

28+
export type OpenChangeReason = BaseOpenChangeReason | 'close-button';
29+
2830
export function useDialogRoot(params: useDialogRoot.Parameters): useDialogRoot.ReturnValue {
2931
const {
3032
defaultOpen,

packages/react/src/menu/backdrop/MenuBackdrop.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ const MenuBackdrop = React.forwardRef(function MenuBackdrop(
4545
role: 'presentation',
4646
hidden: !mounted,
4747
style: {
48-
pointerEvents: openReason === 'hover' ? 'none' : undefined,
48+
pointerEvents: openReason === 'trigger-hover' ? 'none' : undefined,
4949
userSelect: 'none',
5050
WebkitUserSelect: 'none',
5151
},

packages/react/src/menu/popup/useMenuPopup.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
'use client';
22
import * as React from 'react';
33
import type { FloatingEvents } from '@floating-ui/react';
4-
import type { OpenChangeReason } from '../../utils/translateOpenChangeReason';
4+
import type { OpenChangeReason } from '../root/useMenuRoot';
55

66
export function useMenuPopup(parameters: useMenuPopup.Parameters): useMenuPopup.ReturnValue {
77
const { menuEvents, setOpen } = parameters;
88

99
React.useEffect(() => {
1010
function handleClose(event: Event | undefined) {
11-
setOpen(false, event, undefined);
11+
setOpen(false, event, 'item-select');
1212
}
1313

1414
menuEvents.on('close', handleClose);

packages/react/src/menu/positioner/MenuPositioner.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ const MenuPositioner = React.forwardRef(function MenuPositioner(
132132

133133
return (
134134
<MenuPositionerContext.Provider value={contextValue}>
135-
{mounted && modal && openReason !== 'hover' && parentNodeId === null && (
135+
{mounted && modal && openReason !== 'trigger-hover' && parentNodeId === null && (
136136
<InternalBackdrop inert={inertValue(!open)} />
137137
)}
138138
<FloatingNode id={nodeId}>

packages/react/src/menu/root/MenuRoot.tsx

+1-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ import * as React from 'react';
33
import { FloatingTree } from '@floating-ui/react';
44
import { useDirection } from '../../direction-provider/DirectionContext';
55
import { MenuRootContext, useMenuRootContext } from './MenuRootContext';
6-
import { MenuOrientation, useMenuRoot } from './useMenuRoot';
7-
import type { OpenChangeReason } from '../../utils/translateOpenChangeReason';
6+
import { MenuOrientation, OpenChangeReason, useMenuRoot } from './useMenuRoot';
87

98
/**
109
* Groups all parts of the menu.

packages/react/src/menu/root/MenuRootContext.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use client';
22
import * as React from 'react';
3-
import type { useMenuRoot } from './useMenuRoot';
4-
import type { OpenChangeReason } from '../../utils/translateOpenChangeReason';
3+
import type { OpenChangeReason, useMenuRoot } from './useMenuRoot';
54

65
export interface MenuRootContext extends useMenuRoot.ReturnValue {
76
disabled: boolean;

packages/react/src/menu/root/useMenuRoot.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,12 @@ import { useOpenChangeComplete } from '../../utils/useOpenChangeComplete';
2222
import type { TextDirection } from '../../direction-provider/DirectionContext';
2323
import { useScrollLock } from '../../utils/useScrollLock';
2424
import {
25-
type OpenChangeReason,
25+
type BaseOpenChangeReason,
2626
translateOpenChangeReason,
2727
} from '../../utils/translateOpenChangeReason';
2828

2929
const EMPTY_ARRAY: never[] = [];
30+
export type OpenChangeReason = BaseOpenChangeReason | 'item-select' | 'cancel-open';
3031

3132
export function useMenuRoot(parameters: useMenuRoot.Parameters): useMenuRoot.ReturnValue {
3233
const {
@@ -77,7 +78,7 @@ export function useMenuRoot(parameters: useMenuRoot.Parameters): useMenuRoot.Ret
7778
const { mounted, setMounted, transitionStatus } = useTransitionStatus(open);
7879

7980
useScrollLock({
80-
enabled: open && modal && openReason !== 'hover',
81+
enabled: open && modal && openReason !== 'trigger-hover',
8182
mounted,
8283
open,
8384
referenceElement: positionerElement,
@@ -172,7 +173,7 @@ export function useMenuRoot(parameters: useMenuRoot.Parameters): useMenuRoot.Ret
172173
});
173174

174175
const hover = useHover(floatingRootContext, {
175-
enabled: hoverEnabled && openOnHover && !disabled && openReason !== 'click',
176+
enabled: hoverEnabled && openOnHover && !disabled && openReason !== 'trigger-press',
176177
handleClose: safePolygon({ blockPointerEvents: true }),
177178
mouseOnly: true,
178179
move: nested,

packages/react/src/menu/trigger/useMenuTrigger.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { GenericHTMLProps } from '../../utils/types';
77
import { mergeProps } from '../../merge-props';
88
import { ownerDocument } from '../../utils/owner';
99
import { getPseudoElementBounds } from '../../utils/getPseudoElementBounds';
10-
import type { OpenChangeReason } from '../../utils/translateOpenChangeReason';
10+
import { OpenChangeReason } from '../root/useMenuRoot';
1111

1212
export function useMenuTrigger(parameters: useMenuTrigger.Parameters): useMenuTrigger.ReturnValue {
1313
const BOUNDARY_OFFSET = 2;
@@ -90,7 +90,7 @@ export function useMenuTrigger(parameters: useMenuTrigger.Parameters): useMenuTr
9090
return;
9191
}
9292

93-
setOpen(false, mouseEvent, undefined);
93+
setOpen(false, mouseEvent, 'cancel-open');
9494
}
9595

9696
doc.addEventListener('mouseup', handleMouseUp, { once: true });

packages/react/src/popover/backdrop/PopoverBackdrop.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ const PopoverBackdrop = React.forwardRef(function PopoverBackdrop(
4343
role: 'presentation',
4444
hidden: !mounted,
4545
style: {
46-
pointerEvents: openReason === 'hover' ? 'none' : undefined,
46+
pointerEvents: openReason === 'trigger-hover' ? 'none' : undefined,
4747
userSelect: 'none',
4848
WebkitUserSelect: 'none',
4949
},

packages/react/src/popover/close/PopoverClose.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ const PopoverClose = React.forwardRef(function PopoverClose(
2222
ref: forwardedRef,
2323
props: [
2424
{
25-
onClick() {
26-
setOpen(false, undefined, undefined);
25+
onClick(event) {
26+
setOpen(false, event.nativeEvent, 'close-button');
2727
},
2828
},
2929
elementProps,

packages/react/src/popover/popup/PopoverPopup.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ const PopoverPopup = React.forwardRef(function PopoverPopup(
9191
<FloatingFocusManager
9292
context={positioner.context}
9393
modal={modal === 'trap-focus'}
94-
disabled={!mounted || openReason === 'hover'}
94+
disabled={!mounted || openReason === 'trigger-hover'}
9595
initialFocus={resolvedInitialFocus}
9696
returnFocus={finalFocus}
9797
>

packages/react/src/popover/positioner/PopoverPositioner.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ const PopoverPositioner = React.forwardRef(function PopoverPositioner(
8686

8787
return (
8888
<PopoverPositionerContext.Provider value={positioner}>
89-
{mounted && modal === true && openReason !== 'hover' && openMethod !== 'touch' && (
89+
{mounted && modal === true && openReason !== 'trigger-hover' && openMethod !== 'touch' && (
9090
<InternalBackdrop inert={inertValue(!open)} />
9191
)}
9292
{renderElement()}

packages/react/src/popover/root/PopoverRootContext.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type { FloatingRootContext } from '@floating-ui/react';
44
import type { TransitionStatus } from '../../utils/useTransitionStatus';
55
import type { GenericHTMLProps } from '../../utils/types';
66
import type { InteractionType } from '../../utils/useEnhancedClickHandler';
7-
import type { OpenChangeReason } from '../../utils/translateOpenChangeReason';
7+
import { OpenChangeReason } from './usePopoverRoot';
88

99
export interface PopoverRootContext {
1010
open: boolean;

packages/react/src/popover/root/usePopoverRoot.ts

+10-4
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@ import { mergeProps } from '../../merge-props';
2121
import { useOpenInteractionType } from '../../utils/useOpenInteractionType';
2222
import {
2323
translateOpenChangeReason,
24-
type OpenChangeReason,
24+
type BaseOpenChangeReason,
2525
} from '../../utils/translateOpenChangeReason';
2626
import { useOpenChangeComplete } from '../../utils/useOpenChangeComplete';
2727
import { PATIENT_CLICK_THRESHOLD } from '../../utils/constants';
2828
import { useScrollLock } from '../../utils/useScrollLock';
2929

30+
export type OpenChangeReason = BaseOpenChangeReason | 'close-button';
31+
3032
export function usePopoverRoot(params: usePopoverRoot.Parameters): usePopoverRoot.ReturnValue {
3133
const {
3234
open: externalOpen,
@@ -65,7 +67,7 @@ export function usePopoverRoot(params: usePopoverRoot.Parameters): usePopoverRoo
6567
const { mounted, setMounted, transitionStatus } = useTransitionStatus(open);
6668

6769
useScrollLock({
68-
enabled: open && modal === true && openReason !== 'hover',
70+
enabled: open && modal === true && openReason !== 'trigger-hover',
6971
mounted,
7072
open,
7173
referenceElement: positionerElement,
@@ -155,7 +157,7 @@ export function usePopoverRoot(params: usePopoverRoot.Parameters): usePopoverRoo
155157
const computedRestMs = delayWithDefault;
156158

157159
const hover = useHover(context, {
158-
enabled: openOnHover && (openMethod !== 'touch' || openReason !== 'click'),
160+
enabled: openOnHover && (openMethod !== 'touch' || openReason !== 'trigger-press'),
159161
mouseOnly: true,
160162
move: false,
161163
handleClose: safePolygon({ blockPointerEvents: true }),
@@ -287,7 +289,11 @@ export namespace usePopoverRoot {
287289

288290
export interface ReturnValue {
289291
open: boolean;
290-
setOpen: (open: boolean, event?: Event, reason?: OpenChangeReason) => void;
292+
setOpen: (
293+
open: boolean,
294+
event: Event | undefined,
295+
reason: OpenChangeReason | undefined,
296+
) => void;
291297
mounted: boolean;
292298
setMounted: React.Dispatch<React.SetStateAction<boolean>>;
293299
transitionStatus: TransitionStatus;

packages/react/src/popover/trigger/PopoverTrigger.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ const PopoverTrigger = React.forwardRef(function PopoverTrigger(
4040
const customStyleHookMapping: CustomStyleHookMapping<{ open: boolean }> = React.useMemo(
4141
() => ({
4242
open(value) {
43-
if (value && openReason === 'click') {
43+
if (value && openReason === 'trigger-press') {
4444
return pressableTriggerOpenStateMapping.open(value);
4545
}
4646

packages/react/src/preview-card/root/PreviewCardContext.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@ import * as React from 'react';
33
import type { FloatingRootContext } from '@floating-ui/react';
44
import type { TransitionStatus } from '../../utils/useTransitionStatus';
55
import type { GenericHTMLProps } from '../../utils/types';
6-
import type { OpenChangeReason } from '../../utils/translateOpenChangeReason';
6+
import type { BaseOpenChangeReason } from '../../utils/translateOpenChangeReason';
77

88
export interface PreviewCardRootContext {
99
open: boolean;
10-
setOpen: (open: boolean, event?: Event, reason?: OpenChangeReason) => void;
10+
setOpen: (
11+
open: boolean,
12+
event: Event | undefined,
13+
reason: BaseOpenChangeReason | undefined,
14+
) => void;
1115
setTriggerElement: (el: Element | null) => void;
1216
positionerElement: HTMLElement | null;
1317
setPositionerElement: (el: HTMLElement | null) => void;

packages/react/src/preview-card/root/usePreviewCardRoot.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import type { GenericHTMLProps } from '../../utils/types';
1717
import type { TransitionStatus } from '../../utils/useTransitionStatus';
1818
import {
1919
translateOpenChangeReason,
20-
type OpenChangeReason,
20+
type BaseOpenChangeReason as OpenChangeReason,
2121
} from '../../utils/translateOpenChangeReason';
2222
import { useOpenChangeComplete } from '../../utils/useOpenChangeComplete';
2323

@@ -204,7 +204,11 @@ export namespace usePreviewCardRoot {
204204

205205
export interface ReturnValue {
206206
open: boolean;
207-
setOpen: (value: boolean, event?: Event, reason?: OpenChangeReason) => void;
207+
setOpen: (
208+
value: boolean,
209+
event: Event | undefined,
210+
reason: OpenChangeReason | undefined,
211+
) => void;
208212
mounted: boolean;
209213
setMounted: React.Dispatch<React.SetStateAction<boolean>>;
210214
getRootTriggerProps: (externalProps?: GenericHTMLProps) => GenericHTMLProps;

packages/react/src/select/item/useSelectItem.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export function useSelectItem(params: useSelectItem.Parameters): useSelectItem.R
4848

4949
const commitSelection = useEventCallback((event: MouseEvent) => {
5050
handleSelect(event);
51-
setOpen(false, event, undefined);
51+
setOpen(false, event, 'item-select');
5252
});
5353

5454
const handlePopupLeave = useEventCallback(() => {

packages/react/src/select/popup/useSelectPopup.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,8 @@ export function useSelectPopup(): useSelectPopup.ReturnValue {
227227

228228
const win = ownerWindow(positionerElement);
229229

230-
function handleResize() {
231-
setOpen(false, undefined, undefined);
230+
function handleResize(event: Event) {
231+
setOpen(false, event, 'window-resize');
232232
}
233233

234234
win.addEventListener('resize', handleResize);

packages/react/src/select/root/SelectRootContext.ts

+2-6
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useFloatingRootContext } from '@floating-ui/react';
33
import type { TransitionStatus } from '../../utils/useTransitionStatus';
44
import type { useFieldControlValidation } from '../../field/control/useFieldControlValidation';
55
import type { GenericHTMLProps } from '../../utils/types';
6-
import type { OpenChangeReason } from '../../utils/translateOpenChangeReason';
6+
import type { OpenChangeReason } from './useSelectRoot';
77

88
export interface SelectRootContext {
99
name: string | undefined;
@@ -13,11 +13,7 @@ export interface SelectRootContext {
1313
value: any;
1414
setValue: (nextValue: any, event?: Event) => void;
1515
open: boolean;
16-
setOpen: (
17-
nextOpen: boolean,
18-
event: Event | undefined,
19-
reason: OpenChangeReason | undefined,
20-
) => void;
16+
setOpen: (open: boolean, event: Event | undefined, reason: OpenChangeReason | undefined) => void;
2117
mounted: boolean;
2218
setMounted: React.Dispatch<React.SetStateAction<boolean>>;
2319
transitionStatus: TransitionStatus;

0 commit comments

Comments
 (0)