diff --git a/src/fab/README.en-US.md b/src/fab/README.en-US.md
index 0b92fb337..1aed7e17f 100644
--- a/src/fab/README.en-US.md
+++ b/src/fab/README.en-US.md
@@ -9,6 +9,7 @@ button-props | Object | - | \- | N
icon | String | - | \- | N
style | String | right: 16px; bottom: 32px; | \- | N
text | String | - | \- | N
+draggable | Boolean / String | false | \- | N
### Fab Events
diff --git a/src/fab/README.md b/src/fab/README.md
index 571bc2ac2..0f92c4ba5 100644
--- a/src/fab/README.md
+++ b/src/fab/README.md
@@ -44,6 +44,7 @@ button-props | Object | - | 透传至 Button 组件 | N
icon | String | - | 图标 | N
style | String | right: 16px; bottom: 32px; | 悬浮按钮的样式,常用于调整位置(即将废弃,建议使用 `style`) | N
text | String | - | 文本内容 | N
+draggable | Boolean / String | false | `true` / `'all'`可拖动
`'vertical'`可垂直拖动
`'horizontal'`可水平拖动
`false`禁止拖动 | N
### Fab Events
diff --git a/src/fab/_example/draggable/index.js b/src/fab/_example/draggable/index.js
new file mode 100644
index 000000000..7a4e7a590
--- /dev/null
+++ b/src/fab/_example/draggable/index.js
@@ -0,0 +1,10 @@
+Component({
+ methods: {
+ handleClick(e) {
+ console.log(e);
+ },
+ handleMove(e) {
+ console.log(e);
+ },
+ },
+});
diff --git a/src/fab/_example/draggable/index.json b/src/fab/_example/draggable/index.json
new file mode 100644
index 000000000..76f1d491e
--- /dev/null
+++ b/src/fab/_example/draggable/index.json
@@ -0,0 +1,6 @@
+{
+ "component": true,
+ "usingComponents": {
+ "t-fab": "tdesign-miniprogram/fab/fab"
+ }
+}
diff --git a/src/fab/_example/draggable/index.wxml b/src/fab/_example/draggable/index.wxml
new file mode 100644
index 000000000..e33c47c04
--- /dev/null
+++ b/src/fab/_example/draggable/index.wxml
@@ -0,0 +1,8 @@
+
diff --git a/src/fab/_example/draggable/index.wxss b/src/fab/_example/draggable/index.wxss
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/fab/_example/fab.json b/src/fab/_example/fab.json
index 78d58bb27..29e776f6c 100644
--- a/src/fab/_example/fab.json
+++ b/src/fab/_example/fab.json
@@ -4,6 +4,7 @@
"usingComponents": {
"t-button": "tdesign-miniprogram/button/button",
"base": "./base",
- "advance": "./advance"
+ "advance": "./advance",
+ "draggable": "./draggable"
}
}
diff --git a/src/fab/_example/fab.wxml b/src/fab/_example/fab.wxml
index 2160f5609..6b3e5afa1 100644
--- a/src/fab/_example/fab.wxml
+++ b/src/fab/_example/fab.wxml
@@ -14,6 +14,14 @@
+
+
+
+ 可移动悬浮按钮
+
+
+
-
+
+
diff --git a/src/fab/draggable/draggable.json b/src/fab/draggable/draggable.json
new file mode 100644
index 000000000..a89ef4dbe
--- /dev/null
+++ b/src/fab/draggable/draggable.json
@@ -0,0 +1,4 @@
+{
+ "component": true,
+ "usingComponents": {}
+}
diff --git a/src/fab/draggable/draggable.less b/src/fab/draggable/draggable.less
new file mode 100644
index 000000000..7ba1580b0
--- /dev/null
+++ b/src/fab/draggable/draggable.less
@@ -0,0 +1,5 @@
+@import '../../common/style/index.less';
+
+.@{prefix}-draggable {
+ position: absolute;
+}
diff --git a/src/fab/draggable/draggable.ts b/src/fab/draggable/draggable.ts
new file mode 100644
index 000000000..6be62e295
--- /dev/null
+++ b/src/fab/draggable/draggable.ts
@@ -0,0 +1,64 @@
+import { SuperComponent, wxComponent } from '../../common/src/index';
+import config from '../../common/config';
+import props from './props';
+import { getRect } from '../../common/utils';
+import type { TdDraggableProps } from './type';
+
+const systemInfo = wx.getSystemInfoSync();
+const { prefix } = config;
+const name = `${prefix}-draggable`;
+
+export interface DraggableProps extends TdDraggableProps {}
+
+@wxComponent()
+export default class Draggable extends SuperComponent {
+ properties = props;
+
+ externalClasses = [`${prefix}-class`];
+
+ data = {
+ prefix,
+ classPrefix: name,
+ };
+
+ lifetimes = {
+ ready() {
+ this.computedRect();
+ },
+ };
+
+ methods = {
+ onTouchStart(e) {
+ if (this.properties.direction === 'none') return;
+ this.startX = e.touches[0].clientX + systemInfo.windowWidth - this.rect.right;
+ this.startY = e.touches[0].clientY + systemInfo.windowHeight - this.rect.bottom;
+ this.triggerEvent('start', { startX: this.startX, startY: this.startY, rect: this.rect, e });
+ },
+
+ onTouchMove(e) {
+ if (this.properties.direction === 'none') return;
+ let x = this.startX - e.touches[0].clientX; // x轴移动偏移量
+ let y = this.startY - e.touches[0].clientY; // y轴移动偏移量
+
+ if (this.properties.direction === 'vertical') {
+ x = systemInfo.windowWidth - this.rect.right;
+ }
+ if (this.properties.direction === 'horizontal') {
+ y = systemInfo.windowHeight - this.rect.bottom;
+ }
+
+ this.triggerEvent('move', { x, y, rect: this.rect, e });
+ },
+
+ async onTouchEnd(e) {
+ if (this.properties.direction === 'none') return;
+ await this.computedRect();
+ this.triggerEvent('end', { rect: this.rect, e });
+ },
+
+ async computedRect() {
+ this.rect = { right: 0, bottom: 0, width: 0, height: 0 };
+ this.rect = await getRect(this, `.${this.data.classPrefix}`);
+ },
+ };
+}
diff --git a/src/fab/draggable/draggable.wxml b/src/fab/draggable/draggable.wxml
new file mode 100644
index 000000000..4d16d1efd
--- /dev/null
+++ b/src/fab/draggable/draggable.wxml
@@ -0,0 +1,11 @@
+
+
+
+
+
diff --git a/src/fab/draggable/index.ts b/src/fab/draggable/index.ts
new file mode 100644
index 000000000..6c4d04d3f
--- /dev/null
+++ b/src/fab/draggable/index.ts
@@ -0,0 +1,3 @@
+export * from './props';
+export * from './type';
+export * from './draggable';
diff --git a/src/fab/draggable/props.ts b/src/fab/draggable/props.ts
new file mode 100644
index 000000000..e2e5d8f33
--- /dev/null
+++ b/src/fab/draggable/props.ts
@@ -0,0 +1,11 @@
+import { TdDraggableProps } from './type';
+
+const props: TdDraggableProps = {
+ /** 移动方向 */
+ direction: {
+ type: String,
+ value: 'all',
+ },
+};
+
+export default props;
diff --git a/src/fab/draggable/type.ts b/src/fab/draggable/type.ts
new file mode 100644
index 000000000..875b94898
--- /dev/null
+++ b/src/fab/draggable/type.ts
@@ -0,0 +1,10 @@
+export interface TdDraggableProps {
+ /**
+ * 移动方向
+ * @default 'all'
+ */
+ direction?: {
+ type: StringConstructor;
+ value?: 'all' | 'vertical' | 'horizontal' | 'none';
+ };
+}
diff --git a/src/fab/fab.json b/src/fab/fab.json
index e73f3adaa..7025f7d71 100644
--- a/src/fab/fab.json
+++ b/src/fab/fab.json
@@ -1,6 +1,7 @@
{
"component": true,
"usingComponents": {
- "t-button": "../button/button"
+ "t-button": "../button/button",
+ "t-draggable": "./draggable/draggable"
}
}
diff --git a/src/fab/fab.less b/src/fab/fab.less
index 76ded1638..f88380a8f 100644
--- a/src/fab/fab.less
+++ b/src/fab/fab.less
@@ -8,4 +8,8 @@
&__button {
box-shadow: @fab-shadow;
}
+
+ &__draggable {
+ position: fixed;
+ }
}
diff --git a/src/fab/fab.ts b/src/fab/fab.ts
index 8c6c1942e..5cd07d322 100644
--- a/src/fab/fab.ts
+++ b/src/fab/fab.ts
@@ -2,8 +2,15 @@ import { SuperComponent, wxComponent } from '../common/src/index';
import config from '../common/config';
import props from './props';
+const systemInfo = wx.getSystemInfoSync();
const { prefix } = config;
const name = `${prefix}-fab`;
+const baseButtonProps = {
+ size: 'large',
+ shape: 'circle',
+ theme: 'primary',
+ externalClass: `${prefix}-fab__button`,
+};
@wxComponent()
export default class Fab extends SuperComponent {
@@ -14,22 +21,25 @@ export default class Fab extends SuperComponent {
data = {
prefix,
classPrefix: name,
- baseButtonProps: {
- size: 'large',
- shape: 'circle',
- theme: 'primary',
- },
+ buttonData: baseButtonProps,
+ moveStyle: null,
};
observers = {
- text(val) {
- if (val) {
- this.setData({
- baseButtonProps: {
- shape: 'round',
+ 'buttonProps.**, icon, text, ariaLabel'() {
+ this.setData(
+ {
+ buttonData: {
+ ...baseButtonProps,
+ shape: this.properties.text ? 'round' : 'circle',
+ icon: this.properties.icon,
+ ...this.properties.buttonProps,
+ content: this.properties.text,
+ ariaLabel: this.properties.ariaLabel,
},
- });
- }
+ },
+ this.computedSize,
+ );
},
};
@@ -37,5 +47,20 @@ export default class Fab extends SuperComponent {
onTplButtonTap(e) {
this.triggerEvent('click', e);
},
+ onMove(e) {
+ const { x, y, rect } = e.detail;
+ const maxX = systemInfo.windowWidth - rect.width; // 父容器宽度 - 拖动元素宽度
+ const maxY = systemInfo.windowHeight - rect.height; // 父容器高度 - 拖动元素高度
+ const right = Math.max(0, Math.min(x, maxX));
+ const bottom = Math.max(0, Math.min(y, maxY));
+ this.setData({
+ moveStyle: `right: ${right}px; bottom: ${bottom}px;`,
+ });
+ },
+ computedSize() {
+ if (!this.properties.draggable) return;
+ const insChild = this.selectComponent('#draggable');
+ insChild.computedRect(); // button更新时,重新获取其尺寸
+ },
};
}
diff --git a/src/fab/fab.wxml b/src/fab/fab.wxml
index 1bca71c82..231fc4e59 100644
--- a/src/fab/fab.wxml
+++ b/src/fab/fab.wxml
@@ -1,12 +1,7 @@
-
-
+
+
-
-
-
+
diff --git a/src/fab/props.ts b/src/fab/props.ts
index d16b4523b..1211ceada 100644
--- a/src/fab/props.ts
+++ b/src/fab/props.ts
@@ -20,6 +20,12 @@ const props: TdFabProps = {
type: String,
value: '',
},
+ /** 是否可移动 */
+ draggable: {
+ type: Boolean,
+ optionalTypes: [String],
+ value: false,
+ },
};
export default props;
diff --git a/src/fab/template/draggable.wxml b/src/fab/template/draggable.wxml
new file mode 100644
index 000000000..7425f75f4
--- /dev/null
+++ b/src/fab/template/draggable.wxml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
diff --git a/src/fab/template/view.wxml b/src/fab/template/view.wxml
new file mode 100644
index 000000000..ef7b1a190
--- /dev/null
+++ b/src/fab/template/view.wxml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
diff --git a/src/fab/type.ts b/src/fab/type.ts
index f1a614185..c175a687a 100644
--- a/src/fab/type.ts
+++ b/src/fab/type.ts
@@ -36,4 +36,13 @@ export interface TdFabProps {
type: StringConstructor;
value?: string;
};
+ /**
+ * 是否可移动
+ * @default false
+ */
+ draggable?: {
+ type: BooleanConstructor;
+ optionalTypes: Array;
+ value?: boolean | 'all' | 'vertical' | 'horizontal';
+ };
}