first commit
This commit is contained in:
238
uni_modules/tdesign-uniapp/components/fab/fab.vue
Normal file
238
uni_modules/tdesign-uniapp/components/fab/fab.vue
Normal file
@@ -0,0 +1,238 @@
|
||||
<template>
|
||||
<t-draggable
|
||||
v-if="draggable"
|
||||
ref="draggable"
|
||||
:custom-style="tools._style(['right: 16px; bottom: 32px;', customStyle, moveStyle])"
|
||||
:direction="draggable === true ? 'all' : draggable"
|
||||
:t-class="tClass"
|
||||
@start="onStart"
|
||||
@move="onMove"
|
||||
@end="onEnd"
|
||||
>
|
||||
<slot v-if="!buttonData.content && !buttonData.icon" />
|
||||
<block
|
||||
v-else
|
||||
name="button"
|
||||
>
|
||||
<t-button
|
||||
:t-id="buttonData.tId"
|
||||
:custom-style="buttonData.style || ''"
|
||||
:block="buttonData.block"
|
||||
:class="getActionClass(classPrefix, buttonData.buttonLayout) || ''"
|
||||
:t-class="buttonData.tClass"
|
||||
:disabled="buttonData.disabled"
|
||||
:data-type="'action'"
|
||||
:data-extra="buttonData.index"
|
||||
:custom-dataset="buttonData.customDataset"
|
||||
:content="buttonData.content"
|
||||
:icon="buttonData.icon"
|
||||
:loading="buttonData.loading"
|
||||
:loading-props="buttonData.loadingProps"
|
||||
:theme="buttonData.theme"
|
||||
:ghost="buttonData.ghost"
|
||||
:shape="buttonData.shape"
|
||||
:size="buttonData.size"
|
||||
:variant="buttonData.variant"
|
||||
:open-type="buttonData.openType"
|
||||
:hover-class="buttonData.hoverClass"
|
||||
:hover-stop-propagation="buttonData.hoverStopPropagation"
|
||||
:hover-start-time="buttonData.hoverStartTime"
|
||||
:hover-stay-time="buttonData.hoverStayTime"
|
||||
:lang="buttonData.lang"
|
||||
:session-from="buttonData.sessionFrom"
|
||||
:send-message-title="buttonData.sendMessageTitle"
|
||||
:send-message-path="buttonData.sendMessagePath"
|
||||
:send-message-img="buttonData.sendMessageImg"
|
||||
:app-parameter="buttonData.appParameter"
|
||||
:show-message-card="buttonData.showMessageCard"
|
||||
:aria-label="buttonData.ariaLabel"
|
||||
@click="onTplButtonTap"
|
||||
@getuserinfo="onTplButtonTap"
|
||||
@contact="onTplButtonTap"
|
||||
@getphonenumber="onTplButtonTap"
|
||||
@error="onTplButtonTap"
|
||||
@opensetting="onTplButtonTap"
|
||||
@launchapp="onTplButtonTap"
|
||||
@agreeprivacyauthorization="onTplButtonTap"
|
||||
>
|
||||
<slot v-if="true || false" />
|
||||
</t-button>
|
||||
</block>
|
||||
</t-draggable>
|
||||
|
||||
<view
|
||||
v-else
|
||||
:class="[classPrefix, tClass]"
|
||||
:style="tools._style(['right: 16px; bottom: 32px;', customStyle])"
|
||||
>
|
||||
<slot v-if="!buttonData || !buttonData.content && !buttonData.icon" />
|
||||
<t-button
|
||||
v-else
|
||||
:t-id="buttonData.tId"
|
||||
:custom-style="buttonData.style || ''"
|
||||
:block="buttonData.block"
|
||||
:class="getActionClass(classPrefix, buttonData.buttonLayout) || ''"
|
||||
:t-class="buttonData.tClass"
|
||||
:disabled="buttonData.disabled"
|
||||
:data-type="'action'"
|
||||
:data-extra="buttonData.index"
|
||||
:custom-dataset="buttonData.customDataset"
|
||||
:content="buttonData.content"
|
||||
:icon="buttonData.icon"
|
||||
:loading="buttonData.loading"
|
||||
:loading-props="buttonData.loadingProps"
|
||||
:theme="buttonData.theme"
|
||||
:ghost="buttonData.ghost"
|
||||
:shape="buttonData.shape"
|
||||
:size="buttonData.size"
|
||||
:variant="buttonData.variant"
|
||||
:open-type="buttonData.openType"
|
||||
:hover-class="buttonData.hoverClass"
|
||||
:hover-stop-propagation="buttonData.hoverStopPropagation"
|
||||
:hover-start-time="buttonData.hoverStartTime"
|
||||
:hover-stay-time="buttonData.hoverStayTime"
|
||||
:lang="buttonData.lang"
|
||||
:session-from="buttonData.sessionFrom"
|
||||
:send-message-title="buttonData.sendMessageTitle"
|
||||
:send-message-path="buttonData.sendMessagePath"
|
||||
:send-message-img="buttonData.sendMessageImg"
|
||||
:app-parameter="buttonData.appParameter"
|
||||
:show-message-card="buttonData.showMessageCard"
|
||||
:aria-label="buttonData.ariaLabel"
|
||||
@click="onTplButtonTap"
|
||||
@getuserinfo="onTplButtonTap"
|
||||
@contact="onTplButtonTap"
|
||||
@getphonenumber="onTplButtonTap"
|
||||
@error="onTplButtonTap"
|
||||
@opensetting="onTplButtonTap"
|
||||
@launchapp="onTplButtonTap"
|
||||
@agreeprivacyauthorization="onTplButtonTap"
|
||||
>
|
||||
<slot />
|
||||
</t-button>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TButton from '../button/button';
|
||||
import TDraggable from '../draggable/draggable.vue';
|
||||
import { uniComponent } from '../common/src/index';
|
||||
import { prefix } from '../common/config';
|
||||
import props from './props';
|
||||
import useCustomNavbar from '../mixins/using-custom-navbar';
|
||||
import { unitConvert, getWindowInfo } from '../common/utils';
|
||||
import tools from '../common/utils.wxs';
|
||||
|
||||
const name = `${prefix}-fab`;
|
||||
|
||||
const baseButtonProps = {
|
||||
size: 'large',
|
||||
shape: 'circle',
|
||||
theme: 'primary',
|
||||
tClass: `${prefix}-fab__button`,
|
||||
};
|
||||
|
||||
export default uniComponent({
|
||||
name,
|
||||
options: {
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
externalClasses: [`${prefix}-class`, `${prefix}-class-button`],
|
||||
mixins: [useCustomNavbar],
|
||||
components: {
|
||||
TButton,
|
||||
TDraggable,
|
||||
},
|
||||
props: {
|
||||
...props,
|
||||
},
|
||||
emits: [
|
||||
'move',
|
||||
'start',
|
||||
'end',
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
moveStyle: null,
|
||||
tools,
|
||||
systemInfo: getWindowInfo(),
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
buttonData() {
|
||||
return {
|
||||
...baseButtonProps,
|
||||
shape: this.text ? 'round' : 'circle',
|
||||
...this.buttonProps,
|
||||
icon: this.icon,
|
||||
content: this.text,
|
||||
ariaLabel: this.ariaLabel,
|
||||
};
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
icon: 'computedSize',
|
||||
ariaLabel: 'computedSize',
|
||||
yBounds: 'computedSize',
|
||||
buttonProps: 'computedSize',
|
||||
text: {
|
||||
handler(val) {
|
||||
this.content = val;
|
||||
this.computedSize();
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onTplButtonTap(e) {
|
||||
this.$emit('click', { e });
|
||||
},
|
||||
onStart(t) {
|
||||
this.$emit('drag-start', t);
|
||||
},
|
||||
onMove(e) {
|
||||
const {
|
||||
yBounds = [],
|
||||
distanceTop,
|
||||
systemInfo,
|
||||
} = this;
|
||||
|
||||
const { x, y, rect } = e;
|
||||
const maxX = systemInfo.windowWidth - rect.width; // 父容器宽度 - 拖动元素宽度
|
||||
const maxY = systemInfo.windowHeight - Math.max(distanceTop, unitConvert(yBounds[0])) - rect.height; // 父容器高度 - 拖动元素高度
|
||||
const right = Math.max(0, Math.min(x, maxX));
|
||||
const bottom = Math.max(0, unitConvert(yBounds[1]), Math.min(y, maxY));
|
||||
|
||||
|
||||
this.moveStyle = `right: ${right}px; bottom: ${bottom}px;`;
|
||||
},
|
||||
onEnd(t) {
|
||||
this.$emit('drag-end', t);
|
||||
},
|
||||
computedSize() {
|
||||
if (!this.draggable) return;
|
||||
|
||||
setTimeout(() => {
|
||||
const insChild = this.$refs.draggableTemplate?.$refs?.draggable;
|
||||
|
||||
|
||||
// button 更新时,重新获取其尺寸
|
||||
if (this?.yBounds?.[1]) {
|
||||
this.moveStyle = `bottom: ${unitConvert(this.yBounds[1])}px`;
|
||||
insChild?.computedRect();
|
||||
} else {
|
||||
insChild?.computedRect();
|
||||
}
|
||||
});
|
||||
},
|
||||
getActionClass(a, b) {
|
||||
return `${a}-${b}`;
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
@import './fab.css';
|
||||
</style>
|
||||
Reference in New Issue
Block a user