feat: FloatButton PurePanel (#38199)

* refactor: Popout FloatButton component

* test: Update snapshot

* docs: add BackTop

* test: Update snapshot

* chore: fix compile

* chore: fix ts

* chore: pure panel size
This commit is contained in:
二货爱吃白萝卜 2022-10-24 23:15:39 +08:00 committed by GitHub
parent 458cb84a89
commit d08deeeb8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 1030 additions and 118 deletions

View File

@ -4,7 +4,7 @@ import CSSMotion from 'rc-motion';
import addEventListener from 'rc-util/lib/Dom/addEventListener';
import useMergedState from 'rc-util/lib/hooks/useMergedState';
import React, { memo, useContext, useEffect, useMemo, useRef } from 'react';
import FloatButton, { floatButtonPrefixCls } from '.';
import FloatButton, { floatButtonPrefixCls } from './FloatButton';
import type { ConfigConsumerProps } from '../config-provider';
import { ConfigContext } from '../config-provider';
import getScroll from '../_util/getScroll';

View File

@ -0,0 +1,103 @@
import classNames from 'classnames';
import React, { useContext, useMemo } from 'react';
import type { ConfigConsumerProps } from '../config-provider';
import { ConfigContext } from '../config-provider';
import useStyle from './style';
import Tooltip from '../tooltip';
import Content from './FloatButtonContent';
import type {
CompoundedComponent,
FloatButtonContentProps,
FloatButtonProps,
FloatButtonShape,
} from './interface';
import FloatButtonGroupContext from './context';
import warning from '../_util/warning';
export const floatButtonPrefixCls = 'float-btn';
const FloatButton: React.ForwardRefRenderFunction<
HTMLAnchorElement | HTMLButtonElement,
FloatButtonProps
> = (props, ref) => {
const {
prefixCls: customizePrefixCls,
className,
type = 'default',
shape = 'circle',
icon,
description,
tooltip,
...restProps
} = props;
const { getPrefixCls, direction } = useContext<ConfigConsumerProps>(ConfigContext);
const groupShape = useContext<FloatButtonShape | undefined>(FloatButtonGroupContext);
const prefixCls = getPrefixCls(floatButtonPrefixCls, customizePrefixCls);
const [wrapSSR, hashId] = useStyle(prefixCls);
const mergeShape = groupShape || shape;
const classString = classNames(
hashId,
prefixCls,
className,
`${prefixCls}-${type}`,
`${prefixCls}-${mergeShape}`,
{
[`${prefixCls}-rtl`]: direction === 'rtl',
},
);
const contentProps = useMemo<FloatButtonContentProps>(
() => ({ prefixCls, description, icon, type }),
[prefixCls, description, icon, type],
);
const buttonNode = tooltip ? (
<Tooltip title={tooltip} placement="left">
<div className={`${prefixCls}-body`}>
<Content {...contentProps} />
</div>
</Tooltip>
) : (
<div className={`${prefixCls}-body`}>
<Content {...contentProps} />
</div>
);
if (process.env.NODE_ENV !== 'production') {
warning(
!(shape === 'circle' && description),
'FloatButton',
'supported only when `shape` is `square`. Due to narrow space for text, short sentence is recommended.',
);
}
return wrapSSR(
props.href ? (
<a ref={ref as React.LegacyRef<HTMLAnchorElement>} {...restProps} className={classString}>
{buttonNode}
</a>
) : (
<button
ref={ref as React.LegacyRef<HTMLButtonElement>}
{...restProps}
className={classString}
type="button"
>
{buttonNode}
</button>
),
);
};
if (process.env.NODE_ENV !== 'production') {
FloatButton.displayName = 'FloatButton';
}
const ForwardFloatButton = React.forwardRef<
HTMLAnchorElement | HTMLButtonElement,
FloatButtonProps
>(FloatButton) as CompoundedComponent;
export default ForwardFloatButton;

View File

@ -4,7 +4,7 @@ import FileTextOutlined from '@ant-design/icons/FileTextOutlined';
import classNames from 'classnames';
import CSSMotion from 'rc-motion';
import useMergedState from 'rc-util/lib/hooks/useMergedState';
import FloatButton, { floatButtonPrefixCls } from '.';
import FloatButton, { floatButtonPrefixCls } from './FloatButton';
import type { ConfigConsumerProps } from '../config-provider';
import { ConfigContext } from '../config-provider';
import { FloatButtonGroupProvider } from './context';

View File

@ -0,0 +1,43 @@
/* eslint-disable react/no-array-index-key */
import * as React from 'react';
import classNames from 'classnames';
import FloatButton, { floatButtonPrefixCls } from './FloatButton';
import FloatButtonGroup from './FloatButtonGroup';
import BackTop from './BackTop';
import type { FloatButtonProps, FloatButtonGroupProps } from './interface';
import { ConfigContext } from '../config-provider';
export interface PureFloatButtonProps extends FloatButtonProps {
backTop?: boolean;
}
export interface PurePanelProps
extends PureFloatButtonProps,
Omit<FloatButtonGroupProps, 'children'> {
/** Convert to FloatGroup when configured */
items?: PureFloatButtonProps[];
}
function PureFloatButton({ backTop, ...props }: PureFloatButtonProps) {
return backTop ? <BackTop {...props} visible target={undefined} /> : <FloatButton {...props} />;
}
export default function PurePanel({ className, items, ...props }: PurePanelProps) {
const { prefixCls: customizePrefixCls } = props;
const { getPrefixCls } = React.useContext(ConfigContext);
const prefixCls = getPrefixCls(floatButtonPrefixCls, customizePrefixCls);
const pureCls = `${prefixCls}-pure`;
if (items) {
return (
<FloatButtonGroup className={classNames(className, pureCls)} {...props}>
{items.map((item, index) => (
<PureFloatButton key={index} {...item} />
))}
</FloatButtonGroup>
);
}
return <PureFloatButton className={classNames(className, pureCls)} {...props} />;
}

View File

@ -106,7 +106,7 @@ Array [
<div
class="ant-float-btn-description"
>
帮助文档
HELP INFO
</div>
</div>
</div>
@ -125,7 +125,7 @@ Array [
<div
class="ant-float-btn-description"
>
帮助文档
HELP INFO
</div>
</div>
</div>
@ -167,7 +167,7 @@ Array [
<div
class="ant-float-btn-description"
>
文档
HELP
</div>
</div>
</div>
@ -419,6 +419,399 @@ exports[`renders ./components/float-button/demo/group-menu.md extend context cor
</div>
`;
exports[`renders ./components/float-button/demo/render-panel.md extend context correctly 1`] = `
<div
style="display:flex;column-gap:16px;align-items:center"
>
<button
class="ant-float-btn ant-float-btn-pure ant-float-btn-default ant-float-btn-circle"
type="button"
>
<div
class="ant-float-btn-body"
>
<div
class="ant-float-btn-content"
>
<div
class="ant-float-btn-icon"
>
<span
aria-label="vertical-align-top"
class="anticon anticon-vertical-align-top"
role="img"
>
<svg
aria-hidden="true"
data-icon="vertical-align-top"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M859.9 168H164.1c-4.5 0-8.1 3.6-8.1 8v60c0 4.4 3.6 8 8.1 8h695.8c4.5 0 8.1-3.6 8.1-8v-60c0-4.4-3.6-8-8.1-8zM518.3 355a8 8 0 00-12.6 0l-112 141.7a7.98 7.98 0 006.3 12.9h73.9V848c0 4.4 3.6 8 8 8h60c4.4 0 8-3.6 8-8V509.7H624c6.7 0 10.4-7.7 6.3-12.9L518.3 355z"
/>
</svg>
</span>
</div>
</div>
</div>
</button>
<button
class="ant-float-btn ant-float-btn-pure ant-float-btn-default ant-float-btn-circle"
type="button"
>
<div
class="ant-float-btn-body"
>
<div
class="ant-float-btn-content"
>
<div
class="ant-float-btn-icon"
>
<span
aria-label="customer-service"
class="anticon anticon-customer-service"
role="img"
>
<svg
aria-hidden="true"
data-icon="customer-service"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 128c-212.1 0-384 171.9-384 384v360c0 13.3 10.7 24 24 24h184c35.3 0 64-28.7 64-64V624c0-35.3-28.7-64-64-64H200v-48c0-172.3 139.7-312 312-312s312 139.7 312 312v48H688c-35.3 0-64 28.7-64 64v208c0 35.3 28.7 64 64 64h184c13.3 0 24-10.7 24-24V512c0-212.1-171.9-384-384-384zM328 632v192H200V632h128zm496 192H696V632h128v192z"
/>
</svg>
</span>
</div>
</div>
</div>
</button>
<button
class="ant-float-btn ant-float-btn-pure ant-float-btn-primary ant-float-btn-square"
type="button"
>
<div
class="ant-float-btn-body"
>
<div
class="ant-float-btn-content"
>
<div
class="ant-float-btn-icon"
>
<span
aria-label="question-circle"
class="anticon anticon-question-circle"
role="img"
>
<svg
aria-hidden="true"
data-icon="question-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"
/>
<path
d="M623.6 316.7C593.6 290.4 554 276 512 276s-81.6 14.5-111.6 40.7C369.2 344 352 380.7 352 420v7.6c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V420c0-44.1 43.1-80 96-80s96 35.9 96 80c0 31.1-22 59.6-56.1 72.7-21.2 8.1-39.2 22.3-52.1 40.9-13.1 19-19.9 41.8-19.9 64.9V620c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-22.7a48.3 48.3 0 0130.9-44.8c59-22.7 97.1-74.7 97.1-132.5.1-39.3-17.1-76-48.3-103.3zM472 732a40 40 0 1080 0 40 40 0 10-80 0z"
/>
</svg>
</span>
</div>
<div
class="ant-float-btn-description"
>
HELP
</div>
</div>
</div>
</button>
<div
class="ant-float-btn-group ant-float-btn-pure ant-float-btn-group-square ant-float-btn-group-square-shadow"
>
<button
class="ant-float-btn ant-float-btn-default ant-float-btn-square"
type="button"
>
<div
class="ant-float-btn-body"
>
<div
class="ant-float-btn-content"
>
<div
class="ant-float-btn-icon"
>
<span
aria-label="question-circle"
class="anticon anticon-question-circle"
role="img"
>
<svg
aria-hidden="true"
data-icon="question-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"
/>
<path
d="M623.6 316.7C593.6 290.4 554 276 512 276s-81.6 14.5-111.6 40.7C369.2 344 352 380.7 352 420v7.6c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V420c0-44.1 43.1-80 96-80s96 35.9 96 80c0 31.1-22 59.6-56.1 72.7-21.2 8.1-39.2 22.3-52.1 40.9-13.1 19-19.9 41.8-19.9 64.9V620c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-22.7a48.3 48.3 0 0130.9-44.8c59-22.7 97.1-74.7 97.1-132.5.1-39.3-17.1-76-48.3-103.3zM472 732a40 40 0 1080 0 40 40 0 10-80 0z"
/>
</svg>
</span>
</div>
</div>
</div>
</button>
<button
class="ant-float-btn ant-float-btn-default ant-float-btn-square"
type="button"
>
<div
class="ant-float-btn-body"
>
<div
class="ant-float-btn-content"
>
<div
class="ant-float-btn-icon"
>
<span
aria-label="customer-service"
class="anticon anticon-customer-service"
role="img"
>
<svg
aria-hidden="true"
data-icon="customer-service"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 128c-212.1 0-384 171.9-384 384v360c0 13.3 10.7 24 24 24h184c35.3 0 64-28.7 64-64V624c0-35.3-28.7-64-64-64H200v-48c0-172.3 139.7-312 312-312s312 139.7 312 312v48H688c-35.3 0-64 28.7-64 64v208c0 35.3 28.7 64 64 64h184c13.3 0 24-10.7 24-24V512c0-212.1-171.9-384-384-384zM328 632v192H200V632h128zm496 192H696V632h128v192z"
/>
</svg>
</span>
</div>
</div>
</div>
</button>
<button
class="ant-float-btn ant-float-btn-default ant-float-btn-square"
type="button"
>
<div
class="ant-float-btn-body"
>
<div
class="ant-float-btn-content"
>
<div
class="ant-float-btn-icon"
>
<span
aria-label="sync"
class="anticon anticon-sync"
role="img"
>
<svg
aria-hidden="true"
data-icon="sync"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M168 504.2c1-43.7 10-86.1 26.9-126 17.3-41 42.1-77.7 73.7-109.4S337 212.3 378 195c42.4-17.9 87.4-27 133.9-27s91.5 9.1 133.8 27A341.5 341.5 0 01755 268.8c9.9 9.9 19.2 20.4 27.8 31.4l-60.2 47a8 8 0 003 14.1l175.7 43c5 1.2 9.9-2.6 9.9-7.7l.8-180.9c0-6.7-7.7-10.5-12.9-6.3l-56.4 44.1C765.8 155.1 646.2 92 511.8 92 282.7 92 96.3 275.6 92 503.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8zm756 7.8h-60c-4.4 0-7.9 3.5-8 7.8-1 43.7-10 86.1-26.9 126-17.3 41-42.1 77.8-73.7 109.4A342.45 342.45 0 01512.1 856a342.24 342.24 0 01-243.2-100.8c-9.9-9.9-19.2-20.4-27.8-31.4l60.2-47a8 8 0 00-3-14.1l-175.7-43c-5-1.2-9.9 2.6-9.9 7.7l-.7 181c0 6.7 7.7 10.5 12.9 6.3l56.4-44.1C258.2 868.9 377.8 932 512.2 932c229.2 0 415.5-183.7 419.8-411.8a8 8 0 00-8-8.2z"
/>
</svg>
</span>
</div>
</div>
</div>
</button>
</div>
<div
class="ant-float-btn-group ant-float-btn-pure ant-float-btn-group-circle"
>
<div
class="ant-float-btn-group-wrap"
>
<button
class="ant-float-btn ant-float-btn-default ant-float-btn-circle"
type="button"
>
<div
class="ant-float-btn-body"
>
<div
class="ant-float-btn-content"
>
<div
class="ant-float-btn-icon"
>
<span
aria-label="question-circle"
class="anticon anticon-question-circle"
role="img"
>
<svg
aria-hidden="true"
data-icon="question-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"
/>
<path
d="M623.6 316.7C593.6 290.4 554 276 512 276s-81.6 14.5-111.6 40.7C369.2 344 352 380.7 352 420v7.6c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V420c0-44.1 43.1-80 96-80s96 35.9 96 80c0 31.1-22 59.6-56.1 72.7-21.2 8.1-39.2 22.3-52.1 40.9-13.1 19-19.9 41.8-19.9 64.9V620c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-22.7a48.3 48.3 0 0130.9-44.8c59-22.7 97.1-74.7 97.1-132.5.1-39.3-17.1-76-48.3-103.3zM472 732a40 40 0 1080 0 40 40 0 10-80 0z"
/>
</svg>
</span>
</div>
</div>
</div>
</button>
<button
class="ant-float-btn ant-float-btn-default ant-float-btn-circle"
type="button"
>
<div
class="ant-float-btn-body"
>
<div
class="ant-float-btn-content"
>
<div
class="ant-float-btn-icon"
>
<span
aria-label="customer-service"
class="anticon anticon-customer-service"
role="img"
>
<svg
aria-hidden="true"
data-icon="customer-service"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 128c-212.1 0-384 171.9-384 384v360c0 13.3 10.7 24 24 24h184c35.3 0 64-28.7 64-64V624c0-35.3-28.7-64-64-64H200v-48c0-172.3 139.7-312 312-312s312 139.7 312 312v48H688c-35.3 0-64 28.7-64 64v208c0 35.3 28.7 64 64 64h184c13.3 0 24-10.7 24-24V512c0-212.1-171.9-384-384-384zM328 632v192H200V632h128zm496 192H696V632h128v192z"
/>
</svg>
</span>
</div>
</div>
</div>
</button>
<button
class="ant-float-btn ant-float-btn-default ant-float-btn-circle"
type="button"
>
<div
class="ant-float-btn-body"
>
<div
class="ant-float-btn-content"
>
<div
class="ant-float-btn-icon"
>
<span
aria-label="sync"
class="anticon anticon-sync"
role="img"
>
<svg
aria-hidden="true"
data-icon="sync"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M168 504.2c1-43.7 10-86.1 26.9-126 17.3-41 42.1-77.7 73.7-109.4S337 212.3 378 195c42.4-17.9 87.4-27 133.9-27s91.5 9.1 133.8 27A341.5 341.5 0 01755 268.8c9.9 9.9 19.2 20.4 27.8 31.4l-60.2 47a8 8 0 003 14.1l175.7 43c5 1.2 9.9-2.6 9.9-7.7l.8-180.9c0-6.7-7.7-10.5-12.9-6.3l-56.4 44.1C765.8 155.1 646.2 92 511.8 92 282.7 92 96.3 275.6 92 503.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8zm756 7.8h-60c-4.4 0-7.9 3.5-8 7.8-1 43.7-10 86.1-26.9 126-17.3 41-42.1 77.8-73.7 109.4A342.45 342.45 0 01512.1 856a342.24 342.24 0 01-243.2-100.8c-9.9-9.9-19.2-20.4-27.8-31.4l60.2-47a8 8 0 00-3-14.1l-175.7-43c-5-1.2-9.9 2.6-9.9 7.7l-.7 181c0 6.7 7.7 10.5 12.9 6.3l56.4-44.1C258.2 868.9 377.8 932 512.2 932c229.2 0 415.5-183.7 419.8-411.8a8 8 0 00-8-8.2z"
/>
</svg>
</span>
</div>
</div>
</div>
</button>
</div>
<button
class="ant-float-btn ant-float-btn-default ant-float-btn-circle"
type="button"
>
<div
class="ant-float-btn-body"
>
<div
class="ant-float-btn-content"
>
<div
class="ant-float-btn-icon"
>
<span
aria-label="close"
class="anticon anticon-close"
role="img"
>
<svg
aria-hidden="true"
data-icon="close"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
/>
</svg>
</span>
</div>
</div>
</div>
</button>
</div>
</div>
`;
exports[`renders ./components/float-button/demo/shape.md extend context correctly 1`] = `
Array [
<div

View File

@ -106,7 +106,7 @@ Array [
<div
class="ant-float-btn-description"
>
帮助文档
HELP INFO
</div>
</div>
</div>
@ -125,7 +125,7 @@ Array [
<div
class="ant-float-btn-description"
>
帮助文档
HELP INFO
</div>
</div>
</div>
@ -167,7 +167,7 @@ Array [
<div
class="ant-float-btn-description"
>
文档
HELP
</div>
</div>
</div>
@ -419,6 +419,399 @@ exports[`renders ./components/float-button/demo/group-menu.md correctly 1`] = `
</div>
`;
exports[`renders ./components/float-button/demo/render-panel.md correctly 1`] = `
<div
style="display:flex;column-gap:16px;align-items:center"
>
<button
class="ant-float-btn ant-float-btn-pure ant-float-btn-default ant-float-btn-circle"
type="button"
>
<div
class="ant-float-btn-body"
>
<div
class="ant-float-btn-content"
>
<div
class="ant-float-btn-icon"
>
<span
aria-label="vertical-align-top"
class="anticon anticon-vertical-align-top"
role="img"
>
<svg
aria-hidden="true"
data-icon="vertical-align-top"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M859.9 168H164.1c-4.5 0-8.1 3.6-8.1 8v60c0 4.4 3.6 8 8.1 8h695.8c4.5 0 8.1-3.6 8.1-8v-60c0-4.4-3.6-8-8.1-8zM518.3 355a8 8 0 00-12.6 0l-112 141.7a7.98 7.98 0 006.3 12.9h73.9V848c0 4.4 3.6 8 8 8h60c4.4 0 8-3.6 8-8V509.7H624c6.7 0 10.4-7.7 6.3-12.9L518.3 355z"
/>
</svg>
</span>
</div>
</div>
</div>
</button>
<button
class="ant-float-btn ant-float-btn-pure ant-float-btn-default ant-float-btn-circle"
type="button"
>
<div
class="ant-float-btn-body"
>
<div
class="ant-float-btn-content"
>
<div
class="ant-float-btn-icon"
>
<span
aria-label="customer-service"
class="anticon anticon-customer-service"
role="img"
>
<svg
aria-hidden="true"
data-icon="customer-service"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 128c-212.1 0-384 171.9-384 384v360c0 13.3 10.7 24 24 24h184c35.3 0 64-28.7 64-64V624c0-35.3-28.7-64-64-64H200v-48c0-172.3 139.7-312 312-312s312 139.7 312 312v48H688c-35.3 0-64 28.7-64 64v208c0 35.3 28.7 64 64 64h184c13.3 0 24-10.7 24-24V512c0-212.1-171.9-384-384-384zM328 632v192H200V632h128zm496 192H696V632h128v192z"
/>
</svg>
</span>
</div>
</div>
</div>
</button>
<button
class="ant-float-btn ant-float-btn-pure ant-float-btn-primary ant-float-btn-square"
type="button"
>
<div
class="ant-float-btn-body"
>
<div
class="ant-float-btn-content"
>
<div
class="ant-float-btn-icon"
>
<span
aria-label="question-circle"
class="anticon anticon-question-circle"
role="img"
>
<svg
aria-hidden="true"
data-icon="question-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"
/>
<path
d="M623.6 316.7C593.6 290.4 554 276 512 276s-81.6 14.5-111.6 40.7C369.2 344 352 380.7 352 420v7.6c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V420c0-44.1 43.1-80 96-80s96 35.9 96 80c0 31.1-22 59.6-56.1 72.7-21.2 8.1-39.2 22.3-52.1 40.9-13.1 19-19.9 41.8-19.9 64.9V620c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-22.7a48.3 48.3 0 0130.9-44.8c59-22.7 97.1-74.7 97.1-132.5.1-39.3-17.1-76-48.3-103.3zM472 732a40 40 0 1080 0 40 40 0 10-80 0z"
/>
</svg>
</span>
</div>
<div
class="ant-float-btn-description"
>
HELP
</div>
</div>
</div>
</button>
<div
class="ant-float-btn-group ant-float-btn-pure ant-float-btn-group-square ant-float-btn-group-square-shadow"
>
<button
class="ant-float-btn ant-float-btn-default ant-float-btn-square"
type="button"
>
<div
class="ant-float-btn-body"
>
<div
class="ant-float-btn-content"
>
<div
class="ant-float-btn-icon"
>
<span
aria-label="question-circle"
class="anticon anticon-question-circle"
role="img"
>
<svg
aria-hidden="true"
data-icon="question-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"
/>
<path
d="M623.6 316.7C593.6 290.4 554 276 512 276s-81.6 14.5-111.6 40.7C369.2 344 352 380.7 352 420v7.6c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V420c0-44.1 43.1-80 96-80s96 35.9 96 80c0 31.1-22 59.6-56.1 72.7-21.2 8.1-39.2 22.3-52.1 40.9-13.1 19-19.9 41.8-19.9 64.9V620c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-22.7a48.3 48.3 0 0130.9-44.8c59-22.7 97.1-74.7 97.1-132.5.1-39.3-17.1-76-48.3-103.3zM472 732a40 40 0 1080 0 40 40 0 10-80 0z"
/>
</svg>
</span>
</div>
</div>
</div>
</button>
<button
class="ant-float-btn ant-float-btn-default ant-float-btn-square"
type="button"
>
<div
class="ant-float-btn-body"
>
<div
class="ant-float-btn-content"
>
<div
class="ant-float-btn-icon"
>
<span
aria-label="customer-service"
class="anticon anticon-customer-service"
role="img"
>
<svg
aria-hidden="true"
data-icon="customer-service"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 128c-212.1 0-384 171.9-384 384v360c0 13.3 10.7 24 24 24h184c35.3 0 64-28.7 64-64V624c0-35.3-28.7-64-64-64H200v-48c0-172.3 139.7-312 312-312s312 139.7 312 312v48H688c-35.3 0-64 28.7-64 64v208c0 35.3 28.7 64 64 64h184c13.3 0 24-10.7 24-24V512c0-212.1-171.9-384-384-384zM328 632v192H200V632h128zm496 192H696V632h128v192z"
/>
</svg>
</span>
</div>
</div>
</div>
</button>
<button
class="ant-float-btn ant-float-btn-default ant-float-btn-square"
type="button"
>
<div
class="ant-float-btn-body"
>
<div
class="ant-float-btn-content"
>
<div
class="ant-float-btn-icon"
>
<span
aria-label="sync"
class="anticon anticon-sync"
role="img"
>
<svg
aria-hidden="true"
data-icon="sync"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M168 504.2c1-43.7 10-86.1 26.9-126 17.3-41 42.1-77.7 73.7-109.4S337 212.3 378 195c42.4-17.9 87.4-27 133.9-27s91.5 9.1 133.8 27A341.5 341.5 0 01755 268.8c9.9 9.9 19.2 20.4 27.8 31.4l-60.2 47a8 8 0 003 14.1l175.7 43c5 1.2 9.9-2.6 9.9-7.7l.8-180.9c0-6.7-7.7-10.5-12.9-6.3l-56.4 44.1C765.8 155.1 646.2 92 511.8 92 282.7 92 96.3 275.6 92 503.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8zm756 7.8h-60c-4.4 0-7.9 3.5-8 7.8-1 43.7-10 86.1-26.9 126-17.3 41-42.1 77.8-73.7 109.4A342.45 342.45 0 01512.1 856a342.24 342.24 0 01-243.2-100.8c-9.9-9.9-19.2-20.4-27.8-31.4l60.2-47a8 8 0 00-3-14.1l-175.7-43c-5-1.2-9.9 2.6-9.9 7.7l-.7 181c0 6.7 7.7 10.5 12.9 6.3l56.4-44.1C258.2 868.9 377.8 932 512.2 932c229.2 0 415.5-183.7 419.8-411.8a8 8 0 00-8-8.2z"
/>
</svg>
</span>
</div>
</div>
</div>
</button>
</div>
<div
class="ant-float-btn-group ant-float-btn-pure ant-float-btn-group-circle"
>
<div
class="ant-float-btn-group-wrap"
>
<button
class="ant-float-btn ant-float-btn-default ant-float-btn-circle"
type="button"
>
<div
class="ant-float-btn-body"
>
<div
class="ant-float-btn-content"
>
<div
class="ant-float-btn-icon"
>
<span
aria-label="question-circle"
class="anticon anticon-question-circle"
role="img"
>
<svg
aria-hidden="true"
data-icon="question-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"
/>
<path
d="M623.6 316.7C593.6 290.4 554 276 512 276s-81.6 14.5-111.6 40.7C369.2 344 352 380.7 352 420v7.6c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V420c0-44.1 43.1-80 96-80s96 35.9 96 80c0 31.1-22 59.6-56.1 72.7-21.2 8.1-39.2 22.3-52.1 40.9-13.1 19-19.9 41.8-19.9 64.9V620c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-22.7a48.3 48.3 0 0130.9-44.8c59-22.7 97.1-74.7 97.1-132.5.1-39.3-17.1-76-48.3-103.3zM472 732a40 40 0 1080 0 40 40 0 10-80 0z"
/>
</svg>
</span>
</div>
</div>
</div>
</button>
<button
class="ant-float-btn ant-float-btn-default ant-float-btn-circle"
type="button"
>
<div
class="ant-float-btn-body"
>
<div
class="ant-float-btn-content"
>
<div
class="ant-float-btn-icon"
>
<span
aria-label="customer-service"
class="anticon anticon-customer-service"
role="img"
>
<svg
aria-hidden="true"
data-icon="customer-service"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 128c-212.1 0-384 171.9-384 384v360c0 13.3 10.7 24 24 24h184c35.3 0 64-28.7 64-64V624c0-35.3-28.7-64-64-64H200v-48c0-172.3 139.7-312 312-312s312 139.7 312 312v48H688c-35.3 0-64 28.7-64 64v208c0 35.3 28.7 64 64 64h184c13.3 0 24-10.7 24-24V512c0-212.1-171.9-384-384-384zM328 632v192H200V632h128zm496 192H696V632h128v192z"
/>
</svg>
</span>
</div>
</div>
</div>
</button>
<button
class="ant-float-btn ant-float-btn-default ant-float-btn-circle"
type="button"
>
<div
class="ant-float-btn-body"
>
<div
class="ant-float-btn-content"
>
<div
class="ant-float-btn-icon"
>
<span
aria-label="sync"
class="anticon anticon-sync"
role="img"
>
<svg
aria-hidden="true"
data-icon="sync"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M168 504.2c1-43.7 10-86.1 26.9-126 17.3-41 42.1-77.7 73.7-109.4S337 212.3 378 195c42.4-17.9 87.4-27 133.9-27s91.5 9.1 133.8 27A341.5 341.5 0 01755 268.8c9.9 9.9 19.2 20.4 27.8 31.4l-60.2 47a8 8 0 003 14.1l175.7 43c5 1.2 9.9-2.6 9.9-7.7l.8-180.9c0-6.7-7.7-10.5-12.9-6.3l-56.4 44.1C765.8 155.1 646.2 92 511.8 92 282.7 92 96.3 275.6 92 503.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8zm756 7.8h-60c-4.4 0-7.9 3.5-8 7.8-1 43.7-10 86.1-26.9 126-17.3 41-42.1 77.8-73.7 109.4A342.45 342.45 0 01512.1 856a342.24 342.24 0 01-243.2-100.8c-9.9-9.9-19.2-20.4-27.8-31.4l60.2-47a8 8 0 00-3-14.1l-175.7-43c-5-1.2-9.9 2.6-9.9 7.7l-.7 181c0 6.7 7.7 10.5 12.9 6.3l56.4-44.1C258.2 868.9 377.8 932 512.2 932c229.2 0 415.5-183.7 419.8-411.8a8 8 0 00-8-8.2z"
/>
</svg>
</span>
</div>
</div>
</div>
</button>
</div>
<button
class="ant-float-btn ant-float-btn-default ant-float-btn-circle"
type="button"
>
<div
class="ant-float-btn-body"
>
<div
class="ant-float-btn-content"
>
<div
class="ant-float-btn-icon"
>
<span
aria-label="close"
class="anticon anticon-close"
role="img"
>
<svg
aria-hidden="true"
data-icon="close"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
/>
</svg>
</span>
</div>
</div>
</div>
</button>
</div>
</div>
`;
exports[`renders ./components/float-button/demo/shape.md correctly 1`] = `
Array [
<div

View File

@ -27,14 +27,14 @@ const App: React.FC = () => (
<>
<FloatButton
icon={<FileTextOutlined />}
description="帮助文档"
description="HELP INFO"
shape="square"
style={{ right: 24 }}
/>
<FloatButton description="帮助文档" shape="square" style={{ right: 94 }} />
<FloatButton description="HELP INFO" shape="square" style={{ right: 94 }} />
<FloatButton
icon={<FileTextOutlined />}
description="文档"
description="HELP"
shape="square"
style={{ right: 164 }}
/>

View File

@ -0,0 +1,67 @@
---
order: 99
title:
zh-CN: _InternalPanelDoNotUseOrYouWillBeFired
en-US: _InternalPanelDoNotUseOrYouWillBeFired
debug: true
---
## zh-CN
调试用组件,请勿直接使用。
## en-US
Debug usage. Do not use in your production.
```tsx
import React from 'react';
import { CustomerServiceOutlined, QuestionCircleOutlined, SyncOutlined } from '@ant-design/icons';
import { FloatButton } from 'antd';
/** Test usage. Do not use in your production. */
const { _InternalPanelDoNotUseOrYouWillBeFired: InternalFloatButton } = FloatButton;
export default () => (
<div style={{ display: 'flex', columnGap: 16, alignItems: 'center' }}>
<InternalFloatButton backTop />
<InternalFloatButton icon={<CustomerServiceOutlined />} />
<InternalFloatButton
icon={<QuestionCircleOutlined />}
description="HELP"
shape="square"
type="primary"
/>
<InternalFloatButton
shape="square"
items={[
{
icon: <QuestionCircleOutlined />,
},
{
icon: <CustomerServiceOutlined />,
},
{
icon: <SyncOutlined />,
},
]}
/>
<InternalFloatButton
icon={<CustomerServiceOutlined />}
trigger="click"
open
items={[
{
icon: <QuestionCircleOutlined />,
},
{
icon: <CustomerServiceOutlined />,
},
{
icon: <SyncOutlined />,
},
]}
/>
</div>
);
```

View File

@ -1,108 +1,10 @@
import classNames from 'classnames';
import React, { useContext, useMemo } from 'react';
import type { ConfigConsumerProps } from '../config-provider';
import FloatButton from './FloatButton';
import FloatButtonGroup from './FloatButtonGroup';
import BackTop from './BackTop';
import { ConfigContext } from '../config-provider';
import useStyle from './style';
import Tooltip from '../tooltip';
import Content from './FloatButtonContent';
import type {
CompoundedComponent,
FloatButtonContentProps,
FloatButtonProps,
FloatButtonShape,
} from './interface';
import Group from './FloatButtonGroup';
import FloatButtonGroupContext from './context';
import warning from '../_util/warning';
import PurePanel from './PurePanel';
export const floatButtonPrefixCls = 'float-btn';
FloatButton.Group = FloatButtonGroup;
FloatButton.BackTop = BackTop;
FloatButton._InternalPanelDoNotUseOrYouWillBeFired = PurePanel;
const FloatButton: React.ForwardRefRenderFunction<
HTMLAnchorElement | HTMLButtonElement,
FloatButtonProps
> = (props, ref) => {
const {
prefixCls: customizePrefixCls,
className,
type = 'default',
shape = 'circle',
icon,
description,
tooltip,
...restProps
} = props;
const { getPrefixCls, direction } = useContext<ConfigConsumerProps>(ConfigContext);
const groupShape = useContext<FloatButtonShape | undefined>(FloatButtonGroupContext);
const prefixCls = getPrefixCls(floatButtonPrefixCls, customizePrefixCls);
const [wrapSSR, hashId] = useStyle(prefixCls);
const mergeShape = groupShape || shape;
const classString = classNames(
hashId,
prefixCls,
className,
`${prefixCls}-${type}`,
`${prefixCls}-${mergeShape}`,
{
[`${prefixCls}-rtl`]: direction === 'rtl',
},
);
const contentProps = useMemo<FloatButtonContentProps>(
() => ({ prefixCls, description, icon, type }),
[prefixCls, description, icon, type],
);
const buttonNode = tooltip ? (
<Tooltip title={tooltip} placement="left">
<div className={`${prefixCls}-body`}>
<Content {...contentProps} />
</div>
</Tooltip>
) : (
<div className={`${prefixCls}-body`}>
<Content {...contentProps} />
</div>
);
if (process.env.NODE_ENV !== 'production') {
warning(
!(shape === 'circle' && description),
'FloatButton',
'supported only when `shape` is `square`. Due to narrow space for text, short sentence is recommended.',
);
}
return wrapSSR(
props.href ? (
<a ref={ref as React.LegacyRef<HTMLAnchorElement>} {...restProps} className={classString}>
{buttonNode}
</a>
) : (
<button
ref={ref as React.LegacyRef<HTMLButtonElement>}
{...restProps}
className={classString}
type="button"
>
{buttonNode}
</button>
),
);
};
if (process.env.NODE_ENV !== 'production') {
FloatButton.displayName = 'FloatButton';
}
const ForwardFloatButton = React.forwardRef<
HTMLAnchorElement | HTMLButtonElement,
FloatButtonProps
>(FloatButton) as CompoundedComponent;
ForwardFloatButton.Group = Group;
ForwardFloatButton.BackTop = BackTop;
export default ForwardFloatButton;
export default FloatButton;

View File

@ -2,6 +2,7 @@ import type React from 'react';
import type Group from './FloatButtonGroup';
import type BackTop from './BackTop';
import type { TooltipProps } from '../tooltip';
import type PurePanel from './PurePanel';
export type FloatButtonType = 'default' | 'primary';
@ -60,4 +61,5 @@ export type CompoundedComponent = React.ForwardRefExoticComponent<
> & {
Group: typeof Group;
BackTop: typeof BackTop;
_InternalPanelDoNotUseOrYouWillBeFired: typeof PurePanel;
};

View File

@ -67,6 +67,7 @@ const floatButtonGroupStyle: GenerateStyle<FloatButtonToken, CSSObject> = token
insetBlockEnd: token.floatButtonInsetBlockEnd,
backgroundColor: token.colorBgContainer,
borderRadius: token.radiusBase,
[`${groupPrefixCls}-wrap`]: {
zIndex: -1,
display: 'block',
@ -179,9 +180,17 @@ const sharedFloatButtonStyle: GenerateStyle<FloatButtonToken, CSSObject> = token
insetInlineEnd: token.floatButtonInsetInlineEnd,
insetBlockEnd: token.floatButtonInsetBlockEnd,
boxShadow: token.boxShadowSecondary,
// Pure Panel
'&-pure': {
position: 'relative',
inset: 'auto',
},
'&:empty': {
display: 'none',
},
[`${componentCls}-body`]: {
width: floatButtonSize,
height: floatButtonSize,

View File

@ -306,13 +306,13 @@
"size-limit": [
{
"path": "./dist/antd.min.js",
"limit": "373 kB"
"limit": "373.5 kB"
}
],
"bundlesize": [
{
"path": "./dist/antd.min.js",
"maxSize": "373 kB"
"maxSize": "373.5 kB"
}
],
"tnpm": {