Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 18 additions & 12 deletions src/fab/Fab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ import { fabDefaultProps } from './defaultProps';
import { StyledProps } from '../common';
import { usePrefixClass } from '../hooks/useClass';
import useDefaultProps from '../hooks/useDefaultProps';
import parseTNode from '../_util/parseTNode';

export interface FabProps extends TdFabProps, StyledProps {}
export interface FabProps extends TdFabProps, StyledProps {
children?: React.ReactNode;
}

const Fab: React.FC<FabProps> = (originProps) => {
const props = useDefaultProps(originProps, fabDefaultProps);
const { buttonProps, icon = null, text, onClick } = props;
const { children, buttonProps, icon = null, text, onClick } = props;

const fabClass = usePrefixClass('fab');

Expand Down Expand Up @@ -167,6 +170,18 @@ const Fab: React.FC<FabProps> = (originProps) => {
};
setSwitchPosition(switchPos.endX, switchPos.endY);
};
const defaultContent = (
<Button
size="large"
theme="primary"
shape={props.text ? 'round' : 'circle'}
className={`${fabClass}__button`}
{...(buttonProps as TdFabProps['buttonProps'])}
icon={icon}
>
{text}
</Button>
);

return (
<div
Expand All @@ -177,16 +192,7 @@ const Fab: React.FC<FabProps> = (originProps) => {
onTouchStart={onTouchStart}
onTouchEnd={onTouchEnd}
>
<Button
size="large"
theme="primary"
shape={props.text ? 'round' : 'circle'}
className={`${fabClass}__button`}
{...(buttonProps as TdFabProps['buttonProps'])}
icon={icon}
>
{text}
</Button>
{parseTNode(children, null, defaultContent)}
</div>
);
};
Expand Down
59 changes: 59 additions & 0 deletions src/fab/_example/collapsible.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React, { useRef, useState, useEffect, useCallback } from 'react';
import { ChevronLeftIcon, AddCircleIcon, StarIcon, JumpIcon } from 'tdesign-icons-react';
import { Fab } from 'tdesign-mobile-react';
import getScrollParent from '../../_util/getScrollParent';
import './style/collapsible.less';

export default function () {
const timer = useRef<ReturnType<typeof setTimeout>>(null);
const fabRef = useRef(null);
const [scrolling, setScrolling] = useState(false);

const onScroll = useCallback(() => {
console.log('onScroll');
clearTimeout(timer.current);
timer.current = setTimeout(() => {
setScrolling(false);
}, 100);

setScrolling(true);
}, []);

useEffect(() => {
console.log('fabRef.current?.$el)', fabRef.current);
const scroller = getScrollParent(fabRef.current);
console.log('scroller', scroller);
scroller.addEventListener('scroll', onScroll);
return () => {
clearTimeout(timer.current);
scroller.removeEventListener('scroll', onScroll);
};
}, [onScroll]);

return (
<div ref={fabRef}>
<Fab style={scrolling ? { right: 0, bottom: '64px' } : { right: 16, bottom: 24 }}>
{scrolling ? (
<div className="symbol">
<ChevronLeftIcon />
</div>
) : (
<div className="wrap">
<div className="item">
<AddCircleIcon size="20" />
<span className="text">添加</span>
</div>
<div className="item">
<StarIcon size="20" />
<span className="text">收藏</span>
</div>
<div className="item">
<JumpIcon size="20" />
<span className="text">分享</span>
</div>
</div>
)}
</Fab>
</div>
);
}
22 changes: 22 additions & 0 deletions src/fab/_example/draggable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';
import { Icon } from 'tdesign-icons-react';
import { Fab } from 'tdesign-mobile-react';

export default function () {
const onClick = (e) => {
console.log('click Fab', e);
};
const yBounds = [30, 20];

return (
<>
<Fab
icon={<Icon name="add" size={24} />}
draggable="all"
style={{ right: '16px', bottom: '32px' }}
onClick={onClick}
yBounds={yBounds}
/>
</>
);
}
52 changes: 30 additions & 22 deletions src/fab/_example/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
import React, { useState } from 'react';
import { Button } from 'tdesign-mobile-react';
import { Button, Skeleton } from 'tdesign-mobile-react';
import TDemoBlock from '../../../site/mobile/components/DemoBlock';
import TDemoHeader from '../../../site/mobile/components/DemoHeader';
import './style/index.less';
import BaseDemo from './base';
import TextDemo from './advance';
import DraggableDemo from './draggable';
import CollapsibleDemo from './collapsible';

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

const changeType = (type) => setType(type);
const rowCols = [{ size: '163.5px', borderRadius: '12px' }, 1, { width: '61%' }];

const getButtonNode = (type: string, name: string) => (
<Button className="fab-btn" theme="primary" variant="outline" size="large" block onClick={() => changeType(type)}>
{name}
</Button>
);
return (
<div className="tdesign-mobile-demo">
<TDemoHeader
Expand All @@ -18,31 +27,30 @@ export default function FabDemo() {
/>

<TDemoBlock title="01 类型" summary="纯图标悬浮按钮" padding>
<Button
className="fab-btn"
theme="primary"
variant="outline"
size="large"
block
onClick={() => changeType('base')}
>
纯图标悬浮按钮
</Button>
{getButtonNode('base', '纯图标悬浮按钮')}
</TDemoBlock>
<TDemoBlock summary="图标加文字悬浮按钮" padding>
<Button
className="fab-btn"
theme="primary"
variant="outline"
size="large"
block
onClick={() => changeType('advance')}
>
图标加文字悬浮按钮
</Button>
{getButtonNode('advance', '图标加文字悬浮按钮')}
</TDemoBlock>
<TDemoBlock title="02 组件样式" summary="可移动悬浮按钮" padding>
{getButtonNode('draggable', '可移动悬浮按钮')}
</TDemoBlock>
<TDemoBlock summary="带自动收缩功能" padding>
{getButtonNode('collapsible', '带自动收缩功能')}
</TDemoBlock>
<TDemoBlock padding>
{[1, 2].map((item) => (
<div className="group" key={item}>
<Skeleton rowCol={rowCols} loading={true} />
<Skeleton rowCol={rowCols} loading={true} />
</div>
))}
</TDemoBlock>

{type === 'base' ? <BaseDemo /> : <TextDemo />}
{type === 'base' && <BaseDemo />}
{type === 'advance' && <TextDemo />}
{type === 'draggable' && <DraggableDemo />}
{type === 'collapsible' && <CollapsibleDemo />}
</div>
);
}
55 changes: 55 additions & 0 deletions src/fab/_example/style/collapsible.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
.wrap {
border: 1px solid #dcdcdc;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
padding: 8px 0;
border-radius: 22px;
box-shadow:
0px 5px 5px -3px rgba(0, 0, 0, 0.1),
0px 8px 10px 1px rgba(0, 0, 0, 0.06),
0px 3px 14px 2px rgba(0, 0, 0, 0.05);
background: rgba(255, 255, 255, 1);
width: 44px;
height: 156px;
box-sizing: border-box;

.item {
width: 100%;
height: 44px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-end;
font-size: 12px;
color: rgba(0, 0, 0, 0.9);
cursor: pointer;

&:not(:last-child) {
margin-bottom: 4px;
}

.text {
height: 20px;
line-height: 20px;
}
}
}

.symbol {
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 16px 0 0 16px;
background: #fff;

border: 1px solid #dcdcdc;
border-right: 0;
box-shadow:
0px 5px 5px -3px #0000001a,
0px 8px 10px 1px #0000000f,
0px 3px 14px 2px #0000000d;
}
6 changes: 6 additions & 0 deletions src/fab/_example/style/index.less
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
.tdesign-mobile-demo {
background-color: var(--td-bg-color-container);
}

.group {
display: flex;
justify-content: space-between;
margin-top: 24px;
}
2 changes: 1 addition & 1 deletion src/steps/__tests__/__snapshots__/demo.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1792,7 +1792,7 @@ exports[`Steps > Steps verticalDemo demo 1`] = `
>
<div
class="t-loading t-loading--center"
style="font-size: 20px;"
style="color: inherit; font-size: 20px;"
>
<div
class="t-loading__dots"
Expand Down
Loading