diff --git a/components/button/__tests__/index.test.tsx b/components/button/__tests__/index.test.tsx
index 56e6a6b1a9..f5ae30c8c5 100644
--- a/components/button/__tests__/index.test.tsx
+++ b/components/button/__tests__/index.test.tsx
@@ -474,4 +474,10 @@ describe('Button', () => {
'--ant-button-solid-text-color': '#000',
});
});
+
+ it('autoFocus should work', () => {
+ const { container } = render();
+
+ expect(container.querySelector('button')).toBe(document.activeElement);
+ });
});
diff --git a/components/button/button.tsx b/components/button/button.tsx
index 9abc657f41..aa98000d2d 100644
--- a/components/button/button.tsx
+++ b/components/button/button.tsx
@@ -1,7 +1,7 @@
-import React, { Children, createRef, useContext, useEffect, useMemo, useState } from 'react';
+import React, { Children, useContext, useEffect, useMemo, useRef, useState } from 'react';
import classNames from 'classnames';
import omit from 'rc-util/lib/omit';
-import { composeRef } from 'rc-util/lib/ref';
+import { useComposeRef } from 'rc-util/lib/ref';
import { devUseWarning } from '../_util/warning';
import Wave from '../_util/wave';
@@ -119,6 +119,7 @@ const InternalCompoundedButton = React.forwardRef<
classNames: customClassNames,
style: customStyle = {},
autoInsertSpace,
+ autoFocus,
...rest
} = props;
@@ -162,13 +163,15 @@ const InternalCompoundedButton = React.forwardRef<
const [hasTwoCNChar, setHasTwoCNChar] = useState(false);
- const internalRef = createRef();
+ const buttonRef = useRef();
- const buttonRef = composeRef(ref, internalRef);
+ const mergedRef = useComposeRef(ref, buttonRef);
const needInserted =
Children.count(children) === 1 && !icon && !isUnBorderedButtonVariant(mergedVariant);
+ // ========================= Effect =========================
+ // Loading
useEffect(() => {
let delayTimer: ReturnType | null = null;
if (loadingOrDelay.delay > 0) {
@@ -190,12 +193,13 @@ const InternalCompoundedButton = React.forwardRef<
return cleanupTimer;
}, [loadingOrDelay]);
+ // Two chinese characters check
useEffect(() => {
// FIXME: for HOC usage like
- if (!buttonRef || !(buttonRef as any).current || !mergedInsertSpace) {
+ if (!buttonRef.current || !mergedInsertSpace) {
return;
}
- const buttonText = (buttonRef as any).current.textContent;
+ const buttonText = buttonRef.current.textContent || '';
if (needInserted && isTwoCNChar(buttonText)) {
if (!hasTwoCNChar) {
setHasTwoCNChar(true);
@@ -203,8 +207,16 @@ const InternalCompoundedButton = React.forwardRef<
} else if (hasTwoCNChar) {
setHasTwoCNChar(false);
}
- }, [buttonRef]);
+ });
+ // Auto focus
+ useEffect(() => {
+ if (autoFocus && buttonRef.current) {
+ buttonRef.current.focus();
+ }
+ }, []);
+
+ // ========================= Events =========================
const handleClick = React.useCallback(
(e: React.MouseEvent) => {
// FIXME: https://github.com/ant-design/ant-design/issues/30207
@@ -217,6 +229,7 @@ const InternalCompoundedButton = React.forwardRef<
[props.onClick, innerLoading, mergedDisabled],
);
+ // ========================== Warn ==========================
if (process.env.NODE_ENV !== 'production') {
const warning = devUseWarning('Button');
@@ -233,6 +246,7 @@ const InternalCompoundedButton = React.forwardRef<
);
}
+ // ========================== Size ==========================
const { compactSize, compactItemClassnames } = useCompactItemContext(prefixCls, direction);
const sizeClassNameMap = { large: 'lg', small: 'sm', middle: undefined };
@@ -245,6 +259,7 @@ const InternalCompoundedButton = React.forwardRef<
const linkButtonRestProps = omit(rest as ButtonProps & { navigate: any }, ['navigate']);
+ // ========================= Render =========================
const classes = classNames(
prefixCls,
hashId,
@@ -301,7 +316,7 @@ const InternalCompoundedButton = React.forwardRef<
href={mergedDisabled ? undefined : linkButtonRestProps.href}
style={fullStyle}
onClick={handleClick}
- ref={buttonRef as React.Ref}
+ ref={mergedRef as React.Ref}
tabIndex={mergedDisabled ? -1 : 0}
>
{iconNode}
@@ -318,7 +333,7 @@ const InternalCompoundedButton = React.forwardRef<
style={fullStyle}
onClick={handleClick}
disabled={mergedDisabled}
- ref={buttonRef as React.Ref}
+ ref={mergedRef as React.Ref}
>
{iconNode}
{kids}