New Huajishe Check ChaoXing

This commit is contained in:
e2hang
2025-10-01 10:01:52 +08:00
parent 240b884eac
commit 80be8ae3cf
1094 changed files with 61709 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
:: BASE_DOC ::
## API
### Fab Props
name | type | default | description | required
-- | -- | -- | -- | --
style | String | right: 16px; bottom: 32px; | \- | N
custom-style | Object | - | CSS(Cascading Style Sheets)used to set style on virtual component | N
button-props | Object | - | Typescript`ButtonProps`[Button API Documents](./button?tab=api)。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/fab/type.ts) | N
draggable | String / Boolean | false | Typescript`boolean \| FabDirectionEnum ` `type FabDirectionEnum = 'all' \| 'vertical' \| 'horizontal'`。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/fab/type.ts) | N
icon | String | - | \- | N
text | String | - | \- | N
using-custom-navbar | Boolean | false | \- | N
y-bounds | Array | - | Typescript`Array<string \| number>` | N
### Fab Events
name | params | description
-- | -- | --
click | `({e: Event})` | \-
drag-end | `(e: TouchEvent)` | \-
drag-start | `(e: TouchEvent)` | \-
### CSS Variables
The component provides the following CSS variables, which can be used to customize styles.
Name | Default Value | Description
-- | -- | --
--td-fab-shadow | @shadow-2 | -

View File

@@ -0,0 +1,85 @@
---
title: Fab 悬浮按钮
description: 当功能使用图标即可表意清楚时,可使用纯图标悬浮按钮,例如:添加、发布。
spline: form
isComponent: true
---
<span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20lines-100%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20functions-100%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20statements-100%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20branches-100%25-blue" /></span>
<div style="background: #ecf2fe; display: flex; align-items: center; line-height: 20px; padding: 14px 24px; border-radius: 3px; color: #555a65">
<svg fill="none" viewBox="0 0 16 16" width="16px" height="16px" style="margin-right: 5px">
<path fill="#0052d9" d="M8 15A7 7 0 108 1a7 7 0 000 14zM7.4 4h1.2v1.2H7.4V4zm.1 2.5h1V12h-1V6.5z" fillOpacity="0.9"></path>
</svg>
该组件于 0.7.2 版本上线,请留意版本。
</div>
## 引入
全局引入,在 miniprogram 根目录下的`app.json`中配置,局部引入,在需要引入的页面或组件的`index.json`中配置。
```json
"usingComponents": {
"t-fab": "tdesign-miniprogram/fab/fab"
}
```
## 代码演示
<a href="https://developers.weixin.qq.com/s/KNHt9bmB7OSc" title="在开发者工具中预览效果" target="_blank" rel="noopener noreferrer"> 在开发者工具中预览效果 </a>
<blockquote style="background-color: #d9e1ff; font-size: 15px; line-height: 26px;margin: 16px 0 0;padding: 16px; border-radius: 6px; color: #0052d9" >
<p>Tips: 请确保开发者工具为打开状态。导入开发者工具后依次执行npm i > 构建npm包 > 勾选 "将JS编译成ES5"</p>
</blockquote>
### 基础使用
{{ base }}
### 进阶使用
{{ advance }}
### 可移动悬浮按钮
{{ draggable }}
## FAQ
### 为什么通过 style/customStyle 设置 top/left 调整初试定位后,会使页面内容无法点击以及拖拽异常?
由于 `position: fixed;` 会使得元素脱离文档流,它将悬浮于页面上方。同时,元素没有设置宽高,当同时使用 `top``right``bottom``left` 属性时,浏览器会根据给定的 `top``right``bottom``left` 创建一个矩形框来容纳元素及其内容,所以会出现元素覆盖页面内容及拖拽异常等问题。
Fab 组件默认定位 `right: 16px; bottom: 32px;`,且拖拽功能也是通过调整 `right``bottom` 属性值实现,因此在使用 `Fab` 组件时,仅支持通过 `style/customStyle` 属性设置 `right/bottom` 来调整初试位置, 避免使用 `top/left`
## API
### Fab Props
名称 | 类型 | 默认值 | 描述 | 必传
-- | -- | -- | -- | --
style | String | right: 16px; bottom: 32px; | 悬浮按钮的样式,常用于调整位置(即将废弃,建议使用 `style` | N
custom-style | Object | - | 样式,一般用于开启虚拟化组件节点场景 | N
button-props | Object | - | 透传至 Button 组件。TS 类型:`ButtonProps`[Button API Documents](./button?tab=api)。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/fab/type.ts) | N
draggable | String / Boolean | false | 是否可拖拽。`true` / `'all'`可拖动<br>`'vertical'`可垂直拖动<br>`'horizontal'`可水平拖动<br>`false`禁止拖动。TS 类型:`boolean \| FabDirectionEnum ` `type FabDirectionEnum = 'all' \| 'vertical' \| 'horizontal'`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/fab/type.ts) | N
icon | String | - | 图标 | N
text | String | - | 文本内容 | N
using-custom-navbar | Boolean | false | 是否使用了自定义导航栏 | N
y-bounds | Array | - | 设置垂直方向边界限制,示例:[48, 48] 或 ['96rpx', 80]。TS 类型:`Array<string \| number>` | N
### Fab Events
名称 | 参数 | 描述
-- | -- | --
click | `({e: Event})` | 悬浮按钮点击事件
drag-end | `(e: TouchEvent)` | 结束拖拽时触发
drag-start | `(e: TouchEvent)` | 开始拖拽时触发
### CSS Variables
组件提供了下列 CSS 变量,可用于自定义样式。
名称 | 默认值 | 描述
-- | -- | --
--td-fab-shadow | @shadow-2 | -

View File

@@ -0,0 +1,21 @@
import { SuperComponent } from '../../common/src/index';
import type { TdDraggableProps } from './type';
export interface DraggableProps extends TdDraggableProps {
}
export default class Draggable extends SuperComponent {
properties: TdDraggableProps;
externalClasses: string[];
data: {
prefix: string;
classPrefix: string;
};
lifetimes: {
ready(): void;
};
methods: {
onTouchStart(e: any): void;
onTouchMove(e: any): void;
onTouchEnd(e: any): Promise<void>;
computedRect(): Promise<void>;
};
}

View File

@@ -0,0 +1,81 @@
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { SuperComponent, wxComponent } from '../../common/src/index';
import config from '../../common/config';
import props from './props';
import { getRect, systemInfo } from '../../common/utils';
const { prefix } = config;
const name = `${prefix}-draggable`;
let Draggable = class Draggable extends SuperComponent {
constructor() {
super(...arguments);
this.properties = props;
this.externalClasses = [`${prefix}-class`];
this.data = {
prefix,
classPrefix: name,
};
this.lifetimes = {
ready() {
this.computedRect();
},
};
this.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;
let y = this.startY - e.touches[0].clientY;
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 });
},
onTouchEnd(e) {
return __awaiter(this, void 0, void 0, function* () {
if (this.properties.direction === 'none')
return;
yield this.computedRect();
this.triggerEvent('end', { rect: this.rect, e });
});
},
computedRect() {
return __awaiter(this, void 0, void 0, function* () {
this.rect = { right: 0, bottom: 0, width: 0, height: 0 };
try {
this.rect = yield getRect(this, `.${this.data.classPrefix}`);
}
catch (e) {
}
});
},
};
}
};
Draggable = __decorate([
wxComponent()
], Draggable);
export default Draggable;

View File

@@ -0,0 +1,4 @@
{
"component": true,
"usingComponents": {}
}

View File

@@ -0,0 +1,11 @@
<wxs src="../../common/utils.wxs" module="_" />
<view
class="{{classPrefix}} class {{prefix}}-class"
style="{{_._style([style, customStyle])}}"
bind:touchstart="onTouchStart"
catch:touchmove="onTouchMove"
bind:touchend="onTouchEnd"
>
<slot></slot>
</view>

View File

@@ -0,0 +1,30 @@
.t-float-left {
float: left;
}
.t-float-right {
float: right;
}
@keyframes tdesign-fade-out {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
.hotspot-expanded.relative {
position: relative;
}
.hotspot-expanded::after {
content: '';
display: block;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
transform: scale(1.5);
}
.t-draggable {
position: fixed;
}

View File

@@ -0,0 +1,3 @@
export * from './props';
export * from './type';
export * from './draggable';

View File

@@ -0,0 +1,3 @@
export * from './props';
export * from './type';
export * from './draggable';

View File

@@ -0,0 +1,3 @@
import { TdDraggableProps } from './type';
declare const props: TdDraggableProps;
export default props;

View File

@@ -0,0 +1,7 @@
const props = {
direction: {
type: String,
value: 'all',
},
};
export default props;

View File

@@ -0,0 +1,6 @@
export interface TdDraggableProps {
direction?: {
type: StringConstructor;
value?: 'all' | 'vertical' | 'horizontal' | 'none';
};
}

View File

@@ -0,0 +1,27 @@
import { SuperComponent } from '../common/src/index';
export default class Fab extends SuperComponent {
behaviors: string[];
properties: import("./type").TdFabProps;
externalClasses: string[];
data: {
prefix: string;
classPrefix: string;
buttonData: {
size: string;
shape: string;
theme: string;
tClass: string;
};
moveStyle: any;
};
observers: {
'buttonProps.**, icon, text, ariaLabel, yBounds'(): void;
};
methods: {
onTplButtonTap(e: any): void;
onStart(e: any): void;
onMove(e: any): void;
onEnd(e: any): void;
computedSize(): void;
};
}

View File

@@ -0,0 +1,80 @@
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { SuperComponent, wxComponent } from '../common/src/index';
import config from '../common/config';
import props from './props';
import useCustomNavbar from '../mixins/using-custom-navbar';
import { unitConvert, systemInfo } from '../common/utils';
const { prefix } = config;
const name = `${prefix}-fab`;
const baseButtonProps = {
size: 'large',
shape: 'circle',
theme: 'primary',
tClass: `${prefix}-fab__button`,
};
let Fab = class Fab extends SuperComponent {
constructor() {
super(...arguments);
this.behaviors = [useCustomNavbar];
this.properties = props;
this.externalClasses = [`class`, `${prefix}-class`, `${prefix}-class-button`];
this.data = {
prefix,
classPrefix: name,
buttonData: baseButtonProps,
moveStyle: null,
};
this.observers = {
'buttonProps.**, icon, text, ariaLabel, yBounds'() {
var _a;
this.setData({
buttonData: Object.assign(Object.assign(Object.assign(Object.assign({}, baseButtonProps), { shape: this.properties.text ? 'round' : 'circle', icon: this.properties.icon }), this.properties.buttonProps), { content: this.properties.text, ariaLabel: this.properties.ariaLabel }),
}, (_a = this.computedSize) === null || _a === void 0 ? void 0 : _a.bind(this));
},
};
this.methods = {
onTplButtonTap(e) {
this.triggerEvent('click', e);
},
onStart(e) {
this.triggerEvent('dragstart', e.detail.e);
},
onMove(e) {
const { yBounds } = this.properties;
const { distanceTop } = this.data;
const { x, y, rect } = e.detail;
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.setData({
moveStyle: `right: ${right}px; bottom: ${bottom}px;`,
});
},
onEnd(e) {
this.triggerEvent('dragend', e.detail.e);
},
computedSize() {
var _a, _b;
if (!this.properties.draggable)
return;
const insChild = this.selectComponent('#draggable');
if ((_b = (_a = this.properties) === null || _a === void 0 ? void 0 : _a.yBounds) === null || _b === void 0 ? void 0 : _b[1]) {
this.setData({ moveStyle: `bottom: ${unitConvert(this.properties.yBounds[1])}px` }, insChild.computedRect);
}
else {
insChild.computedRect();
}
},
};
}
};
Fab = __decorate([
wxComponent()
], Fab);
export default Fab;

View File

@@ -0,0 +1,8 @@
{
"component": true,
"styleIsolation": "apply-shared",
"usingComponents": {
"t-button": "../button/button",
"t-draggable": "./draggable/draggable"
}
}

View File

@@ -0,0 +1,7 @@
<import src="./template/view.wxml" />
<import src="./template/draggable.wxml" />
<template
is="{{draggable ? 'draggable' : 'view'}}"
data="{{prefix, classPrefix, style, customStyle, moveStyle, draggable, buttonData}}"
/>

View File

@@ -0,0 +1,36 @@
.t-float-left {
float: left;
}
.t-float-right {
float: right;
}
@keyframes tdesign-fade-out {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
.hotspot-expanded.relative {
position: relative;
}
.hotspot-expanded::after {
content: '';
display: block;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
transform: scale(1.5);
}
.t-fab {
position: fixed;
}
.t-fab__button {
box-shadow: var(--td-fab-shadow, var(--td-shadow-2, 0 3px 14px 2px rgba(0, 0, 0, 0.05), 0 8px 10px 1px rgba(0, 0, 0, 0.06), 0 5px 5px -3px rgba(0, 0, 0, 0.1)));
}
.t-fab__draggable {
position: fixed;
}

View File

@@ -0,0 +1,3 @@
import { TdFabProps } from './type';
declare const props: TdFabProps;
export default props;

View File

@@ -0,0 +1,29 @@
const props = {
buttonProps: {
type: Object,
},
draggable: {
type: null,
value: false,
},
icon: {
type: String,
value: '',
},
style: {
type: String,
value: 'right: 16px; bottom: 32px;',
},
text: {
type: String,
value: '',
},
usingCustomNavbar: {
type: Boolean,
value: false,
},
yBounds: {
type: Array,
},
};
export default props;

View File

@@ -0,0 +1,15 @@
<import src="../../common/template/button.wxml" />
<wxs src="../../common/utils.wxs" module="_" />
<template name="draggable">
<t-draggable
id="draggable"
style="right: 16px; bottom: 32px; {{_._style([style, customStyle, moveStyle])}}"
direction="{{draggable === true ? 'all' : draggable}}"
bind:start="onStart"
bind:move="onMove"
bind:end="onEnd"
>
<template is="button" data="{{...buttonData}}" />
</t-draggable>
</template>

View File

@@ -0,0 +1,11 @@
<import src="../../common/template/button.wxml" />
<wxs src="../../common/utils.wxs" module="_" />
<template name="view">
<view
class="{{classPrefix}} class {{prefix}}-class"
style="right: 16px; bottom: 32px; {{_._style([style, customStyle])}}"
>
<template is="button" data="{{...buttonData}}" />
</view>
</template>

View File

@@ -0,0 +1,32 @@
import { ButtonProps } from '../button/index';
export interface TdFabProps {
buttonProps?: {
type: ObjectConstructor;
value?: ButtonProps;
};
draggable?: {
type: null;
value?: boolean | FabDirectionEnum;
};
icon?: {
type: StringConstructor;
value?: string;
};
style?: {
type: StringConstructor;
value?: string;
};
text?: {
type: StringConstructor;
value?: string;
};
usingCustomNavbar?: {
type: BooleanConstructor;
value?: boolean;
};
yBounds?: {
type: ArrayConstructor;
value?: Array<string | number>;
};
}
export declare type FabDirectionEnum = 'all' | 'vertical' | 'horizontal';

View File

@@ -0,0 +1 @@
export {};