From 2f25bf61f532be4b202d20d575f6135b8129a406 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E6=9C=BA=E5=99=A8=E4=BA=BA?= Date: Tue, 9 Dec 2025 17:28:16 +0800 Subject: [PATCH 1/3] chore: init --- package.json | 2 +- src/Dialog/Content/Panel.tsx | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 90bea5ea..c5d71551 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "dependencies": { "@rc-component/motion": "^1.1.3", "@rc-component/portal": "^2.0.0", - "@rc-component/util": "^1.0.1", + "@rc-component/util": "^1.5.0", "classnames": "^2.2.6" }, "devDependencies": { diff --git a/src/Dialog/Content/Panel.tsx b/src/Dialog/Content/Panel.tsx index 1fbfcd92..53f91238 100644 --- a/src/Dialog/Content/Panel.tsx +++ b/src/Dialog/Content/Panel.tsx @@ -1,5 +1,6 @@ import classNames from 'classnames'; import { useComposeRef } from '@rc-component/util/lib/ref'; +import { useLockFocus } from '@rc-component/util/lib/Dom/focus'; import React, { useMemo, useRef } from 'react'; import { RefContext } from '../../context'; import type { IDialogPropTypes } from '../../IDialogPropTypes'; From f1231960cd43a34cea0411bce51bd9d141a8cc1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E6=9C=BA=E5=99=A8=E4=BA=BA?= Date: Tue, 9 Dec 2025 18:42:55 +0800 Subject: [PATCH 2/3] chore: focus refactor --- src/Dialog/Content/Panel.tsx | 39 ++++++++---------------------------- src/Dialog/index.tsx | 7 ------- 2 files changed, 8 insertions(+), 38 deletions(-) diff --git a/src/Dialog/Content/Panel.tsx b/src/Dialog/Content/Panel.tsx index 53f91238..0c7e6e1d 100644 --- a/src/Dialog/Content/Panel.tsx +++ b/src/Dialog/Content/Panel.tsx @@ -7,17 +7,6 @@ import type { IDialogPropTypes } from '../../IDialogPropTypes'; import MemoChildren from './MemoChildren'; import pickAttrs from '@rc-component/util/lib/pickAttrs'; -const sentinelStyle: React.CSSProperties = { - width: 0, - height: 0, - overflow: 'hidden', - outline: 'none', -}; - -const entityStyle: React.CSSProperties = { - outline: 'none', -}; - export interface PanelProps extends Omit { prefixCls: string; ariaId?: string; @@ -28,7 +17,6 @@ export interface PanelProps extends Omit { export type PanelRef = { focus: () => void; - changeActive: (next: boolean) => void; }; const Panel = React.forwardRef((props, ref) => { @@ -59,23 +47,14 @@ const Panel = React.forwardRef((props, ref) => { // ================================= Refs ================================= const { panel: panelRef } = React.useContext(RefContext); + const internalRef = useRef(null); + const mergedRef = useComposeRef(holderRef, panelRef, internalRef); - const mergedRef = useComposeRef(holderRef, panelRef); - - const sentinelStartRef = useRef(null); - const sentinelEndRef = useRef(null); + useLockFocus(visible, () => internalRef.current); React.useImperativeHandle(ref, () => ({ focus: () => { - sentinelStartRef.current?.focus({ preventScroll: true }); - }, - changeActive: (next) => { - const { activeElement } = document; - if (next && activeElement === sentinelEndRef.current) { - sentinelStartRef.current.focus({ preventScroll: true }); - } else if (!next && activeElement === sentinelStartRef.current) { - sentinelEndRef.current.focus({ preventScroll: true }); - } + internalRef.current?.focus({ preventScroll: true }); }, })); @@ -168,13 +147,11 @@ const Panel = React.forwardRef((props, ref) => { className={classNames(prefixCls, className)} onMouseDown={onMouseDown} onMouseUp={onMouseUp} + tabIndex={-1} > -
- - {modalRender ? modalRender(content) : content} - -
-
+ + {modalRender ? modalRender(content) : content} +
); }); diff --git a/src/Dialog/index.tsx b/src/Dialog/index.tsx index 3512e772..018e2446 100644 --- a/src/Dialog/index.tsx +++ b/src/Dialog/index.tsx @@ -47,7 +47,6 @@ const Dialog: React.FC = (props) => { if (process.env.NODE_ENV !== 'production') { ['wrapStyle', 'bodyStyle', 'maskStyle'].forEach((prop) => { - // (prop in props) && console.error(`Warning: ${prop} is deprecated, please use styles instead.`) warning(!(prop in props), `${prop} is deprecated, please use styles instead.`); }); if ('wrapClassName' in props) { @@ -148,11 +147,6 @@ const Dialog: React.FC = (props) => { onInternalClose(e); return; } - - // keep focus inside dialog - if (visible && e.keyCode === KeyCode.TAB) { - contentRef.current.changeActive(!e.shiftKey); - } } // ========================= Effect ========================= @@ -200,7 +194,6 @@ const Dialog: React.FC = (props) => { className={modalClassNames?.mask} />
Date: Tue, 9 Dec 2025 18:55:12 +0800 Subject: [PATCH 3/3] test: clean up --- tests/__snapshots__/index.spec.tsx.snap | 198 ++++++++++-------------- tests/index.spec.tsx | 29 ---- 2 files changed, 81 insertions(+), 146 deletions(-) diff --git a/tests/__snapshots__/index.spec.tsx.snap b/tests/__snapshots__/index.spec.tsx.snap index 8c47cc1e..dc679362 100644 --- a/tests/__snapshots__/index.spec.tsx.snap +++ b/tests/__snapshots__/index.spec.tsx.snap @@ -11,39 +11,30 @@ exports[`dialog add rootClassName and rootStyle should render correct 1`] = `