Browse Source

add FloatBotton component open api description and demo (#42835)

* docs: FloatBotton open 属性说明

* test: update snapshots

* demo: add controlled demo

* demo: update demo

* feat: add warning

* feat: update warning

* demo: update controlled demo

---------

Co-authored-by: 二货机器人 <smith3816@gmail.com>
pull/42970/head
dingkang 1 year ago
committed by GitHub
parent
commit
9459cbfaf8
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 14
      components/float-button/FloatButtonGroup.tsx
  2. 214
      components/float-button/__tests__/__snapshots__/demo-extend.test.ts.snap
  3. 163
      components/float-button/__tests__/__snapshots__/demo.test.ts.snap
  4. 24
      components/float-button/__tests__/group.test.tsx
  5. 7
      components/float-button/demo/controlled.md
  6. 28
      components/float-button/demo/controlled.tsx
  7. 4
      components/float-button/demo/group-menu.tsx
  8. 5
      components/float-button/index.en-US.md
  9. 13
      components/float-button/index.zh-CN.md

14
components/float-button/FloatButtonGroup.tsx

@ -1,12 +1,13 @@
import React, { useRef, memo, useContext, useEffect, useCallback, useMemo } from 'react';
import CloseOutlined from '@ant-design/icons/CloseOutlined';
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 './FloatButton';
import React, { memo, useCallback, useContext, useEffect, useMemo, useRef } from 'react';
import warning from '../_util/warning';
import type { ConfigConsumerProps } from '../config-provider';
import { ConfigContext } from '../config-provider';
import FloatButton, { floatButtonPrefixCls } from './FloatButton';
import { FloatButtonGroupProvider } from './context';
import type { FloatButtonGroupProps } from './interface';
import useStyle from './style';
@ -88,6 +89,15 @@ const FloatButtonGroup: React.FC<FloatButtonGroupProps> = (props) => {
}
}, [trigger]);
// =================== Warning =====================
if (process.env.NODE_ENV !== 'production') {
warning(
typeof props.open !== 'boolean' || !!trigger,
'FloatButton.Group',
'`open` need to be used together with `trigger`',
);
}
return wrapSSR(
<FloatButtonGroupProvider value={shape}>
<div ref={floatButtonGroupRef} className={groupCls} style={style} {...hoverAction}>

214
components/float-button/__tests__/__snapshots__/demo-extend.test.ts.snap

@ -660,6 +660,220 @@ exports[`renders components/float-button/demo/basic.tsx extend context correctly
</button>
`;
exports[`renders components/float-button/demo/controlled.tsx extend context correctly 1`] = `
Array [
<div
class="ant-float-btn-group ant-float-btn-group-circle"
style="right: 24px;"
>
<div
class="ant-float-btn-group-wrap-appear ant-float-btn-group-wrap-appear-start ant-float-btn-group-wrap ant-float-btn-group-wrap"
>
<button
class="ant-float-btn ant-float-btn-default ant-float-btn-circle"
type="button"
>
<span
class="ant-badge"
>
<div
class="ant-float-btn-body"
>
<div
class="ant-float-btn-content"
>
<div
class="ant-float-btn-icon"
>
<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"
>
<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>
</div>
</span>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-tooltip-placement-left"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; right: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
</button>
<button
class="ant-float-btn ant-float-btn-default ant-float-btn-circle"
type="button"
>
<span
class="ant-badge"
>
<div
class="ant-float-btn-body"
>
<div
class="ant-float-btn-content"
>
<div
class="ant-float-btn-icon"
>
<span
aria-label="comment"
class="anticon anticon-comment"
role="img"
>
<svg
aria-hidden="true"
data-icon="comment"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<defs>
<style />
</defs>
<path
d="M573 421c-23.1 0-41 17.9-41 40s17.9 40 41 40c21.1 0 39-17.9 39-40s-17.9-40-39-40zm-280 0c-23.1 0-41 17.9-41 40s17.9 40 41 40c21.1 0 39-17.9 39-40s-17.9-40-39-40z"
/>
<path
d="M894 345a343.92 343.92 0 00-189-130v.1c-17.1-19-36.4-36.5-58-52.1-163.7-119-393.5-82.7-513 81-96.3 133-92.2 311.9 6 439l.8 132.6c0 3.2.5 6.4 1.5 9.4a31.95 31.95 0 0040.1 20.9L309 806c33.5 11.9 68.1 18.7 102.5 20.6l-.5.4c89.1 64.9 205.9 84.4 313 49l127.1 41.4c3.2 1 6.5 1.6 9.9 1.6 17.7 0 32-14.3 32-32V753c88.1-119.6 90.4-284.9 1-408zM323 735l-12-5-99 31-1-104-8-9c-84.6-103.2-90.2-251.9-11-361 96.4-132.2 281.2-161.4 413-66 132.2 96.1 161.5 280.6 66 412-80.1 109.9-223.5 150.5-348 102zm505-17l-8 10 1 104-98-33-12 5c-56 20.8-115.7 22.5-171 7l-.2-.1A367.31 367.31 0 00729 676c76.4-105.3 88.8-237.6 44.4-350.4l.6.4c23 16.5 44.1 37.1 62 62 72.6 99.6 68.5 235.2-8 330z"
/>
<path
d="M433 421c-23.1 0-41 17.9-41 40s17.9 40 41 40c21.1 0 39-17.9 39-40s-17.9-40-39-40z"
/>
</svg>
</span>
</div>
</div>
</div>
</span>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-tooltip-placement-left"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; right: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
</button>
</div>
<button
class="ant-float-btn ant-float-btn-default ant-float-btn-circle"
type="button"
>
<span
class="ant-badge"
>
<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>
</span>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-tooltip-placement-left"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; right: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
</button>
</div>,
<button
aria-checked="true"
class="ant-switch ant-switch-checked"
role="switch"
type="button"
>
<div
class="ant-switch-handle"
/>
<span
class="ant-switch-inner"
>
<span
class="ant-switch-inner-checked"
/>
<span
class="ant-switch-inner-unchecked"
/>
</span>
</button>,
]
`;
exports[`renders components/float-button/demo/description.tsx extend context correctly 1`] = `
Array [
<button

163
components/float-button/__tests__/__snapshots__/demo.test.ts.snap

@ -501,6 +501,169 @@ exports[`renders components/float-button/demo/basic.tsx correctly 1`] = `
</button>
`;
exports[`renders components/float-button/demo/controlled.tsx correctly 1`] = `
Array [
<div
class="ant-float-btn-group ant-float-btn-group-circle"
style="right:24px"
>
<div
class="ant-float-btn-group-wrap"
>
<button
class="ant-float-btn ant-float-btn-default ant-float-btn-circle"
type="button"
>
<span
class="ant-badge"
>
<div
class="ant-float-btn-body"
>
<div
class="ant-float-btn-content"
>
<div
class="ant-float-btn-icon"
>
<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"
>
<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>
</div>
</span>
</button>
<button
class="ant-float-btn ant-float-btn-default ant-float-btn-circle"
type="button"
>
<span
class="ant-badge"
>
<div
class="ant-float-btn-body"
>
<div
class="ant-float-btn-content"
>
<div
class="ant-float-btn-icon"
>
<span
aria-label="comment"
class="anticon anticon-comment"
role="img"
>
<svg
aria-hidden="true"
data-icon="comment"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<defs>
<style />
</defs>
<path
d="M573 421c-23.1 0-41 17.9-41 40s17.9 40 41 40c21.1 0 39-17.9 39-40s-17.9-40-39-40zm-280 0c-23.1 0-41 17.9-41 40s17.9 40 41 40c21.1 0 39-17.9 39-40s-17.9-40-39-40z"
/>
<path
d="M894 345a343.92 343.92 0 00-189-130v.1c-17.1-19-36.4-36.5-58-52.1-163.7-119-393.5-82.7-513 81-96.3 133-92.2 311.9 6 439l.8 132.6c0 3.2.5 6.4 1.5 9.4a31.95 31.95 0 0040.1 20.9L309 806c33.5 11.9 68.1 18.7 102.5 20.6l-.5.4c89.1 64.9 205.9 84.4 313 49l127.1 41.4c3.2 1 6.5 1.6 9.9 1.6 17.7 0 32-14.3 32-32V753c88.1-119.6 90.4-284.9 1-408zM323 735l-12-5-99 31-1-104-8-9c-84.6-103.2-90.2-251.9-11-361 96.4-132.2 281.2-161.4 413-66 132.2 96.1 161.5 280.6 66 412-80.1 109.9-223.5 150.5-348 102zm505-17l-8 10 1 104-98-33-12 5c-56 20.8-115.7 22.5-171 7l-.2-.1A367.31 367.31 0 00729 676c76.4-105.3 88.8-237.6 44.4-350.4l.6.4c23 16.5 44.1 37.1 62 62 72.6 99.6 68.5 235.2-8 330z"
/>
<path
d="M433 421c-23.1 0-41 17.9-41 40s17.9 40 41 40c21.1 0 39-17.9 39-40s-17.9-40-39-40z"
/>
</svg>
</span>
</div>
</div>
</div>
</span>
</button>
</div>
<button
class="ant-float-btn ant-float-btn-default ant-float-btn-circle"
type="button"
>
<span
class="ant-badge"
>
<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>
</span>
</button>
</div>,
<button
aria-checked="true"
class="ant-switch ant-switch-checked"
role="switch"
type="button"
>
<div
class="ant-switch-handle"
/>
<span
class="ant-switch-inner"
>
<span
class="ant-switch-inner-checked"
/>
<span
class="ant-switch-inner-unchecked"
/>
</span>
</button>,
]
`;
exports[`renders components/float-button/demo/description.tsx correctly 1`] = `
Array [
<button

24
components/float-button/__tests__/group.test.tsx

@ -84,4 +84,28 @@ describe('FloatButtonGroup', () => {
fireEvent.click(container);
expect(onOpenChange).toHaveBeenCalledTimes(2);
});
it('warning if set `open` but not set `trigger`', () => {
const warnSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
render(
<FloatButton.Group open trigger="click">
<FloatButton />
<FloatButton />
</FloatButton.Group>,
);
expect(warnSpy).not.toHaveBeenCalled();
render(
<FloatButton.Group open>
<FloatButton />
<FloatButton />
</FloatButton.Group>,
);
expect(warnSpy).toHaveBeenCalledWith(
'Warning: [antd: FloatButton.Group] `open` need to be used together with `trigger`',
);
warnSpy.mockRestore();
});
});

7
components/float-button/demo/controlled.md

@ -0,0 +1,7 @@
## zh-CN
通过 `open` 设置组件为受控模式,需要配合 trigger 一起使用。
## en-US
Set the component to controlled mode through `open`, which need to be used together with trigger.

28
components/float-button/demo/controlled.tsx

@ -0,0 +1,28 @@
import { CommentOutlined, CustomerServiceOutlined } from '@ant-design/icons';
import { FloatButton, Switch } from 'antd';
import React, { useState } from 'react';
const App: React.FC = () => {
const [open, setOpen] = useState(true);
const onChange = (checked: boolean) => {
setOpen(checked);
};
return (
<>
<FloatButton.Group
open={open}
trigger="click"
style={{ right: 24 }}
icon={<CustomerServiceOutlined />}
>
<FloatButton />
<FloatButton icon={<CommentOutlined />} />
</FloatButton.Group>
<Switch onChange={onChange} checked={open} />
</>
);
};
export default App;

4
components/float-button/demo/group-menu.tsx

@ -1,6 +1,6 @@
import React from 'react';
import { CommentOutlined, CustomerServiceOutlined } from '@ant-design/icons';
import { FloatButton } from 'antd';
import { CustomerServiceOutlined, CommentOutlined } from '@ant-design/icons';
import React from 'react';
const App: React.FC = () => (
<>

5
components/float-button/index.en-US.md

@ -25,6 +25,7 @@ FloatButton. Available since `5.0.0`.
<code src="./demo/tooltip.tsx" iframe="360">FloatButton with tooltip</code>
<code src="./demo/group.tsx" iframe="360">FloatButton Group</code>
<code src="./demo/group-menu.tsx" iframe="360">Menu mode</code>
<code src="./demo/controlled.tsx" iframe="360">Controlled mode</code>
<code src="./demo/back-top.tsx" iframe="360">BackTop</code>
<code src="./demo/badge.tsx" iframe="360">badge</code>
<code src="./demo/badge-debug.tsx" iframe="360" debug>debug dot</code>
@ -54,8 +55,8 @@ FloatButton. Available since `5.0.0`.
| --- | --- | --- | --- | --- |
| shape | Setting button shape of children | `circle` \| `square` | `circle` | |
| trigger | Which action can trigger menu open/close | `click` \| `hover` | - | |
| open | Whether the menu is visible or not | boolean | - | |
| onOpenChange | Callback executed when active menu is changed | (open: boolean) => void | - | |
| open | Whether the menu is visible or not, use it with trigger | boolean | - | |
| onOpenChange | Callback executed when active menu is changed, use it with trigger | (open: boolean) => void | - | |
### FloatButton.BackTop

13
components/float-button/index.zh-CN.md

@ -26,6 +26,7 @@ demo:
<code src="./demo/tooltip.tsx" iframe="360">含有气泡卡片的悬浮按钮</code>
<code src="./demo/group.tsx" iframe="360">浮动按钮组</code>
<code src="./demo/group-menu.tsx" iframe="360">菜单模式</code>
<code src="./demo/controlled.tsx" iframe="360">受控模式</code>
<code src="./demo/back-top.tsx" iframe="360">回到顶部</code>
<code src="./demo/badge.tsx" iframe="360">徽标数</code>
<code src="./demo/badge-debug.tsx" iframe="360" debug>调试小圆点使用</code>
@ -51,12 +52,12 @@ demo:
### FloatButton.Group
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| ------------ | -------------------------------- | ----------------------- | -------- | ---- |
| shape | 设置包含的 FloatButton 按钮形状 | `circle` \| `square` | `circle` | |
| trigger | 触发方式(有触发方式为菜单模式) | `click` \| `hover` | - | |
| open | 受控展开 | boolean | - | |
| onOpenChange | 展开收起时的回调 | (open: boolean) => void | - | |
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| shape | 设置包含的 FloatButton 按钮形状 | `circle` \| `square` | `circle` | |
| trigger | 触发方式(有触发方式为菜单模式) | `click` \| `hover` | - | |
| open | 受控展开,需配合 trigger 一起使用 | boolean | - | |
| onOpenChange | 展开收起时的回调,需配合 trigger 一起使用 | (open: boolean) => void | - | |
### FloatButton.BackTop

Loading…
Cancel
Save