短通知 + 上部消息
This commit is contained in:
74
components/message/README.md
Normal file
74
components/message/README.md
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
---
|
||||||
|
title: Message 消息通知
|
||||||
|
description: 用于轻量级反馈或提示,不会打断用户操作。
|
||||||
|
spline: message
|
||||||
|
isComponent: true
|
||||||
|
---
|
||||||
|
|
||||||
|
<span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20lines-94%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20functions-89%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20statements-94%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20branches-86%25-blue" /></span>
|
||||||
|
## 引入
|
||||||
|
|
||||||
|
全局引入,在 miniprogram 根目录下的`app.json`中配置,局部引入,在需要引入的页面或组件的`index.json`中配置。
|
||||||
|
|
||||||
|
```json
|
||||||
|
"usingComponents": {
|
||||||
|
"t-message": "tdesign-miniprogram/message/message"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 引入 API
|
||||||
|
|
||||||
|
若以 API 形式调用 Message,则需在页面 `page.js` 中引入组件 API:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import Message from 'tdesign-miniprogram/message/index';
|
||||||
|
```
|
||||||
|
|
||||||
|
## 代码演示
|
||||||
|
|
||||||
|
### 基础消息通知
|
||||||
|
|
||||||
|
弹窗内容为纯文本、标题和副标题、带输入框,用 API `Message.info` 方法调用反馈类对话框。
|
||||||
|
|
||||||
|
|
||||||
|
{{ base }}
|
||||||
|
|
||||||
|
|
||||||
|
### 不同状态的消息通知
|
||||||
|
|
||||||
|
消息通知类型为普通(info)、警示(warning)、成功(success)、错误(error)
|
||||||
|
|
||||||
|
{{ status-message }}
|
||||||
|
|
||||||
|
### 自定义导航栏
|
||||||
|
|
||||||
|
当设置了 `navigationStyle = custom`,可以通过 offetset 来调整显示位置:
|
||||||
|
|
||||||
|
{{ custom-navigation }}
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
### Message Props
|
||||||
|
|
||||||
|
| 名称 | 类型 | 默认值 | 说明 | 必传|
|
||||||
|
| -- | -- | -- | -- | -- |
|
||||||
|
| action | String / Slot | - | 操作 | N |
|
||||||
|
| align | String | left | 文本对齐方式。可选项:left/center | N |
|
||||||
|
| close-btn | String / Boolean / Slot | undefined | 关闭按钮,可以自定义。值为 true 显示默认关闭按钮,值为 false 不显示关闭按钮。值类型为 string 则直接显示值,如:“关闭”。也可以完全自定义按钮 | N |
|
||||||
|
| content | String / Slot | - | 用于自定义消息弹出内容 | N |
|
||||||
|
| duration | Number | 3000 | 消息内置计时器,计时到达时会触发 duration-end 事件。单位:毫秒。值为 0 则表示没有计时器。 | N |
|
||||||
|
| external-classes | Array | - | 样式类名,分别用于设置 组件外层、消息内容、左侧图标、操作按钮、关闭按钮等元素类名。`['t-class', 't-class-content', 't-class-icon', 't-class-action', 't-class-close-btn']` | N |
|
||||||
|
| icon | String / Boolean / Slot | true | 消息提醒前面的图标。值为 true 则根据 theme 显示对应的图标,值为 false 则不显示图标。值为 'info' 或 'bell' 则显示组件内置图标。也可以完全自定义图标节点。TS 类型:`boolean | 'info' | 'bell'` | N |
|
||||||
|
| marquee | Boolean / Object | false | 跑马灯效果。speed 指速度控制;loop 指循环播放次数,值为 -1 表示循环播放,值为 0 表示不循环播放;delay 表示延迟多久开始播放。TS 类型:`boolean | DrawMarquee`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/message/type.ts) | N |
|
||||||
|
| offset | Array | - | 相对于 placement 的偏移量,示例:[-10, 20] 或 ['10rpx', '8rpx']。TS 类型:`Array<string | number>` | N |
|
||||||
|
| theme | String | info | 消息组件风格。可选项:info/success/warning/error。TS 类型:`MessageThemeList`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/message/type.ts) | N |
|
||||||
|
| visible | Boolean | false | 是否显示,隐藏时默认销毁组件 | N |
|
||||||
|
| z-index | Number | 15000 | 组件层级,样式默认为 15000 | N |
|
||||||
|
|
||||||
|
### Message Events
|
||||||
|
|
||||||
|
| 名称 | 参数 | 描述 |
|
||||||
|
| ---------------- | ---- | ---------------------------------------- |
|
||||||
|
| action-btn-click | - | 当操作按钮存在时,用户点击操作按钮时触发 |
|
||||||
|
| close-btn-click | - | 当关闭按钮存在时,用户点击关闭按钮触发 |
|
||||||
|
| duration-end | - | 计时结束后触发 |
|
||||||
100
components/message/api.md
Normal file
100
components/message/api.md
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
# Message
|
||||||
|
|
||||||
|
消息组件
|
||||||
|
|
||||||
|
### 特性及兼容性
|
||||||
|
|
||||||
|
无
|
||||||
|
|
||||||
|
## 引入
|
||||||
|
|
||||||
|
### 引入组件
|
||||||
|
|
||||||
|
在 `app.json` 或 `page.json` 中引入组件:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"usingComponents": {
|
||||||
|
"t-message": "tdesign-miniprogram/message/message"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 引入 API
|
||||||
|
|
||||||
|
若以 API 形式调用 Message,则需在页面 `page.js` 中引入组件 API:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import Message from 'tdesign-miniprogram/message/index';
|
||||||
|
```
|
||||||
|
|
||||||
|
## 用法
|
||||||
|
|
||||||
|
### 消息提示
|
||||||
|
|
||||||
|
用 API `Message.info` 方法调用反馈类对话框
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!-- page.wxml -->
|
||||||
|
<t-message id="t-message" />
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
// page.js
|
||||||
|
Message.info({
|
||||||
|
content: '消息内容',
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
### `<Message>` 组件
|
||||||
|
|
||||||
|
组件路径:`tdesign-miniprogram/message/message`
|
||||||
|
|
||||||
|
#### Props
|
||||||
|
|
||||||
|
| 属性 | 值类型 | 默认值 | 说明 |
|
||||||
|
| --------------- | ----------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | --------------- |
|
||||||
|
| visible | Boolean | false | 是否显示,隐藏时默认销毁组件 | N |
|
||||||
|
| content | String / Slot | - | 用于自定义消息弹出内容。 | N |
|
||||||
|
| theme | String | info | 消息组件风格。可选值:info/success/warning/error。 | N |
|
||||||
|
| duration | Number | 3000 | 消息内置计时器,计时到达时会触发 duration-end 事件。单位:毫秒。值为 0 则表示没有计时器。 | N |
|
||||||
|
| offset | `Object` | - | 偏移量,默认[0,0] |
|
||||||
|
| closeBtn | String / Boolean /Slot | undefined | 关闭按钮,可以自定义。值为 true 显示默认关闭按钮,值为 false 不显示关闭按钮。值类型为 string 则直接显示值,如:“关闭”。也可以完全自定义按钮。 | N |
|
||||||
|
| externalClasses | Array | - | 样式类名,分别用于设置 组件外层、消息内容、左侧图标、操作按钮、关闭按钮等元素类名。`['t-class', 't-class-content', 't-class-icon', 't-class-action', 't-class-close-btn']` | N |
|
||||||
|
| icon | String / Boolean / Slot | true | 消息提醒前面的图标。值为 true 则根据 theme 显示对应的图标,值为 false 则不显示图标。值为 'info' 或 'bell' 则显示组件内置图标。也可以完全自定义图标节点。TS 类型:`boolean | 'warning_fill' | 'sound_fill'` N |
|
||||||
|
| marquee | Object | - | 跑马灯效果,delay 动画延迟时间 (s);speed 滚动速率 (px/s)。N |
|
||||||
|
| zIndex | Number | - | 元素层级,样式默认为 5000 | N |
|
||||||
|
|
||||||
|
### Event
|
||||||
|
|
||||||
|
| 事件名 | 说明 | 参数 |
|
||||||
|
| -------------- | ---------------------------------------- | ---------------- |
|
||||||
|
| closeBtnClick | 点击关闭 icon 时触发 | - |
|
||||||
|
| actionBtnClick | 点击按钮时触发, 可通过 self 拿到组件实例 | `{ self: this }` |
|
||||||
|
|
||||||
|
### Slot
|
||||||
|
|
||||||
|
| 事件名 | 说明 |
|
||||||
|
| -------- | ------------------- |
|
||||||
|
| icon | 左侧 icon 处 |
|
||||||
|
| action | 右侧操作按钮。 N |
|
||||||
|
| closeBtn | 按钮(关闭 icon)处 |
|
||||||
|
|
||||||
|
### 外部样式
|
||||||
|
|
||||||
|
| class | 说明 |
|
||||||
|
| ----------------- | ----------- |
|
||||||
|
| t-class | 根节点 |
|
||||||
|
| t-class-content | 文本内容 |
|
||||||
|
| t-class-icon | 左侧 icon |
|
||||||
|
| t-class-action | 右侧 button |
|
||||||
|
| t-class-close-btn | 右侧 icon |
|
||||||
|
|
||||||
|
### 编程式调用
|
||||||
|
|
||||||
|
| 方法 | type | 返回值 | 说明 |
|
||||||
|
| -------------------------- | ------- | ------ | ------------------------------------------------------------------------------------------------------------ |
|
||||||
|
| Message.info(`options`) | info | `void` | 弹出消息,参数参考 Props,额外可指定`{context: WechatMiniprogram.Component.TrivialInstance,selector: string}` |
|
||||||
|
| Message.success(`options`) | success | `void` | 弹出消息,参数参考 Props,额外可指定`{context: WechatMiniprogram.Component.TrivialInstance,selector: string}` |
|
||||||
|
| Message.warning(`options`) | warning | `void` | 弹出消息,参数参考 Props,额外可指定`{context: WechatMiniprogram.Component.TrivialInstance,selector: string}` |
|
||||||
|
| Message.error(`options`) | error | `void` | 弹出消息,参数参考 Props,额外可指定`{context: WechatMiniprogram.Component.TrivialInstance,selector: string}` |
|
||||||
17
components/message/index.d.ts
vendored
Normal file
17
components/message/index.d.ts
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/// <reference types="miniprogram-api-typings" />
|
||||||
|
/// <reference types="miniprogram-api-typings" />
|
||||||
|
/// <reference types="miniprogram-api-typings" />
|
||||||
|
import { MessageProps } from './message.interface';
|
||||||
|
declare type Context = WechatMiniprogram.Page.TrivialInstance | WechatMiniprogram.Component.TrivialInstance;
|
||||||
|
interface MessageActionOptionsType extends Optional<MessageProps> {
|
||||||
|
context?: Context;
|
||||||
|
selector?: string;
|
||||||
|
}
|
||||||
|
declare const _default: {
|
||||||
|
info(options: MessageActionOptionsType): WechatMiniprogram.Component.TrivialInstance;
|
||||||
|
success(options: MessageActionOptionsType): WechatMiniprogram.Component.TrivialInstance;
|
||||||
|
warning(options: MessageActionOptionsType): WechatMiniprogram.Component.TrivialInstance;
|
||||||
|
error(options: MessageActionOptionsType): WechatMiniprogram.Component.TrivialInstance;
|
||||||
|
hide(options: MessageActionOptionsType): void;
|
||||||
|
};
|
||||||
|
export default _default;
|
||||||
46
components/message/index.js
Normal file
46
components/message/index.js
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
var __rest = (this && this.__rest) || function (s, e) {
|
||||||
|
var t = {};
|
||||||
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||||
|
t[p] = s[p];
|
||||||
|
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||||
|
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||||
|
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||||
|
t[p[i]] = s[p[i]];
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
};
|
||||||
|
import { MessageType } from './message.interface';
|
||||||
|
import { getInstance } from '../common/utils';
|
||||||
|
const showMessage = function (options, theme = MessageType.info) {
|
||||||
|
const { context, selector = '#t-message' } = options, otherOptions = __rest(options, ["context", "selector"]);
|
||||||
|
const instance = getInstance(context, selector);
|
||||||
|
if (instance) {
|
||||||
|
instance.resetData(() => {
|
||||||
|
instance.setData(Object.assign({ theme }, otherOptions), instance.show.bind(instance));
|
||||||
|
});
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
console.error('未找到组件,请确认 selector && context 是否正确');
|
||||||
|
};
|
||||||
|
export default {
|
||||||
|
info(options) {
|
||||||
|
return showMessage(options, MessageType.info);
|
||||||
|
},
|
||||||
|
success(options) {
|
||||||
|
return showMessage(options, MessageType.success);
|
||||||
|
},
|
||||||
|
warning(options) {
|
||||||
|
return showMessage(options, MessageType.warning);
|
||||||
|
},
|
||||||
|
error(options) {
|
||||||
|
return showMessage(options, MessageType.error);
|
||||||
|
},
|
||||||
|
hide(options) {
|
||||||
|
const { context, selector = '#t-message' } = Object.assign({}, options);
|
||||||
|
const instance = getInstance(context, selector);
|
||||||
|
if (!instance) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
instance.hide();
|
||||||
|
},
|
||||||
|
};
|
||||||
38
components/message/message.d.ts
vendored
Normal file
38
components/message/message.d.ts
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/// <reference types="miniprogram-api-typings" />
|
||||||
|
import { SuperComponent, ComponentsOptionsType } from '../common/src/index';
|
||||||
|
import { MessageProps } from './message.interface';
|
||||||
|
export default class Message extends SuperComponent {
|
||||||
|
externalClasses: string[];
|
||||||
|
options: ComponentsOptionsType;
|
||||||
|
properties: MessageProps;
|
||||||
|
data: {
|
||||||
|
prefix: string;
|
||||||
|
classPrefix: string;
|
||||||
|
visible: boolean;
|
||||||
|
loop: number;
|
||||||
|
animation: any[];
|
||||||
|
showAnimation: any[];
|
||||||
|
iconName: string;
|
||||||
|
wrapTop: number;
|
||||||
|
};
|
||||||
|
observers: {
|
||||||
|
marquee(val: any): void;
|
||||||
|
};
|
||||||
|
closeTimeoutContext: number;
|
||||||
|
nextAnimationContext: number;
|
||||||
|
resetAnimation: WechatMiniprogram.Animation;
|
||||||
|
showAnimation: WechatMiniprogram.AnimationExportResult;
|
||||||
|
hideAnimation: WechatMiniprogram.AnimationExportResult;
|
||||||
|
ready(): void;
|
||||||
|
memoInitalData(): void;
|
||||||
|
resetData(cb: () => void): void;
|
||||||
|
detached(): void;
|
||||||
|
setIcon(icon?: string | boolean): void;
|
||||||
|
checkAnimation(): void;
|
||||||
|
clearMessageAnimation(): void;
|
||||||
|
show(): void;
|
||||||
|
hide(): void;
|
||||||
|
reset(): void;
|
||||||
|
handleClose(): void;
|
||||||
|
handleBtnClick(): void;
|
||||||
|
}
|
||||||
24
components/message/message.interface.d.ts
vendored
Normal file
24
components/message/message.interface.d.ts
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
export declare enum MessageType {
|
||||||
|
info = "info",
|
||||||
|
success = "success",
|
||||||
|
warning = "warning",
|
||||||
|
error = "error"
|
||||||
|
}
|
||||||
|
export interface MessageMarquee {
|
||||||
|
speed?: number;
|
||||||
|
loop?: number;
|
||||||
|
delay?: number;
|
||||||
|
}
|
||||||
|
export interface MessageProps {
|
||||||
|
visible?: boolean;
|
||||||
|
content: string;
|
||||||
|
align?: string;
|
||||||
|
theme?: MessageType;
|
||||||
|
icon?: boolean | string;
|
||||||
|
closeBtn?: boolean;
|
||||||
|
action?: string;
|
||||||
|
marquee?: MessageMarquee;
|
||||||
|
offset?: object;
|
||||||
|
duration?: number;
|
||||||
|
zIndex?: number;
|
||||||
|
}
|
||||||
7
components/message/message.interface.js
Normal file
7
components/message/message.interface.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export var MessageType;
|
||||||
|
(function (MessageType) {
|
||||||
|
MessageType["info"] = "info";
|
||||||
|
MessageType["success"] = "success";
|
||||||
|
MessageType["warning"] = "warning";
|
||||||
|
MessageType["error"] = "error";
|
||||||
|
})(MessageType || (MessageType = {}));
|
||||||
180
components/message/message.js
Normal file
180
components/message/message.js
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
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 { getRect } from '../common/utils';
|
||||||
|
const { prefix } = config;
|
||||||
|
const name = `${prefix}-message`;
|
||||||
|
const SHOW_DURATION = 500;
|
||||||
|
let Message = class Message extends SuperComponent {
|
||||||
|
constructor() {
|
||||||
|
super(...arguments);
|
||||||
|
this.externalClasses = ['t-class', 't-class-content', 't-class-icon', 't-class-action', 't-class-close-btn'];
|
||||||
|
this.options = {
|
||||||
|
styleIsolation: 'apply-shared',
|
||||||
|
multipleSlots: true,
|
||||||
|
};
|
||||||
|
this.properties = Object.assign({}, props);
|
||||||
|
this.data = {
|
||||||
|
prefix,
|
||||||
|
classPrefix: name,
|
||||||
|
visible: false,
|
||||||
|
loop: -1,
|
||||||
|
animation: [],
|
||||||
|
showAnimation: [],
|
||||||
|
iconName: '',
|
||||||
|
wrapTop: -92,
|
||||||
|
};
|
||||||
|
this.observers = {
|
||||||
|
marquee(val) {
|
||||||
|
if (JSON.stringify(val) === '{}') {
|
||||||
|
this.setData({
|
||||||
|
marquee: {
|
||||||
|
speed: 50,
|
||||||
|
loop: -1,
|
||||||
|
delay: 5000,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
this.closeTimeoutContext = 0;
|
||||||
|
this.nextAnimationContext = 0;
|
||||||
|
this.resetAnimation = wx.createAnimation({
|
||||||
|
duration: 0,
|
||||||
|
timingFunction: 'linear',
|
||||||
|
});
|
||||||
|
this.showAnimation = wx.createAnimation({ duration: SHOW_DURATION, timingFunction: 'ease' }).translateY(0).step().export();
|
||||||
|
this.hideAnimation = wx
|
||||||
|
.createAnimation({ duration: SHOW_DURATION, timingFunction: 'ease' })
|
||||||
|
.translateY(this.data.wrapTop)
|
||||||
|
.step()
|
||||||
|
.export();
|
||||||
|
}
|
||||||
|
ready() {
|
||||||
|
this.memoInitalData();
|
||||||
|
this.setIcon();
|
||||||
|
}
|
||||||
|
memoInitalData() {
|
||||||
|
this.initalData = Object.assign(Object.assign({}, this.properties), this.data);
|
||||||
|
}
|
||||||
|
resetData(cb) {
|
||||||
|
this.setData(Object.assign({}, this.initalData), cb);
|
||||||
|
}
|
||||||
|
detached() {
|
||||||
|
this.clearMessageAnimation();
|
||||||
|
}
|
||||||
|
setIcon(icon = this.properties.icon) {
|
||||||
|
if (!icon) {
|
||||||
|
this.setData({ iconName: '' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (typeof icon === 'string') {
|
||||||
|
this.setData({
|
||||||
|
iconName: `${icon}`,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (icon) {
|
||||||
|
let nextValue = 'notification';
|
||||||
|
const { theme } = this.properties;
|
||||||
|
const themeMessage = {
|
||||||
|
info: 'error-circle',
|
||||||
|
success: 'check-circle',
|
||||||
|
warning: 'error-circle',
|
||||||
|
error: 'error-circle',
|
||||||
|
};
|
||||||
|
nextValue = themeMessage[theme];
|
||||||
|
this.setData({ iconName: nextValue });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkAnimation() {
|
||||||
|
if (!this.properties.marquee) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const speeding = this.properties.marquee.speed;
|
||||||
|
if (this.data.loop > 0) {
|
||||||
|
this.data.loop -= 1;
|
||||||
|
}
|
||||||
|
else if (this.data.loop === 0) {
|
||||||
|
this.setData({ animation: this.resetAnimation.translateX(0).step().export() });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.nextAnimationContext) {
|
||||||
|
this.clearMessageAnimation();
|
||||||
|
}
|
||||||
|
const warpID = `#${name}__text-wrap`;
|
||||||
|
const nodeID = `#${name}__text`;
|
||||||
|
Promise.all([getRect(this, nodeID), getRect(this, warpID)]).then(([nodeRect, wrapRect]) => {
|
||||||
|
this.setData({
|
||||||
|
animation: this.resetAnimation.translateX(wrapRect.width).step().export(),
|
||||||
|
}, () => {
|
||||||
|
const durationTime = ((nodeRect.width + wrapRect.width) / speeding) * 1000;
|
||||||
|
const nextAnimation = wx
|
||||||
|
.createAnimation({
|
||||||
|
duration: durationTime,
|
||||||
|
})
|
||||||
|
.translateX(-nodeRect.width)
|
||||||
|
.step()
|
||||||
|
.export();
|
||||||
|
setTimeout(() => {
|
||||||
|
this.nextAnimationContext = setTimeout(this.checkAnimation.bind(this), durationTime);
|
||||||
|
this.setData({ animation: nextAnimation });
|
||||||
|
}, 20);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
clearMessageAnimation() {
|
||||||
|
clearTimeout(this.nextAnimationContext);
|
||||||
|
this.nextAnimationContext = 0;
|
||||||
|
}
|
||||||
|
show() {
|
||||||
|
const { duration, icon, marquee } = this.properties;
|
||||||
|
this.setData({ visible: true, loop: marquee.loop });
|
||||||
|
this.reset();
|
||||||
|
this.setIcon(icon);
|
||||||
|
this.checkAnimation();
|
||||||
|
if (duration && duration > 0) {
|
||||||
|
this.closeTimeoutContext = setTimeout(() => {
|
||||||
|
this.hide();
|
||||||
|
this.triggerEvent('durationEnd', { self: this });
|
||||||
|
}, duration);
|
||||||
|
}
|
||||||
|
const wrapID = `#${name}`;
|
||||||
|
getRect(this, wrapID).then((wrapRect) => {
|
||||||
|
this.setData({ wrapTop: -wrapRect.height }, () => {
|
||||||
|
this.setData({ showAnimation: this.showAnimation });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
hide() {
|
||||||
|
this.reset();
|
||||||
|
this.setData({ showAnimation: this.hideAnimation });
|
||||||
|
setTimeout(() => {
|
||||||
|
this.setData({ visible: false, animation: [] });
|
||||||
|
}, SHOW_DURATION);
|
||||||
|
}
|
||||||
|
reset() {
|
||||||
|
if (this.nextAnimationContext) {
|
||||||
|
this.clearMessageAnimation();
|
||||||
|
}
|
||||||
|
clearTimeout(this.closeTimeoutContext);
|
||||||
|
this.closeTimeoutContext = 0;
|
||||||
|
}
|
||||||
|
handleClose() {
|
||||||
|
this.hide();
|
||||||
|
this.triggerEvent('closeBtnClick');
|
||||||
|
}
|
||||||
|
handleBtnClick() {
|
||||||
|
this.triggerEvent('actionBtnClick', { self: this });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Message = __decorate([
|
||||||
|
wxComponent()
|
||||||
|
], Message);
|
||||||
|
export default Message;
|
||||||
7
components/message/message.json
Normal file
7
components/message/message.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"component": true,
|
||||||
|
"usingComponents": {
|
||||||
|
"t-icon": "../icon/icon",
|
||||||
|
"t-button": "../button/button"
|
||||||
|
}
|
||||||
|
}
|
||||||
51
components/message/message.wxml
Normal file
51
components/message/message.wxml
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<wxs src="./message.wxs" module="this"></wxs>
|
||||||
|
|
||||||
|
<block wx:if="{{visible}}">
|
||||||
|
<view
|
||||||
|
class="{{classPrefix}} {{prefix}}-class {{classPrefix}}--{{theme}}"
|
||||||
|
style="z-index: {{zIndex}};{{this.getMessageStylesOffset({ offset })}};transform: translateY({{wrapTop}}px)"
|
||||||
|
animation="{{showAnimation}}"
|
||||||
|
id="{{classPrefix}}"
|
||||||
|
>
|
||||||
|
<t-icon
|
||||||
|
wx:if="{{iconName}}"
|
||||||
|
name="{{iconName}}"
|
||||||
|
class="{{classPrefix}}__icon--left {{prefix}}-class-icon"
|
||||||
|
size="44rpx"
|
||||||
|
/>
|
||||||
|
<slot name="icon" />
|
||||||
|
|
||||||
|
<view
|
||||||
|
class="{{classPrefix}}__text-wrap {{marquee ? '{{classPrefix}}__text-nowrap' : ''}}"
|
||||||
|
style="text-align: {{align}}"
|
||||||
|
id="{{classPrefix}}__text-wrap"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
class="{{classPrefix}}__text {{prefix}}-class-content"
|
||||||
|
id="{{classPrefix}}__text"
|
||||||
|
animation="{{animation}}"
|
||||||
|
>
|
||||||
|
<view wx:if="{{content}}">{{content}}</view>
|
||||||
|
<slot name="content"></slot>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<t-button
|
||||||
|
wx:if="{{action}}"
|
||||||
|
t-class="{{classPrefix}}__btn--right {{prefix}}-class-action"
|
||||||
|
size="small"
|
||||||
|
bind:tap="handleBtnClick"
|
||||||
|
>{{action}}</t-button
|
||||||
|
>
|
||||||
|
<slot name="action" />
|
||||||
|
|
||||||
|
<t-icon
|
||||||
|
wx:if="{{closeBtn}}"
|
||||||
|
class="{{classPrefix}}__icon--right {{prefix}}-class-close-btn"
|
||||||
|
name="close"
|
||||||
|
size="20px"
|
||||||
|
bind:tap="handleClose"
|
||||||
|
/>
|
||||||
|
<slot name="closeBtn" />
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
16
components/message/message.wxs
Normal file
16
components/message/message.wxs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
var changeNumToStr = function (arr) {
|
||||||
|
return arr.map(function (item) {
|
||||||
|
return typeof item === 'number' ? item + 'rpx' : item;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var getMessageStylesOffset = function (props) {
|
||||||
|
var arr = changeNumToStr(props.offset);
|
||||||
|
var styleOffset = '';
|
||||||
|
styleOffset += 'top:' + arr[0] + ';';
|
||||||
|
styleOffset += 'right:' + arr[1] + ';';
|
||||||
|
styleOffset += 'left:' + arr[1] + ';';
|
||||||
|
return styleOffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.getMessageStylesOffset = getMessageStylesOffset;
|
||||||
89
components/message/message.wxss
Normal file
89
components/message/message.wxss
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
.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-message {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
z-index: 15000;
|
||||||
|
color: #0052d9;
|
||||||
|
padding: 24rpx 32rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
line-height: 1;
|
||||||
|
background: #ffffff;
|
||||||
|
box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
.t-message__text {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.t-message__text-wrap {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
line-height: 44rpx;
|
||||||
|
}
|
||||||
|
.t-message__text-nowrap {
|
||||||
|
word-break: keep-all;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.t-message--info {
|
||||||
|
color: #0052d9;
|
||||||
|
}
|
||||||
|
.t-message--success {
|
||||||
|
color: #00a870;
|
||||||
|
}
|
||||||
|
.t-message--warning {
|
||||||
|
color: #ed7b2f;
|
||||||
|
}
|
||||||
|
.t-message--error {
|
||||||
|
color: #e34d59;
|
||||||
|
}
|
||||||
|
.t-message .t-message__icon--left {
|
||||||
|
margin-right: 16rpx;
|
||||||
|
}
|
||||||
|
.t-message .t-message__icon--right,
|
||||||
|
.t-message .t-message__btn--right {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
margin-left: 16rpx;
|
||||||
|
}
|
||||||
|
.t-message .t-message__btn--right {
|
||||||
|
font-size: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
height: 44rpx;
|
||||||
|
line-height: 44rpx;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
border-color: inherit;
|
||||||
|
color: inherit;
|
||||||
|
min-height: 0;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
3
components/message/props.d.ts
vendored
Normal file
3
components/message/props.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import { TdMessageProps } from './type';
|
||||||
|
declare const props: TdMessageProps;
|
||||||
|
export default props;
|
||||||
49
components/message/props.js
Normal file
49
components/message/props.js
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
const props = {
|
||||||
|
action: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
align: {
|
||||||
|
type: String,
|
||||||
|
value: 'left',
|
||||||
|
},
|
||||||
|
closeBtn: {
|
||||||
|
type: String,
|
||||||
|
optionalTypes: [Boolean],
|
||||||
|
value: undefined,
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
duration: {
|
||||||
|
type: Number,
|
||||||
|
value: 3000,
|
||||||
|
},
|
||||||
|
externalClasses: {
|
||||||
|
type: Array,
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
optionalTypes: [Boolean],
|
||||||
|
value: true,
|
||||||
|
},
|
||||||
|
marquee: {
|
||||||
|
type: null,
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
|
offset: {
|
||||||
|
type: Array,
|
||||||
|
},
|
||||||
|
theme: {
|
||||||
|
type: String,
|
||||||
|
value: 'info',
|
||||||
|
},
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
|
zIndex: {
|
||||||
|
type: Number,
|
||||||
|
value: 15000,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export default props;
|
||||||
70
components/message/type.d.ts
vendored
Normal file
70
components/message/type.d.ts
vendored
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
export interface TdMessageProps {
|
||||||
|
action?: {
|
||||||
|
type: StringConstructor;
|
||||||
|
value?: string;
|
||||||
|
required?: boolean;
|
||||||
|
};
|
||||||
|
align?: {
|
||||||
|
type: StringConstructor;
|
||||||
|
value?: 'left' | 'center';
|
||||||
|
required?: boolean;
|
||||||
|
};
|
||||||
|
closeBtn?: {
|
||||||
|
type: StringConstructor;
|
||||||
|
optionalTypes: Array<BooleanConstructor>;
|
||||||
|
value?: string | boolean;
|
||||||
|
required?: boolean;
|
||||||
|
};
|
||||||
|
content?: {
|
||||||
|
type: StringConstructor;
|
||||||
|
value?: string;
|
||||||
|
required?: boolean;
|
||||||
|
};
|
||||||
|
duration?: {
|
||||||
|
type: NumberConstructor;
|
||||||
|
value?: number;
|
||||||
|
required?: boolean;
|
||||||
|
};
|
||||||
|
externalClasses?: {
|
||||||
|
type: ArrayConstructor;
|
||||||
|
value?: ['t-class', 't-class-content', 't-class-icon', 't-class-action', 't-class-close-btn'];
|
||||||
|
required?: boolean;
|
||||||
|
};
|
||||||
|
icon?: {
|
||||||
|
type: StringConstructor;
|
||||||
|
optionalTypes: Array<BooleanConstructor>;
|
||||||
|
value?: boolean | 'info' | 'bell';
|
||||||
|
required?: boolean;
|
||||||
|
};
|
||||||
|
marquee?: {
|
||||||
|
type: null;
|
||||||
|
value?: DrawMarquee | boolean;
|
||||||
|
required?: boolean;
|
||||||
|
};
|
||||||
|
offset?: {
|
||||||
|
type: ArrayConstructor;
|
||||||
|
value?: Array<string | number>;
|
||||||
|
required?: boolean;
|
||||||
|
};
|
||||||
|
theme?: {
|
||||||
|
type: StringConstructor;
|
||||||
|
value?: MessageThemeList;
|
||||||
|
required?: boolean;
|
||||||
|
};
|
||||||
|
visible?: {
|
||||||
|
type: BooleanConstructor;
|
||||||
|
value?: boolean;
|
||||||
|
required?: boolean;
|
||||||
|
};
|
||||||
|
zIndex?: {
|
||||||
|
type: NumberConstructor;
|
||||||
|
value?: number;
|
||||||
|
required?: boolean;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
export interface DrawMarquee {
|
||||||
|
speed?: number;
|
||||||
|
loop?: number;
|
||||||
|
delay?: number;
|
||||||
|
}
|
||||||
|
export declare type MessageThemeList = 'info' | 'success' | 'warning' | 'error';
|
||||||
1
components/message/type.js
Normal file
1
components/message/type.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export {};
|
||||||
25
components/toast/README.en-US.md
Normal file
25
components/toast/README.en-US.md
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
:: BASE_DOC ::
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
### Toast Props
|
||||||
|
|
||||||
|
name | type | default | description | required
|
||||||
|
-- | -- | -- | -- | --
|
||||||
|
direction | String | row | options:row/column | N
|
||||||
|
duration | Number | 2000 | \- | N
|
||||||
|
external-classes | Array | - | `['t-class']` | N
|
||||||
|
icon | String | - | \- | N
|
||||||
|
message | String / Slot | - | \- | N
|
||||||
|
overlay-props | Object | {} | \- | N
|
||||||
|
placement | String | middle | options: top/middle/bottom | N
|
||||||
|
prevent-scroll-through | Boolean | false | \- | N
|
||||||
|
show-overlay | Boolean | false | \- | N
|
||||||
|
theme | String | - | options:loading/success/fail | N
|
||||||
|
|
||||||
|
### Toast Events
|
||||||
|
|
||||||
|
name | params | description
|
||||||
|
-- | -- | --
|
||||||
|
close | \- | \-
|
||||||
|
destory | \- | \-
|
||||||
59
components/toast/README.md
Normal file
59
components/toast/README.md
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
---
|
||||||
|
title: Toast 轻提示
|
||||||
|
description: 用于轻量级反馈或提示,不会打断用户操作。
|
||||||
|
spline: message
|
||||||
|
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-83%25-blue" /></span>
|
||||||
|
## 引入
|
||||||
|
|
||||||
|
全局引入,在 miniprogram 根目录下的`app.json`中配置,局部引入,在需要引入的页面或组件的`index.json`中配置。
|
||||||
|
|
||||||
|
```json
|
||||||
|
"usingComponents": {
|
||||||
|
"t-toast": "tdesign-miniprogram/toast/toast"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 代码演示
|
||||||
|
|
||||||
|
### 基础提示
|
||||||
|
|
||||||
|
{{ base }}
|
||||||
|
|
||||||
|
### 默认提示
|
||||||
|
|
||||||
|
{{ normal }}
|
||||||
|
|
||||||
|
### 不同位置的提示
|
||||||
|
|
||||||
|
{{ display }}
|
||||||
|
|
||||||
|
### 显示遮罩
|
||||||
|
{{ cover }}
|
||||||
|
|
||||||
|
### 手动关闭
|
||||||
|
{{ close }}
|
||||||
|
## API
|
||||||
|
### Toast Props
|
||||||
|
|
||||||
|
名称 | 类型 | 默认值 | 说明 | 必传
|
||||||
|
-- | -- | -- | -- | --
|
||||||
|
direction | String | row | 图标排列方式。可选项:row/column | N
|
||||||
|
duration | Number | 2000 | 弹窗显示毫秒数 | N
|
||||||
|
external-classes | Array | - | 组件类名。`['t-class']` | N
|
||||||
|
icon | String | - | 自定义图标 | N
|
||||||
|
message | String / Slot | - | 弹窗显示文字 | N
|
||||||
|
overlay-props | Object | {} | 遮罩层属性,透传至 Overlay | N
|
||||||
|
placement | String | middle | 弹窗展示位置。可选项: top/middle/bottom | N
|
||||||
|
prevent-scroll-through | Boolean | false | 防止滚动穿透,即不允许点击和滚动 | N
|
||||||
|
show-overlay | Boolean | false | 是否显示遮罩层 | N
|
||||||
|
theme | String | - | 提示类型。可选项:loading/success/fail | N
|
||||||
|
|
||||||
|
### Toast Events
|
||||||
|
|
||||||
|
名称 | 参数 | 描述
|
||||||
|
-- | -- | --
|
||||||
|
close | - | 轻提示隐藏的时候触发
|
||||||
|
destory | - | 轻提示销毁的时候触发
|
||||||
21
components/toast/index.d.ts
vendored
Normal file
21
components/toast/index.d.ts
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
// @ts-ignore
|
||||||
|
declare type Context = WechatMiniprogram.Page.TrivialInstance | WechatMiniprogram.Component.TrivialInstance;
|
||||||
|
declare type ToastType = 'loading' | 'success' | 'fail';
|
||||||
|
declare type ToastPositionType = 'top' | 'middle' | 'bottom';
|
||||||
|
declare type ToastDirectionType = 'row' | 'column';
|
||||||
|
export declare type ToastOptionsType = {
|
||||||
|
context?: Context;
|
||||||
|
selector?: string;
|
||||||
|
icon?: string;
|
||||||
|
message?: string;
|
||||||
|
duration?: number;
|
||||||
|
theme?: ToastType;
|
||||||
|
placement?: ToastPositionType;
|
||||||
|
preventScrollThrough?: boolean;
|
||||||
|
direction?: ToastDirectionType;
|
||||||
|
close?: <T = any>() => T;
|
||||||
|
};
|
||||||
|
declare function Toast(options: ToastOptionsType): void;
|
||||||
|
declare function showToast(options?: ToastOptionsType): void;
|
||||||
|
declare function hideToast(options?: ToastOptionsType): void;
|
||||||
|
export { Toast as default, showToast, hideToast };
|
||||||
31
components/toast/index.js
Normal file
31
components/toast/index.js
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
var __rest = (this && this.__rest) || function (s, e) {
|
||||||
|
var t = {};
|
||||||
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||||
|
t[p] = s[p];
|
||||||
|
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||||
|
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||||
|
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||||
|
t[p[i]] = s[p[i]];
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
};
|
||||||
|
import { getInstance } from '../common/utils';
|
||||||
|
function Toast(options) {
|
||||||
|
var _a;
|
||||||
|
const { context, selector = '#t-toast' } = options, Options = __rest(options, ["context", "selector"]);
|
||||||
|
const instance = getInstance(context, selector);
|
||||||
|
if (instance) {
|
||||||
|
instance.show(Object.assign(Object.assign({}, Options), { duration: (_a = Options.duration) !== null && _a !== void 0 ? _a : 2000 }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function showToast(options = {}) {
|
||||||
|
Toast(options);
|
||||||
|
}
|
||||||
|
function hideToast(options = {}) {
|
||||||
|
const { context, selector = '#t-toast' } = options;
|
||||||
|
const instance = getInstance(context, selector);
|
||||||
|
if (instance) {
|
||||||
|
instance.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export { Toast as default, showToast, hideToast };
|
||||||
3
components/toast/props.d.ts
vendored
Normal file
3
components/toast/props.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import { TdToastProps } from './type';
|
||||||
|
declare const props: TdToastProps;
|
||||||
|
export default props;
|
||||||
40
components/toast/props.js
Normal file
40
components/toast/props.js
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
const props = {
|
||||||
|
direction: {
|
||||||
|
type: String,
|
||||||
|
value: 'row',
|
||||||
|
},
|
||||||
|
duration: {
|
||||||
|
type: Number,
|
||||||
|
value: 2000,
|
||||||
|
},
|
||||||
|
externalClasses: {
|
||||||
|
type: Array,
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
value: '',
|
||||||
|
},
|
||||||
|
message: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
overlayProps: {
|
||||||
|
type: Object,
|
||||||
|
value: {},
|
||||||
|
},
|
||||||
|
placement: {
|
||||||
|
type: String,
|
||||||
|
value: 'middle',
|
||||||
|
},
|
||||||
|
preventScrollThrough: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
|
showOverlay: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
|
theme: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export default props;
|
||||||
25
components/toast/toast.d.ts
vendored
Normal file
25
components/toast/toast.d.ts
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/// <reference types="node" />
|
||||||
|
import { SuperComponent } from '../common/src/index';
|
||||||
|
import { ToastOptionsType } from './index';
|
||||||
|
declare type Timer = NodeJS.Timeout | null;
|
||||||
|
export default class Toast extends SuperComponent {
|
||||||
|
externalClasses: string[];
|
||||||
|
options: {
|
||||||
|
multipleSlots: boolean;
|
||||||
|
};
|
||||||
|
behaviors: string[];
|
||||||
|
hideTimer: Timer;
|
||||||
|
data: {
|
||||||
|
prefix: string;
|
||||||
|
classPrefix: string;
|
||||||
|
typeMapIcon: string;
|
||||||
|
};
|
||||||
|
properties: import("./type").TdToastProps;
|
||||||
|
detached(): void;
|
||||||
|
methods: {
|
||||||
|
show(options: ToastOptionsType): void;
|
||||||
|
hide(): void;
|
||||||
|
destroyed(): void;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
export {};
|
||||||
78
components/toast/toast.js
Normal file
78
components/toast/toast.js
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
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 transition from '../mixins/transition';
|
||||||
|
const { prefix } = config;
|
||||||
|
const name = `${prefix}-toast`;
|
||||||
|
let Toast = class Toast extends SuperComponent {
|
||||||
|
constructor() {
|
||||||
|
super(...arguments);
|
||||||
|
this.externalClasses = [`${prefix}-class`];
|
||||||
|
this.options = {
|
||||||
|
multipleSlots: true,
|
||||||
|
};
|
||||||
|
this.behaviors = [transition()];
|
||||||
|
this.hideTimer = null;
|
||||||
|
this.data = {
|
||||||
|
prefix,
|
||||||
|
classPrefix: name,
|
||||||
|
typeMapIcon: '',
|
||||||
|
};
|
||||||
|
this.properties = props;
|
||||||
|
this.methods = {
|
||||||
|
show(options) {
|
||||||
|
if (this.hideTimer)
|
||||||
|
clearTimeout(this.hideTimer);
|
||||||
|
const iconMap = {
|
||||||
|
loading: 'loading',
|
||||||
|
success: 'check-circle',
|
||||||
|
fail: 'error-circle',
|
||||||
|
};
|
||||||
|
const typeMapIcon = iconMap[options === null || options === void 0 ? void 0 : options.theme] || '';
|
||||||
|
const defaultOptions = {
|
||||||
|
direction: props.direction.value,
|
||||||
|
duration: props.duration.value,
|
||||||
|
icon: props.icon.value,
|
||||||
|
message: props.message.value,
|
||||||
|
placement: props.placement.value,
|
||||||
|
preventScrollThrough: props.preventScrollThrough.value,
|
||||||
|
theme: props.theme.value,
|
||||||
|
};
|
||||||
|
const data = Object.assign(Object.assign(Object.assign({}, defaultOptions), options), { visible: true, typeMapIcon });
|
||||||
|
const { duration } = data;
|
||||||
|
this.setData(data);
|
||||||
|
if (duration > 0) {
|
||||||
|
this.hideTimer = setTimeout(() => {
|
||||||
|
this.hide();
|
||||||
|
}, duration);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hide() {
|
||||||
|
var _a, _b;
|
||||||
|
this.setData({ visible: false });
|
||||||
|
(_b = (_a = this.data) === null || _a === void 0 ? void 0 : _a.close) === null || _b === void 0 ? void 0 : _b.call(_a);
|
||||||
|
this.triggerEvent('close');
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
if (this.hideTimer) {
|
||||||
|
clearTimeout(this.hideTimer);
|
||||||
|
this.hideTimer = null;
|
||||||
|
}
|
||||||
|
this.triggerEvent('destory');
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
detached() {
|
||||||
|
this.destroyed();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Toast = __decorate([
|
||||||
|
wxComponent()
|
||||||
|
], Toast);
|
||||||
|
export default Toast;
|
||||||
8
components/toast/toast.json
Normal file
8
components/toast/toast.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"component": true,
|
||||||
|
"usingComponents": {
|
||||||
|
"t-icon": "../icon/icon",
|
||||||
|
"t-loading": "../loading/loading",
|
||||||
|
"t-overlay": "../overlay/overlay"
|
||||||
|
}
|
||||||
|
}
|
||||||
36
components/toast/toast.wxml
Normal file
36
components/toast/toast.wxml
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<view
|
||||||
|
wx:if="{{realVisible}}"
|
||||||
|
class="{{classPrefix}} {{prefix}}-class {{transitionClass}} {{classPrefix}}--{{direction}}"
|
||||||
|
style="top: {{placement === 'top' ? '25%' : placement === 'bottom' ? '75%': '45%'}}"
|
||||||
|
bind:transitionend="onTransitionEnd"
|
||||||
|
>
|
||||||
|
<view class="{{classPrefix}}__content {{classPrefix}}__content--{{direction}}">
|
||||||
|
<t-icon
|
||||||
|
wx:if="{{typeMapIcon!=='loading' || icon}}"
|
||||||
|
name="{{typeMapIcon || icon}}"
|
||||||
|
class="{{classPrefix}}__icon {{classPrefix}}__icon--{{direction}}"
|
||||||
|
color="#fff"
|
||||||
|
size="{{direction === 'row' ? '42rpx' : '96rpx'}}"
|
||||||
|
/>
|
||||||
|
<t-loading
|
||||||
|
wx:if="{{typeMapIcon === 'loading'}}"
|
||||||
|
theme="circular"
|
||||||
|
size="{{direction === 'row' ? '42rpx' : '96rpx'}}"
|
||||||
|
loading
|
||||||
|
inherit-color
|
||||||
|
style="color: white"
|
||||||
|
layout="vertical"
|
||||||
|
/>
|
||||||
|
<slot name="icon" />
|
||||||
|
<view class="{{classPrefix}}__text {{typeMapIcon || icon ? classPrefix + '__text--' + direction : ''}}"
|
||||||
|
>{{message}}</view
|
||||||
|
>
|
||||||
|
<slot name="message" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<t-overlay
|
||||||
|
visible="{{realVisible && (showOverlay || preventScrollThrough)}}"
|
||||||
|
z-index="{{overlayProps.zIndex}}"
|
||||||
|
backgroundColor="{{preventScrollThrough ? 'transparent' : overlayProps.backgroundColor}}"
|
||||||
|
preventScrollThrough="{{preventScrollThrough || overlayProps.preventScrollThrough}}"
|
||||||
|
/>
|
||||||
84
components/toast/toast.wxss
Normal file
84
components/toast/toast.wxss
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
.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-toast {
|
||||||
|
position: fixed;
|
||||||
|
right: -50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
z-index: 12001;
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 300ms ease;
|
||||||
|
background-color: rgba(0, 0, 0, 0.6);
|
||||||
|
border-radius: 8rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: white;
|
||||||
|
max-width: 374rpx;
|
||||||
|
width: fit-content;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.t-toast--column {
|
||||||
|
padding: 48rpx;
|
||||||
|
min-width: 272rpx;
|
||||||
|
min-height: 260rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
}
|
||||||
|
.t-toast__content {
|
||||||
|
align-items: center;
|
||||||
|
line-height: 44rpx;
|
||||||
|
}
|
||||||
|
.t-toast__content--row {
|
||||||
|
display: flex;
|
||||||
|
text-align: left;
|
||||||
|
padding: 28rpx 44rpx;
|
||||||
|
}
|
||||||
|
.t-toast__content--column {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.t-toast__icon--row {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.t-toast__text {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
-webkit-line-clamp: 3;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
}
|
||||||
|
.t-toast__text--column {
|
||||||
|
margin-top: 24rpx;
|
||||||
|
}
|
||||||
|
.t-toast__text--row {
|
||||||
|
margin-left: 12rpx;
|
||||||
|
}
|
||||||
|
.t-toast.t-fade-enter,
|
||||||
|
.t-toast.t-fade-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
42
components/toast/type.d.ts
vendored
Normal file
42
components/toast/type.d.ts
vendored
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
export interface TdToastProps {
|
||||||
|
direction?: {
|
||||||
|
type: StringConstructor;
|
||||||
|
value?: 'row' | 'column';
|
||||||
|
};
|
||||||
|
duration?: {
|
||||||
|
type: NumberConstructor;
|
||||||
|
value?: number;
|
||||||
|
};
|
||||||
|
externalClasses?: {
|
||||||
|
type: ArrayConstructor;
|
||||||
|
value?: ['t-class'];
|
||||||
|
};
|
||||||
|
icon?: {
|
||||||
|
type: StringConstructor;
|
||||||
|
value?: string;
|
||||||
|
};
|
||||||
|
message?: {
|
||||||
|
type: StringConstructor;
|
||||||
|
value?: string;
|
||||||
|
};
|
||||||
|
overlayProps?: {
|
||||||
|
type: ObjectConstructor;
|
||||||
|
value?: object;
|
||||||
|
};
|
||||||
|
placement?: {
|
||||||
|
type: StringConstructor;
|
||||||
|
value?: 'top' | 'middle' | 'bottom';
|
||||||
|
};
|
||||||
|
preventScrollThrough?: {
|
||||||
|
type: BooleanConstructor;
|
||||||
|
value?: boolean;
|
||||||
|
};
|
||||||
|
showOverlay?: {
|
||||||
|
type: BooleanConstructor;
|
||||||
|
value?: boolean;
|
||||||
|
};
|
||||||
|
theme?: {
|
||||||
|
type: StringConstructor;
|
||||||
|
value?: 'loading' | 'success' | 'fail';
|
||||||
|
};
|
||||||
|
}
|
||||||
1
components/toast/type.js
Normal file
1
components/toast/type.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export {};
|
||||||
@@ -3,7 +3,6 @@
|
|||||||
"t-date-time-picker": "/components/date-time-picker/date-time-picker",
|
"t-date-time-picker": "/components/date-time-picker/date-time-picker",
|
||||||
"t-picker": "/components/picker/picker",
|
"t-picker": "/components/picker/picker",
|
||||||
"t-picker-item": "/components/picker/picker-item",
|
"t-picker-item": "/components/picker/picker-item",
|
||||||
"jh-lunar-picker": "/components/jh-lunar-picker/index",
|
|
||||||
"t-switch": "/components/switch/switch",
|
"t-switch": "/components/switch/switch",
|
||||||
"t-button": "/components/button/button"
|
"t-button": "/components/button/button"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
// pages/message/index.js
|
// pages/message/index.js
|
||||||
|
import Toast from '../../components/toast/index';
|
||||||
|
import Message from '../../components/message/index';
|
||||||
Page({
|
Page({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -7,60 +9,27 @@ Page({
|
|||||||
data: {
|
data: {
|
||||||
aIconList: ['check-rectangle','star','notification-filled','circle'],
|
aIconList: ['check-rectangle','star','notification-filled','circle'],
|
||||||
},
|
},
|
||||||
|
toast(option) {
|
||||||
/**
|
Toast({
|
||||||
* 生命周期函数--监听页面加载
|
context: this,
|
||||||
*/
|
selector: '#t-toast',
|
||||||
onLoad(options) {
|
...option,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
startVipButton(e){
|
||||||
/**
|
this.toast({
|
||||||
* 生命周期函数--监听页面初次渲染完成
|
message: '已获得会员资格!',
|
||||||
*/
|
theme: 'success',
|
||||||
onReady() {
|
placement: 'bottom',
|
||||||
|
direction: 'column',
|
||||||
},
|
});
|
||||||
|
Message.info({
|
||||||
/**
|
context: this,
|
||||||
* 生命周期函数--监听页面显示
|
offset: [20, 32],
|
||||||
*/
|
marquee: { speed: 50, loop: -1, delay: 5000 },
|
||||||
onShow() {
|
icon: false,
|
||||||
|
content: '请关注微信公众号Quinn,回复"VIP"',
|
||||||
},
|
duration: -1,
|
||||||
|
});
|
||||||
/**
|
|
||||||
* 生命周期函数--监听页面隐藏
|
|
||||||
*/
|
|
||||||
onHide() {
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 生命周期函数--监听页面卸载
|
|
||||||
*/
|
|
||||||
onUnload() {
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 页面相关事件处理函数--监听用户下拉动作
|
|
||||||
*/
|
|
||||||
onPullDownRefresh() {
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 页面上拉触底事件的处理函数
|
|
||||||
*/
|
|
||||||
onReachBottom() {
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户点击右上角分享
|
|
||||||
*/
|
|
||||||
onShareAppMessage() {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
{
|
{
|
||||||
"usingComponents": {
|
"usingComponents": {
|
||||||
"foot-tab": "../foot-tab/foot-tab"
|
"foot-tab": "../foot-tab/foot-tab",
|
||||||
|
"t-empty": "/components/empty/empty",
|
||||||
|
"t-button": "/components/button/button",
|
||||||
|
"t-toast": "/components/toast/toast",
|
||||||
|
"t-message": "/components/message/message"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
<!--pages/message/index.wxml-->
|
<!--pages/message/index.wxml-->
|
||||||
<text>您有新的消息</text>
|
<t-message id="t-message" />
|
||||||
|
<t-empty t-class="empty-cls" icon="info-circle-filled" description="开通会员解锁完整功能">
|
||||||
|
<t-button slot="action" theme="danger" variant="plain" bind:tap="startVipButton">开通会员</t-button>
|
||||||
|
</t-empty>
|
||||||
|
<t-toast id="t-toast" />
|
||||||
<view>
|
<view>
|
||||||
<foot-tab iconList="{{aIconList}}"/>
|
<foot-tab iconList="{{aIconList}}"/>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@@ -1 +1,4 @@
|
|||||||
/* pages/message/index.wxss */
|
/* pages/message/index.wxss */
|
||||||
|
.empty-cls {
|
||||||
|
margin-top: 250rpx !important;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user