Skip to content

Commit a35634a

Browse files
novlan1anlyyaogithub-actions[bot]
authored
feat(fab): support children (#645)
* feat(fab): support children * chore: update snapshot * fix: fix cr * chore: update snapshot --------- Co-authored-by: anlyyao <[email protected]> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 6c62a99 commit a35634a

File tree

9 files changed

+749
-308
lines changed

9 files changed

+749
-308
lines changed

src/fab/Fab.tsx

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@ import { fabDefaultProps } from './defaultProps';
66
import { StyledProps } from '../common';
77
import { usePrefixClass } from '../hooks/useClass';
88
import useDefaultProps from '../hooks/useDefaultProps';
9+
import parseTNode from '../_util/parseTNode';
910

10-
export interface FabProps extends TdFabProps, StyledProps {}
11+
export interface FabProps extends TdFabProps, StyledProps {
12+
children?: React.ReactNode;
13+
}
1114

1215
const Fab: React.FC<FabProps> = (originProps) => {
1316
const props = useDefaultProps(originProps, fabDefaultProps);
14-
const { buttonProps, icon = null, text, onClick } = props;
17+
const { children, buttonProps, icon = null, text, onClick } = props;
1518

1619
const fabClass = usePrefixClass('fab');
1720

@@ -167,6 +170,18 @@ const Fab: React.FC<FabProps> = (originProps) => {
167170
};
168171
setSwitchPosition(switchPos.endX, switchPos.endY);
169172
};
173+
const defaultContent = (
174+
<Button
175+
size="large"
176+
theme="primary"
177+
shape={props.text ? 'round' : 'circle'}
178+
className={`${fabClass}__button`}
179+
{...(buttonProps as TdFabProps['buttonProps'])}
180+
icon={icon}
181+
>
182+
{text}
183+
</Button>
184+
);
170185

171186
return (
172187
<div
@@ -177,16 +192,7 @@ const Fab: React.FC<FabProps> = (originProps) => {
177192
onTouchStart={onTouchStart}
178193
onTouchEnd={onTouchEnd}
179194
>
180-
<Button
181-
size="large"
182-
theme="primary"
183-
shape={props.text ? 'round' : 'circle'}
184-
className={`${fabClass}__button`}
185-
{...(buttonProps as TdFabProps['buttonProps'])}
186-
icon={icon}
187-
>
188-
{text}
189-
</Button>
195+
{parseTNode(children, null, defaultContent)}
190196
</div>
191197
);
192198
};

src/fab/_example/collapsible.tsx

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import React, { useRef, useState, useEffect, useCallback } from 'react';
2+
import { ChevronLeftIcon, AddCircleIcon, StarIcon, JumpIcon } from 'tdesign-icons-react';
3+
import { Fab } from 'tdesign-mobile-react';
4+
import getScrollParent from '../../_util/getScrollParent';
5+
import './style/collapsible.less';
6+
7+
export default function () {
8+
const timer = useRef<ReturnType<typeof setTimeout>>(null);
9+
const fabRef = useRef(null);
10+
const [scrolling, setScrolling] = useState(false);
11+
12+
const onScroll = useCallback(() => {
13+
console.log('onScroll');
14+
clearTimeout(timer.current);
15+
timer.current = setTimeout(() => {
16+
setScrolling(false);
17+
}, 100);
18+
19+
setScrolling(true);
20+
}, []);
21+
22+
useEffect(() => {
23+
console.log('fabRef.current?.$el)', fabRef.current);
24+
const scroller = getScrollParent(fabRef.current);
25+
console.log('scroller', scroller);
26+
scroller.addEventListener('scroll', onScroll);
27+
return () => {
28+
clearTimeout(timer.current);
29+
scroller.removeEventListener('scroll', onScroll);
30+
};
31+
}, [onScroll]);
32+
33+
return (
34+
<div ref={fabRef}>
35+
<Fab style={scrolling ? { right: 0, bottom: '64px' } : { right: 16, bottom: 24 }}>
36+
{scrolling ? (
37+
<div className="symbol">
38+
<ChevronLeftIcon />
39+
</div>
40+
) : (
41+
<div className="wrap">
42+
<div className="item">
43+
<AddCircleIcon size="20" />
44+
<span className="text">添加</span>
45+
</div>
46+
<div className="item">
47+
<StarIcon size="20" />
48+
<span className="text">收藏</span>
49+
</div>
50+
<div className="item">
51+
<JumpIcon size="20" />
52+
<span className="text">分享</span>
53+
</div>
54+
</div>
55+
)}
56+
</Fab>
57+
</div>
58+
);
59+
}

src/fab/_example/draggable.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import React from 'react';
2+
import { Icon } from 'tdesign-icons-react';
3+
import { Fab } from 'tdesign-mobile-react';
4+
5+
export default function () {
6+
const onClick = (e) => {
7+
console.log('click Fab', e);
8+
};
9+
const yBounds = [30, 20];
10+
11+
return (
12+
<>
13+
<Fab
14+
icon={<Icon name="add" size={24} />}
15+
draggable="all"
16+
style={{ right: '16px', bottom: '32px' }}
17+
onClick={onClick}
18+
yBounds={yBounds}
19+
/>
20+
</>
21+
);
22+
}

src/fab/_example/index.tsx

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,24 @@
11
import React, { useState } from 'react';
2-
import { Button } from 'tdesign-mobile-react';
2+
import { Button, Skeleton } from 'tdesign-mobile-react';
33
import TDemoBlock from '../../../site/mobile/components/DemoBlock';
44
import TDemoHeader from '../../../site/mobile/components/DemoHeader';
55
import './style/index.less';
66
import BaseDemo from './base';
77
import TextDemo from './advance';
8+
import DraggableDemo from './draggable';
9+
import CollapsibleDemo from './collapsible';
810

911
export default function FabDemo() {
1012
const [type, setType] = useState('base');
1113

1214
const changeType = (type) => setType(type);
15+
const rowCols = [{ size: '163.5px', borderRadius: '12px' }, 1, { width: '61%' }];
16+
17+
const getButtonNode = (type: string, name: string) => (
18+
<Button className="fab-btn" theme="primary" variant="outline" size="large" block onClick={() => changeType(type)}>
19+
{name}
20+
</Button>
21+
);
1322
return (
1423
<div className="tdesign-mobile-demo">
1524
<TDemoHeader
@@ -18,31 +27,30 @@ export default function FabDemo() {
1827
/>
1928

2029
<TDemoBlock title="01 类型" summary="纯图标悬浮按钮" padding>
21-
<Button
22-
className="fab-btn"
23-
theme="primary"
24-
variant="outline"
25-
size="large"
26-
block
27-
onClick={() => changeType('base')}
28-
>
29-
纯图标悬浮按钮
30-
</Button>
30+
{getButtonNode('base', '纯图标悬浮按钮')}
3131
</TDemoBlock>
3232
<TDemoBlock summary="图标加文字悬浮按钮" padding>
33-
<Button
34-
className="fab-btn"
35-
theme="primary"
36-
variant="outline"
37-
size="large"
38-
block
39-
onClick={() => changeType('advance')}
40-
>
41-
图标加文字悬浮按钮
42-
</Button>
33+
{getButtonNode('advance', '图标加文字悬浮按钮')}
34+
</TDemoBlock>
35+
<TDemoBlock title="02 组件样式" summary="可移动悬浮按钮" padding>
36+
{getButtonNode('draggable', '可移动悬浮按钮')}
37+
</TDemoBlock>
38+
<TDemoBlock summary="带自动收缩功能" padding>
39+
{getButtonNode('collapsible', '带自动收缩功能')}
40+
</TDemoBlock>
41+
<TDemoBlock padding>
42+
{[1, 2].map((item) => (
43+
<div className="group" key={item}>
44+
<Skeleton rowCol={rowCols} loading={true} />
45+
<Skeleton rowCol={rowCols} loading={true} />
46+
</div>
47+
))}
4348
</TDemoBlock>
4449

45-
{type === 'base' ? <BaseDemo /> : <TextDemo />}
50+
{type === 'base' && <BaseDemo />}
51+
{type === 'advance' && <TextDemo />}
52+
{type === 'draggable' && <DraggableDemo />}
53+
{type === 'collapsible' && <CollapsibleDemo />}
4654
</div>
4755
);
4856
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
.wrap {
2+
border: 1px solid #dcdcdc;
3+
display: flex;
4+
flex-direction: column;
5+
align-items: center;
6+
justify-content: space-around;
7+
padding: 8px 0;
8+
border-radius: 22px;
9+
box-shadow:
10+
0px 5px 5px -3px rgba(0, 0, 0, 0.1),
11+
0px 8px 10px 1px rgba(0, 0, 0, 0.06),
12+
0px 3px 14px 2px rgba(0, 0, 0, 0.05);
13+
background: rgba(255, 255, 255, 1);
14+
width: 44px;
15+
height: 156px;
16+
box-sizing: border-box;
17+
18+
.item {
19+
width: 100%;
20+
height: 44px;
21+
display: flex;
22+
flex-direction: column;
23+
align-items: center;
24+
justify-content: flex-end;
25+
font-size: 12px;
26+
color: rgba(0, 0, 0, 0.9);
27+
cursor: pointer;
28+
29+
&:not(:last-child) {
30+
margin-bottom: 4px;
31+
}
32+
33+
.text {
34+
height: 20px;
35+
line-height: 20px;
36+
}
37+
}
38+
}
39+
40+
.symbol {
41+
width: 32px;
42+
height: 32px;
43+
display: flex;
44+
align-items: center;
45+
justify-content: center;
46+
border-radius: 16px 0 0 16px;
47+
background: #fff;
48+
49+
border: 1px solid #dcdcdc;
50+
border-right: 0;
51+
box-shadow:
52+
0px 5px 5px -3px #0000001a,
53+
0px 8px 10px 1px #0000000f,
54+
0px 3px 14px 2px #0000000d;
55+
}

src/fab/_example/style/index.less

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
.tdesign-mobile-demo {
22
background-color: var(--td-bg-color-container);
33
}
4+
5+
.group {
6+
display: flex;
7+
justify-content: space-between;
8+
margin-top: 24px;
9+
}

src/steps/__tests__/__snapshots__/demo.test.tsx.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1792,7 +1792,7 @@ exports[`Steps > Steps verticalDemo demo 1`] = `
17921792
>
17931793
<div
17941794
class="t-loading t-loading--center"
1795-
style="font-size: 20px;"
1795+
style="color: inherit; font-size: 20px;"
17961796
>
17971797
<div
17981798
class="t-loading__dots"

0 commit comments

Comments
 (0)