refactor: remove body dom

This commit is contained in:
aojunhao123 2025-05-11 15:31:36 +08:00
parent ac256ab599
commit d54a7d3a09
9 changed files with 2830 additions and 2848 deletions

View File

@ -7,7 +7,7 @@ const App: React.FC = () => {
const [visible, setVisible] = React.useState(false);
const [panelVisible, setPanelVisible] = React.useState(false);
const [date, setDate] = React.useState(dayjs());
const [date, setDate] = React.useState(() => dayjs());
return (
<Dropdown

View File

@ -65,11 +65,7 @@ const InternalFloatButton = React.forwardRef<FloatButtonElement, FloatButtonProp
// 虽然在 ts 中已经 omit 过了,但是为了防止多余的属性被透传进来,这里再 omit 一遍,以防万一
const badgeProps = omit(badge, ['title', 'children', 'status', 'text'] as any[]);
let buttonNode = (
<div className={`${prefixCls}-body`}>
<Content prefixCls={prefixCls} description={description} icon={icon} />
</div>
);
let buttonNode = <Content prefixCls={prefixCls} description={description} icon={icon} />;
if ('badge' in props) {
buttonNode = <Badge {...badgeProps}>{buttonNode}</Badge>;

View File

@ -9,34 +9,30 @@ exports[`FloatButtonGroup should correct render 1`] = `
type="button"
>
<div
class="ant-float-btn-body"
class="ant-float-btn-content"
>
<div
class="ant-float-btn-content"
class="ant-float-btn-icon"
>
<div
class="ant-float-btn-icon"
<span
aria-label="file-text"
class="anticon anticon-file-text"
role="img"
>
<span
aria-label="file-text"
class="anticon anticon-file-text"
role="img"
<svg
aria-hidden="true"
data-icon="file-text"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<svg
aria-hidden="true"
data-icon="file-text"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494zM504 618H320c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h184c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zM312 490v48c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H320c-4.4 0-8 3.6-8 8z"
/>
</svg>
</span>
</div>
<path
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494zM504 618H320c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h184c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zM312 490v48c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H320c-4.4 0-8 3.6-8 8z"
/>
</svg>
</span>
</div>
</div>
</button>
@ -45,34 +41,30 @@ exports[`FloatButtonGroup should correct render 1`] = `
type="button"
>
<div
class="ant-float-btn-body"
class="ant-float-btn-content"
>
<div
class="ant-float-btn-content"
class="ant-float-btn-icon"
>
<div
class="ant-float-btn-icon"
<span
aria-label="file-text"
class="anticon anticon-file-text"
role="img"
>
<span
aria-label="file-text"
class="anticon anticon-file-text"
role="img"
<svg
aria-hidden="true"
data-icon="file-text"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<svg
aria-hidden="true"
data-icon="file-text"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494zM504 618H320c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h184c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zM312 490v48c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H320c-4.4 0-8 3.6-8 8z"
/>
</svg>
</span>
</div>
<path
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494zM504 618H320c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h184c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zM312 490v48c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H320c-4.4 0-8 3.6-8 8z"
/>
</svg>
</span>
</div>
</div>
</button>
@ -81,34 +73,30 @@ exports[`FloatButtonGroup should correct render 1`] = `
type="button"
>
<div
class="ant-float-btn-body"
class="ant-float-btn-content"
>
<div
class="ant-float-btn-content"
class="ant-float-btn-icon"
>
<div
class="ant-float-btn-icon"
<span
aria-label="file-text"
class="anticon anticon-file-text"
role="img"
>
<span
aria-label="file-text"
class="anticon anticon-file-text"
role="img"
<svg
aria-hidden="true"
data-icon="file-text"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<svg
aria-hidden="true"
data-icon="file-text"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494zM504 618H320c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h184c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zM312 490v48c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H320c-4.4 0-8 3.6-8 8z"
/>
</svg>
</span>
</div>
<path
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494zM504 618H320c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h184c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zM312 490v48c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H320c-4.4 0-8 3.6-8 8z"
/>
</svg>
</span>
</div>
</div>
</button>

View File

@ -6,34 +6,30 @@ exports[`FloatButton rtl render component should be rendered correctly in RTL di
type="button"
>
<div
class="ant-float-btn-body"
class="ant-float-btn-content"
>
<div
class="ant-float-btn-content"
class="ant-float-btn-icon"
>
<div
class="ant-float-btn-icon"
<span
aria-label="file-text"
class="anticon anticon-file-text"
role="img"
>
<span
aria-label="file-text"
class="anticon anticon-file-text"
role="img"
<svg
aria-hidden="true"
data-icon="file-text"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<svg
aria-hidden="true"
data-icon="file-text"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494zM504 618H320c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h184c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zM312 490v48c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H320c-4.4 0-8 3.6-8 8z"
/>
</svg>
</span>
</div>
<path
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494zM504 618H320c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h184c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zM312 490v48c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H320c-4.4 0-8 3.6-8 8z"
/>
</svg>
</span>
</div>
</div>
</button>
@ -45,34 +41,30 @@ exports[`FloatButton should correct render 1`] = `
type="button"
>
<div
class="ant-float-btn-body"
class="ant-float-btn-content"
>
<div
class="ant-float-btn-content"
class="ant-float-btn-icon"
>
<div
class="ant-float-btn-icon"
<span
aria-label="file-text"
class="anticon anticon-file-text"
role="img"
>
<span
aria-label="file-text"
class="anticon anticon-file-text"
role="img"
<svg
aria-hidden="true"
data-icon="file-text"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<svg
aria-hidden="true"
data-icon="file-text"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494zM504 618H320c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h184c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zM312 490v48c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H320c-4.4 0-8 3.6-8 8z"
/>
</svg>
</span>
</div>
<path
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494zM504 618H320c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h184c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zM312 490v48c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H320c-4.4 0-8 3.6-8 8z"
/>
</svg>
</span>
</div>
</div>
</button>

View File

@ -67,7 +67,7 @@ describe('FloatButton', () => {
it('tooltip should support number `0`', async () => {
jest.useFakeTimers();
const { container } = render(<FloatButton tooltip={0} />);
fireEvent.mouseEnter(container.querySelector<HTMLDivElement>('.ant-float-btn-body')!);
fireEvent.mouseEnter(container.querySelector<HTMLDivElement>('.ant-float-btn-content')!);
await waitFakeTimer();
const element = container.querySelector('.ant-tooltip')?.querySelector('.ant-tooltip-inner');
expect(element?.textContent).toBe('0');
@ -77,7 +77,7 @@ describe('FloatButton', () => {
it('tooltip should support tooltipProps', async () => {
jest.useFakeTimers();
const { container } = render(<FloatButton tooltip={{ title: 'hi' }} />);
fireEvent.mouseEnter(container.querySelector<HTMLDivElement>('.ant-float-btn-body')!);
fireEvent.mouseEnter(container.querySelector<HTMLDivElement>('.ant-float-btn-content')!);
await waitFakeTimer();
const element = container.querySelector('.ant-tooltip')?.querySelector('.ant-tooltip-inner');
expect(element?.textContent).toBe('hi');

View File

@ -4,7 +4,24 @@ import { FloatButton } from 'antd';
const App: React.FC = () => (
<>
<FloatButton shape="circle" style={{ insetInlineEnd: 24 + 70 + 70 }} badge={{ dot: true }} />
<FloatButton
shape="circle"
style={{ insetInlineEnd: 24 + 70 + 70 + 70 + 70 }}
badge={{ dot: true }}
/>
<FloatButton
style={{ insetInlineEnd: 24 + 70 + 70 + 70 }}
shape="square"
badge={{ count: 5 }}
/>
<FloatButton.Group shape="square" style={{ insetInlineEnd: 24 + 70 + 70 }}>
<FloatButton
href="https://ant.design/index-cn"
tooltip={<div>custom badge color</div>}
badge={{ count: 5, color: 'blue' }}
/>
<FloatButton badge={{ count: 5 }} />
</FloatButton.Group>
<FloatButton.Group shape="circle" style={{ insetInlineEnd: 24 + 70 }}>
<FloatButton
href="https://ant.design/index-cn"

View File

@ -211,6 +211,22 @@ const floatButtonGroupStyle: GenerateStyle<FloatButtonToken, CSSObject> = (token
},
},
},
[`${componentCls}-square${componentCls}-default`]: {
'&:hover': {
backgroundColor: token.floatButtonBackgroundColor,
[`${componentCls}-content`]: {
backgroundColor: token.colorFillContent,
},
},
},
[`${componentCls}-square${componentCls}-primary`]: {
'&:hover': {
backgroundColor: token.colorPrimary,
[`${componentCls}-content`]: {
backgroundColor: token.colorPrimaryHover,
},
},
},
[`${groupPrefixCls}-wrap`]: {
borderRadius: borderRadiusLG,
boxShadow: token.boxShadowSecondary,
@ -218,7 +234,7 @@ const floatButtonGroupStyle: GenerateStyle<FloatButtonToken, CSSObject> = (token
boxShadow: 'none',
borderRadius: 0,
padding: floatButtonBodyPadding,
[`${componentCls}-body`]: {
[`${componentCls}-content`]: {
width: token.floatButtonBodySize,
height: token.floatButtonBodySize,
borderRadius: borderRadiusSM,
@ -267,7 +283,7 @@ const floatButtonGroupStyle: GenerateStyle<FloatButtonToken, CSSObject> = (token
[`${componentCls}-square`]: {
boxShadow: 'none',
padding: floatButtonBodyPadding,
[`${componentCls}-body`]: {
[`${componentCls}-content`]: {
width: token.floatButtonBodySize,
height: token.floatButtonBodySize,
borderRadius: borderRadiusSM,
@ -295,6 +311,9 @@ const sharedFloatButtonStyle: GenerateStyle<FloatButtonToken, CSSObject> = (toke
return {
[componentCls]: {
...resetComponent(token),
padding: `${unit(calc(floatButtonBodyPadding).div(2).equal())} ${unit(
floatButtonBodyPadding,
)}`,
border: 'none',
position: 'fixed',
cursor: 'pointer',
@ -305,6 +324,7 @@ const sharedFloatButtonStyle: GenerateStyle<FloatButtonToken, CSSObject> = (toke
display: 'block',
width: floatButtonSize,
height: floatButtonSize,
minHeight: floatButtonSize,
insetInlineEnd: token.floatButtonInsetInlineEnd,
bottom: token.floatButtonInsetBlockEnd,
boxShadow: token.boxShadowSecondary,
@ -322,35 +342,26 @@ const sharedFloatButtonStyle: GenerateStyle<FloatButtonToken, CSSObject> = (toke
[`${antCls}-badge-count`]: {
transform: 'translate(0, 0)',
transformOrigin: 'center',
top: calc(badgeOffset).mul(-1).equal(),
insetInlineEnd: calc(badgeOffset).mul(-1).equal(),
top: calc(badgeOffset).add(calc(floatButtonBodyPadding).div(2)).mul(-1).equal(),
insetInlineEnd: calc(badgeOffset).add(floatButtonBodyPadding).mul(-1).equal(),
},
},
[`${componentCls}-body`]: {
[`${componentCls}-content`]: {
width: '100%',
height: '100%',
transition: `all ${token.motionDurationMid}`,
borderRadius: '50%',
textAlign: 'center',
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
transition: `all ${token.motionDurationMid}`,
[`${componentCls}-content`]: {
overflow: 'hidden',
[`${componentCls}-icon`]: {
textAlign: 'center',
minHeight: floatButtonSize,
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
padding: `${unit(calc(floatButtonBodyPadding).div(2).equal())} ${unit(
floatButtonBodyPadding,
)}`,
[`${componentCls}-icon`]: {
textAlign: 'center',
margin: 'auto',
width: floatButtonIconSize,
fontSize: floatButtonIconSize,
lineHeight: 1,
},
margin: 'auto',
width: floatButtonIconSize,
fontSize: floatButtonIconSize,
lineHeight: 1,
},
},
},
@ -363,71 +374,73 @@ const sharedFloatButtonStyle: GenerateStyle<FloatButtonToken, CSSObject> = (toke
borderRadius: '50%',
[`${antCls}-badge`]: {
[`${antCls}-badge-dot`]: {
top: dotOffsetInCircle,
insetInlineEnd: dotOffsetInCircle,
top: unit(
token
.calc(dotOffsetInCircle)
.sub(token.calc(token.floatButtonBodyPadding).div(2))
.equal(),
),
insetInlineEnd: unit(
token.calc(dotOffsetInCircle).sub(token.floatButtonBodyPadding).equal(),
),
},
},
[`${componentCls}-body`]: {
borderRadius: '50%',
},
},
[`${componentCls}-square`]: {
height: 'auto',
minHeight: floatButtonSize,
borderRadius: borderRadiusLG,
[`${antCls}-badge`]: {
[`${antCls}-badge-dot`]: {
top: dotOffsetInSquare,
insetInlineEnd: dotOffsetInSquare,
top: unit(
token
.calc(dotOffsetInSquare)
.sub(token.calc(token.floatButtonBodyPadding).div(2))
.equal(),
),
insetInlineEnd: unit(
token.calc(dotOffsetInSquare).sub(token.floatButtonBodyPadding).equal(),
),
},
},
[`${componentCls}-body`]: {
height: 'auto',
[`${componentCls}-content`]: {
borderRadius: borderRadiusLG,
},
},
[`${componentCls}-default`]: {
backgroundColor: token.floatButtonBackgroundColor,
transition: `background-color ${token.motionDurationMid}`,
[`${componentCls}-body`]: {
backgroundColor: token.floatButtonBackgroundColor,
transition: `background-color ${token.motionDurationMid}`,
'&:hover': {
backgroundColor: token.colorFillContent,
'&:hover': {
backgroundColor: token.colorFillContent,
},
[`${componentCls}-content`]: {
[`${componentCls}-icon`]: {
color: token.colorText,
},
[`${componentCls}-content`]: {
[`${componentCls}-icon`]: {
color: token.colorText,
},
[`${componentCls}-description`]: {
display: 'flex',
alignItems: 'center',
lineHeight: unit(token.fontSizeLG),
color: token.colorText,
fontSize: token.fontSizeSM,
},
[`${componentCls}-description`]: {
display: 'flex',
alignItems: 'center',
lineHeight: unit(token.fontSizeLG),
color: token.colorText,
fontSize: token.fontSizeSM,
},
},
},
[`${componentCls}-primary`]: {
backgroundColor: token.colorPrimary,
[`${componentCls}-body`]: {
backgroundColor: token.colorPrimary,
'&:hover': {
backgroundColor: token.colorPrimaryHover,
},
[`${componentCls}-content`]: {
transition: `background-color ${token.motionDurationMid}`,
'&:hover': {
backgroundColor: token.colorPrimaryHover,
[`${componentCls}-icon`]: {
color: token.colorTextLightSolid,
},
[`${componentCls}-content`]: {
[`${componentCls}-icon`]: {
color: token.colorTextLightSolid,
},
[`${componentCls}-description`]: {
display: 'flex',
alignItems: 'center',
lineHeight: unit(token.fontSizeLG),
color: token.colorTextLightSolid,
fontSize: token.fontSizeSM,
},
[`${componentCls}-description`]: {
display: 'flex',
alignItems: 'center',
lineHeight: unit(token.fontSizeLG),
color: token.colorTextLightSolid,
fontSize: token.fontSizeSM,
},
},
},