个人消息
This commit is contained in:
73
components/dialog/README.md
Normal file
73
components/dialog/README.md
Normal file
@@ -0,0 +1,73 @@
|
||||
---
|
||||
title: Dialog 对话框
|
||||
description: 用于显示重要提示或请求用户进行重要操作,一种打断当前操作的模态视图。
|
||||
spline: message
|
||||
isComponent: true
|
||||
---
|
||||
|
||||
<span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20lines-97%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-94%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20branches-82%25-blue" /></span>
|
||||
## 引入
|
||||
|
||||
全局引入,在 miniprogram 根目录下的`app.json`中配置,局部引入,在需要引入的页面或组件的`index.json`中配置。
|
||||
|
||||
```json
|
||||
"usingComponents": {
|
||||
"t-dialog": "tdesign-miniprogram/dialog/dialog"
|
||||
}
|
||||
```
|
||||
|
||||
## 代码演示
|
||||
|
||||
### 反馈类对话框
|
||||
|
||||
<img src="https://tdesign.gtimg.com/miniprogram/readme/dialog-1.png" width="375px" height="50%">
|
||||
|
||||
{{ base }}
|
||||
|
||||
> 使用这种方式,对话框的 `visible` 是受控的,需要手动设置额 `visible` 为 `false` 才会关闭对话框。
|
||||
|
||||
### 确认类对话框
|
||||
{{ confirm }}
|
||||
|
||||
### 输入类对话框
|
||||
{{ inputDialog }}
|
||||
|
||||
### 命令调用
|
||||
{{ command }}
|
||||
|
||||
### 开发能力按钮
|
||||
|
||||
当传入的按钮类型为对象时,整个对象都将透传至 `t-button`,因此按钮可以直接使用开放能力
|
||||
|
||||
{{ button }}
|
||||
|
||||
## API
|
||||
### Dialog Props
|
||||
|
||||
名称 | 类型 | 默认值 | 说明 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
actions | Array / Slot | - | 操作栏。TS 类型:`Array<ButtonProps>`,[Button API Documents](./button?tab=api)。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/dialog/type.ts) | N
|
||||
button-layout | String | horizontal | 多按钮排列方式。可选项:horizontal/vertical | N
|
||||
cancel-btn | String / Object / Slot | '' | 取消按钮,可自定义。值为 null 则不显示取消按钮。值类型为字符串,则表示自定义按钮文本,值类型为 Object 则表示透传 Button 组件属性。使用 TNode 自定义按钮时,需自行控制取消事件。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/dialog/type.ts) | N
|
||||
close-on-overlay-click | Boolean | true | 点击蒙层时是否触发关闭事件 | N
|
||||
confirm-btn | String / Object / Slot | '' | 确认按钮。值为 null 则不显示确认按钮。值类型为字符串,则表示自定义按钮文本,值类型为 Object 则表示透传 Button 组件属性。使用 TNode 自定义按钮时,需自行控制确认事件 | N
|
||||
content | String / Slot | - | 内容 | N
|
||||
external-classes | Array | - | 组件类名,分别用于设置 组件外层元素、组件内容部分、确认按钮、取消按钮 等元素类名。`['t-class', 't-class-content', 't-class-confirm', 't-class-cancel']` | N
|
||||
overlay-props | Object | {} | 透传至 Overlay 组件 | N
|
||||
prevent-scroll-through | Boolean | true | 防止滚动穿透 | N
|
||||
show-overlay | Boolean | true | 是否显示遮罩层 | N
|
||||
title | String / Slot | - | 标题 | N
|
||||
visible | Boolean | false | 控制对话框是否显示 | N
|
||||
z-index | Number | 11500 | 组件层级,样式默认为 11500 | N
|
||||
|
||||
### Dialog Events
|
||||
|
||||
名称 | 参数 | 描述
|
||||
-- | -- | --
|
||||
cancel | - | 如果“取消”按钮存在,则点击“取消”按钮时触发,同时触发关闭事件
|
||||
close | `(trigger: DialogEventSource)` | 关闭事件,点击 取消按钮 或 点击蒙层 时触发。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/dialog/type.ts)。<br/>`type DialogEventSource = 'cancel' | 'overlay'`<br/>
|
||||
overlay-click | - | 如果蒙层存在,点击蒙层时触发
|
||||
confirm | - | 如果“确认”按钮存在,则点击“确认”按钮时触发
|
||||
action | `(index: number)` | 操作列表的点击时间,`index` 代表操作列表的顺序
|
||||
open-type-event | `(ButtonEventDetail)` | “确认”按钮具有开放能力的话,对应的成功回调
|
||||
open-type-error-event | `(ButtonError)` | “确认”按钮具有开放能力的话,对应的失败回调
|
||||
24
components/dialog/dialog.d.ts
vendored
Normal file
24
components/dialog/dialog.d.ts
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
import { SuperComponent } from '../common/src/index';
|
||||
export default class Dialog extends SuperComponent {
|
||||
// @ts-ignore
|
||||
options: {
|
||||
multipleSlots: boolean;
|
||||
addGlobalClass: boolean;
|
||||
};
|
||||
externalClasses: string[];
|
||||
properties: import("./type").TdDialogProps;
|
||||
data: {
|
||||
prefix: string;
|
||||
classPrefix: string;
|
||||
};
|
||||
methods: {
|
||||
onTplButtonTap(e: any): void;
|
||||
onConfirm(): void;
|
||||
onCancel(): void;
|
||||
close(): void;
|
||||
overlayClick(): void;
|
||||
onActionTap(e: any): void;
|
||||
openValueCBHandle(e: any): void;
|
||||
openValueErrCBHandle(e: any): void;
|
||||
};
|
||||
}
|
||||
90
components/dialog/dialog.js
Normal file
90
components/dialog/dialog.js
Normal file
@@ -0,0 +1,90 @@
|
||||
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';
|
||||
const { prefix } = config;
|
||||
const name = `${prefix}-dialog`;
|
||||
let Dialog = class Dialog extends SuperComponent {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.options = {
|
||||
multipleSlots: true,
|
||||
addGlobalClass: true,
|
||||
};
|
||||
this.externalClasses = [
|
||||
`${prefix}-class`,
|
||||
`${prefix}-class-content`,
|
||||
`${prefix}-class-confirm`,
|
||||
`${prefix}-class-cancel`,
|
||||
`${prefix}-class-action`,
|
||||
];
|
||||
this.properties = props;
|
||||
this.data = {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
};
|
||||
this.methods = {
|
||||
onTplButtonTap(e) {
|
||||
var _a;
|
||||
const evtType = e.type;
|
||||
const { type } = e.target.dataset;
|
||||
const button = this.data[`${type}Btn`];
|
||||
const cbName = `bind${evtType}`;
|
||||
if (typeof button[cbName] === 'function') {
|
||||
button[cbName](e);
|
||||
}
|
||||
if (evtType !== 'tap') {
|
||||
const success = ((_a = e.detail) === null || _a === void 0 ? void 0 : _a.errMsg.indexOf('ok')) > -1;
|
||||
this.triggerEvent(success ? 'open-type-event' : 'open-type-error-event', e.detail);
|
||||
}
|
||||
},
|
||||
onConfirm() {
|
||||
this.triggerEvent('confirm');
|
||||
if (this._onComfirm) {
|
||||
this._onComfirm();
|
||||
this.close();
|
||||
}
|
||||
},
|
||||
onCancel() {
|
||||
this.triggerEvent('close', { trigger: 'cancel' });
|
||||
this.triggerEvent('cancel');
|
||||
if (this._onCancel) {
|
||||
this._onCancel();
|
||||
this.close();
|
||||
}
|
||||
},
|
||||
close() {
|
||||
this.setData({ visible: false });
|
||||
},
|
||||
overlayClick() {
|
||||
if (this.properties.closeOnOverlayClick) {
|
||||
this.triggerEvent('close', { trigger: 'overlay' });
|
||||
}
|
||||
this.triggerEvent('overlayClick');
|
||||
},
|
||||
onActionTap(e) {
|
||||
const { index } = e.currentTarget.dataset;
|
||||
this.triggerEvent('action', { index });
|
||||
if (this._onAction) {
|
||||
this._onAction({ index });
|
||||
this.close();
|
||||
}
|
||||
},
|
||||
openValueCBHandle(e) {
|
||||
this.triggerEvent('open-type-event', e.detail);
|
||||
},
|
||||
openValueErrCBHandle(e) {
|
||||
this.triggerEvent('open-type-error-event', e.detail);
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
Dialog = __decorate([
|
||||
wxComponent()
|
||||
], Dialog);
|
||||
export default Dialog;
|
||||
7
components/dialog/dialog.json
Normal file
7
components/dialog/dialog.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"t-popup": "../popup/popup",
|
||||
"t-button": "../button/button"
|
||||
}
|
||||
}
|
||||
81
components/dialog/dialog.wxml
Normal file
81
components/dialog/dialog.wxml
Normal file
@@ -0,0 +1,81 @@
|
||||
<import src="../common/template/button.wxml" />
|
||||
<wxs src="./dialog.wxs" module="_" />
|
||||
|
||||
<t-popup
|
||||
name="dialog"
|
||||
class="{{classPrefix}}__wrapper"
|
||||
visible="{{visible}}"
|
||||
showOverlay="{{showOverlay}}"
|
||||
closeOnOverlayClick="{{closeOnOverlayClick}}"
|
||||
preventScrollThrough="{{preventScrollThrough}}"
|
||||
overlayProps="{{overlayProps}}"
|
||||
zIndex="{{zIndex}}"
|
||||
placement="center"
|
||||
bind:visible-change="overlayClick"
|
||||
>
|
||||
<view slot="content" class="{{classPrefix}} {{prefix}}-class">
|
||||
<view class="{{classPrefix}}__content {{prefix}}-class-content">
|
||||
<view wx:if="{{title}}" class="{{classPrefix}}__header">{{title}}</view>
|
||||
<slot name="title" />
|
||||
<view wx:if="{{content}}" class="{{classPrefix}}__body {{title ? '' : classPrefix + '__body--without-title'}}">
|
||||
<text class="{{classPrefix}}__body-text">{{content}}</text>
|
||||
</view>
|
||||
<slot name="content" />
|
||||
</view>
|
||||
<view
|
||||
class="{{classPrefix}}__footer {{classPrefix}}__footer--default {{buttonLayout === 'vertical' ? classPrefix + '__footer--column' : ''}}"
|
||||
>
|
||||
<t-button
|
||||
block
|
||||
class="{{classPrefix}}__footer-button-host"
|
||||
wx:if="{{actions}}"
|
||||
wx:for="{{actions}}"
|
||||
wx:key="action"
|
||||
data-index="{{index}}"
|
||||
t-class="{{classPrefix}}__button {{classPrefix}}__button-{{item.primary ? 'confirm' : 'cancel'}} {{prefix}}-class-action"
|
||||
bindtap="onActionTap"
|
||||
>
|
||||
{{item.name}}
|
||||
</t-button>
|
||||
<slot name="actions" />
|
||||
<t-button
|
||||
block
|
||||
class="{{classPrefix}}__footer-button-host {{classPrefix}}__footer-button--cancel"
|
||||
wx:if="{{cancelBtn && _.getTypeof(cancelBtn) == 'string'}}"
|
||||
t-class="{{classPrefix}}__button {{classPrefix}}__button-cancel {{confirmBtn ? classPrefix + '__button-half' : ''}} {{prefix}}-class-cancel"
|
||||
bindtap="onCancel"
|
||||
>
|
||||
{{cancelBtn}}
|
||||
</t-button>
|
||||
<block wx:elif="{{_.getTypeof(cancelBtn) == 'object'}}">
|
||||
<template
|
||||
is="button"
|
||||
data="{{...cancelBtn, block: true, type: 'cancel', externalClass: classPrefix + '__button ' + classPrefix + '__button-cancel ' + (cancelBtn ? classPrefix + '__button-half ' : ' ') + prefix + '-class-cancel',class: classPrefix + '__footer-button-host ' + classPrefix + '__footer-button--cancel' }}"
|
||||
></template>
|
||||
</block>
|
||||
<slot name="cancelBtn" />
|
||||
<t-button
|
||||
block
|
||||
class="{{classPrefix}}__footer-button-host {{classPrefix}}__footer-button--confirm"
|
||||
wx:if="{{confirmBtn && _.getTypeof(confirmBtn) == 'string'}}"
|
||||
t-class="{{classPrefix}}__button {{classPrefix}}__button-confirm {{cancelBtn ? classPrefix + '__button-half' : ''}} {{prefix}}-class-confirm"
|
||||
bind:tap="onConfirm"
|
||||
bind:getuserinfo="openValueCBHandle"
|
||||
bind:contact="openValueCBHandle"
|
||||
bind:getphonenumber="openValueCBHandle"
|
||||
bind:opensetting="openValueCBHandle"
|
||||
bind:launchapp="openValueCBHandle"
|
||||
bind:error="openValueErrCBHandle"
|
||||
>
|
||||
{{confirmBtn}}
|
||||
</t-button>
|
||||
<block wx:elif="{{_.getTypeof(confirmBtn) == 'object'}}">
|
||||
<template
|
||||
is="button"
|
||||
data="{{...confirmBtn, block: true, type: 'confirm', externalClass: classPrefix + '__button ' + classPrefix + '__button-confirm ' + (cancelBtn ? classPrefix + '__button-half ' : ' ') + prefix + '-class-confirm', class: classPrefix + '__footer-button-host ' + classPrefix + '__footer-button--confirm'}}"
|
||||
></template>
|
||||
</block>
|
||||
<slot name="confirmBtn" />
|
||||
</view>
|
||||
</view>
|
||||
</t-popup>
|
||||
3
components/dialog/dialog.wxs
Normal file
3
components/dialog/dialog.wxs
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports.getTypeof = function (obj) {
|
||||
return typeof obj;
|
||||
};
|
||||
152
components/dialog/dialog.wxss
Normal file
152
components/dialog/dialog.wxss
Normal file
@@ -0,0 +1,152 @@
|
||||
.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-dialog__wrapper .t-dialog {
|
||||
overflow: hidden;
|
||||
width: 644rpx;
|
||||
border-radius: 16rpx;
|
||||
background-color: #fff;
|
||||
}
|
||||
.t-dialog__wrapper .t-dialog__content {
|
||||
padding: 64rpx 48rpx;
|
||||
min-height: 176rpx;
|
||||
max-height: 776rpx;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
font-size: 32rpx;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.t-dialog__wrapper .t-dialog__header {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
font-size: 32rpx;
|
||||
line-height: 1.5;
|
||||
color: #000000;
|
||||
}
|
||||
.t-dialog__wrapper .t-dialog__body {
|
||||
overflow-y: scroll;
|
||||
text-align: center;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
font-size: 32rpx;
|
||||
color: #888888;
|
||||
margin-top: 32rpx;
|
||||
}
|
||||
.t-dialog__wrapper .t-dialog__body--without-title {
|
||||
margin-top: 0;
|
||||
}
|
||||
.t-dialog__wrapper .t-dialog__body-text {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.t-dialog__wrapper .t-dialog__body--left {
|
||||
text-align: left;
|
||||
}
|
||||
.t-dialog__wrapper .t-dialog__body--right {
|
||||
text-align: right;
|
||||
}
|
||||
.t-dialog__wrapper .t-dialog__footer {
|
||||
display: flex;
|
||||
}
|
||||
.t-dialog__wrapper .t-dialog__footer-button-host {
|
||||
width: 100%;
|
||||
}
|
||||
.t-dialog__wrapper .t-dialog__footer--column {
|
||||
flex-flow: column-reverse;
|
||||
}
|
||||
.t-dialog__wrapper .t-dialog__footer--column .t-dialog__button {
|
||||
width: 100%;
|
||||
}
|
||||
.t-dialog__wrapper .t-dialog__button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
font-size: 32rpx;
|
||||
padding: 0 48rpx;
|
||||
background-color: #fff;
|
||||
width: 644rpx;
|
||||
height: 112rpx;
|
||||
line-height: 112rpx;
|
||||
border-radius: 0;
|
||||
border: 0;
|
||||
}
|
||||
.t-dialog__wrapper .t-dialog__button:before {
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
box-sizing: border-box;
|
||||
top: 0;
|
||||
left: 0;
|
||||
border-top: 1px solid #e7e7e7;
|
||||
border-left: 1px solid #e7e7e7;
|
||||
transform: scale(0.5);
|
||||
transform-origin: 0 0;
|
||||
width: 200%;
|
||||
height: 200%;
|
||||
}
|
||||
.t-dialog__wrapper .t-dialog__button-half {
|
||||
width: 322rpx;
|
||||
}
|
||||
.t-dialog__wrapper .t-dialog__button-confirm {
|
||||
color: #0052d9;
|
||||
font-weight: bold;
|
||||
}
|
||||
.t-dialog__wrapper .t-dialog__button-cancel {
|
||||
color: #000000;
|
||||
font-weight: normal;
|
||||
}
|
||||
.t-dialog__wrapper .t-dialog__button-bounce-enter {
|
||||
transform: translate3d(-50%, -50%, 0) scale(0.7);
|
||||
opacity: 0;
|
||||
}
|
||||
.t-dialog__wrapper .t-dialog__button-bounce-leave-active {
|
||||
transform: translate3d(-50%, -50%, 0) scale(0.9);
|
||||
opacity: 0;
|
||||
}
|
||||
.t-dialog__wrapper .t-dialog__button::after {
|
||||
border-radius: 0;
|
||||
border-color: rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
.t-dialog__wrapper .t-dialog__text + .t-dialog__input {
|
||||
margin-top: 48rpx;
|
||||
}
|
||||
.t-dialog__wrapper .t-dialog__input {
|
||||
width: 100%;
|
||||
background-color: #f0f0f0;
|
||||
font-size: 32rpx;
|
||||
color: #000000;
|
||||
border-radius: 16rpx / 2;
|
||||
height: 96rpx;
|
||||
line-height: 1.5;
|
||||
padding: 24rpx;
|
||||
margin-top: 24rpx;
|
||||
box-sizing: border-box;
|
||||
text-align: left;
|
||||
}
|
||||
.t-dialog__wrapper .t-dialog__input-placeholder {
|
||||
color: #bbbbbb;
|
||||
}
|
||||
42
components/dialog/index.d.ts
vendored
Normal file
42
components/dialog/index.d.ts
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
/// <reference types="miniprogram-api-typings" />
|
||||
/// <reference types="miniprogram-api-typings" />
|
||||
declare type Context = WechatMiniprogram.Page.TrivialInstance | WechatMiniprogram.Component.TrivialInstance;
|
||||
interface DialogAlertOptionsType {
|
||||
context?: Context;
|
||||
selector?: string;
|
||||
title?: string;
|
||||
content: string;
|
||||
zIndex?: number;
|
||||
asyncClose?: boolean;
|
||||
confirmButtonText?: string;
|
||||
textAlign?: string;
|
||||
cancelBtn?: string | object;
|
||||
confirmBtn?: string | object;
|
||||
}
|
||||
interface DialogComfirmOptionsType extends DialogAlertOptionsType {
|
||||
cancelButtonText?: string;
|
||||
}
|
||||
interface Action {
|
||||
name: string;
|
||||
primary?: boolean;
|
||||
style?: string;
|
||||
}
|
||||
interface DialogActionOptionsType {
|
||||
context?: Context;
|
||||
selector?: string;
|
||||
title?: string;
|
||||
content: string;
|
||||
zIndex?: number;
|
||||
asyncClose?: boolean;
|
||||
actions?: Action[];
|
||||
buttonLayout?: 'vertical' | 'horizontal';
|
||||
}
|
||||
declare const _default: {
|
||||
alert(options: DialogAlertOptionsType): Promise<unknown>;
|
||||
confirm(options: DialogComfirmOptionsType): Promise<unknown>;
|
||||
close(options: DialogComfirmOptionsType): Promise<void>;
|
||||
action(options: DialogActionOptionsType): Promise<{
|
||||
index: number;
|
||||
}>;
|
||||
};
|
||||
export default _default;
|
||||
70
components/dialog/index.js
Normal file
70
components/dialog/index.js
Normal file
@@ -0,0 +1,70 @@
|
||||
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 props from './props';
|
||||
import { getInstance } from '../common/utils';
|
||||
const defaultOptions = {
|
||||
actions: false,
|
||||
buttonLayout: props.buttonLayout.value,
|
||||
cancelBtn: props.cancelBtn.value,
|
||||
closeOnOverlayClick: props.closeOnOverlayClick.value,
|
||||
confirmBtn: props.confirmBtn.value,
|
||||
content: '',
|
||||
preventScrollThrough: props.preventScrollThrough.value,
|
||||
showOverlay: props.showOverlay.value,
|
||||
title: '',
|
||||
visible: props.visible.value,
|
||||
};
|
||||
export default {
|
||||
alert(options) {
|
||||
const _a = Object.assign(Object.assign({}, defaultOptions), options), { context, selector = '#t-dialog' } = _a, otherOptions = __rest(_a, ["context", "selector"]);
|
||||
const instance = getInstance(context, selector);
|
||||
if (!instance)
|
||||
return Promise.reject();
|
||||
return new Promise((resolve) => {
|
||||
instance.setData(Object.assign(Object.assign({ cancelBtn: '' }, otherOptions), { visible: true }));
|
||||
instance._onComfirm = resolve;
|
||||
});
|
||||
},
|
||||
confirm(options) {
|
||||
const _a = Object.assign(Object.assign({}, defaultOptions), options), { context, selector = '#t-dialog' } = _a, otherOptions = __rest(_a, ["context", "selector"]);
|
||||
const instance = getInstance(context, selector);
|
||||
if (!instance)
|
||||
return Promise.reject();
|
||||
return new Promise((resolve, reject) => {
|
||||
instance.setData(Object.assign(Object.assign({}, otherOptions), { visible: true }));
|
||||
instance._onComfirm = resolve;
|
||||
instance._onCancel = reject;
|
||||
});
|
||||
},
|
||||
close(options) {
|
||||
const { context, selector = '#t-dialog' } = Object.assign({}, options);
|
||||
const instance = getInstance(context, selector);
|
||||
if (instance) {
|
||||
instance.close();
|
||||
return Promise.resolve();
|
||||
}
|
||||
return Promise.reject();
|
||||
},
|
||||
action(options) {
|
||||
const _a = Object.assign(Object.assign({}, defaultOptions), options), { context, selector = '#t-dialog', actions } = _a, otherOptions = __rest(_a, ["context", "selector", "actions"]);
|
||||
const instance = getInstance(context, selector);
|
||||
if (!instance)
|
||||
return Promise.reject();
|
||||
if (!actions || (typeof actions === 'object' && (actions.length === 0 || actions.length > 7))) {
|
||||
console.warn('action 数量建议控制在1至7个');
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
instance.setData(Object.assign(Object.assign({ actions, buttonLayout: 'vertical' }, otherOptions), { visible: true }));
|
||||
instance._onAction = resolve;
|
||||
});
|
||||
},
|
||||
};
|
||||
3
components/dialog/props.d.ts
vendored
Normal file
3
components/dialog/props.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import { TdDialogProps } from './type';
|
||||
declare const props: TdDialogProps;
|
||||
export default props;
|
||||
53
components/dialog/props.js
Normal file
53
components/dialog/props.js
Normal file
@@ -0,0 +1,53 @@
|
||||
const props = {
|
||||
actions: {
|
||||
type: Array,
|
||||
},
|
||||
buttonLayout: {
|
||||
type: String,
|
||||
value: 'horizontal',
|
||||
},
|
||||
cancelBtn: {
|
||||
type: String,
|
||||
optionalTypes: [Object],
|
||||
value: '',
|
||||
},
|
||||
closeOnOverlayClick: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
confirmBtn: {
|
||||
type: null,
|
||||
optionalTypes: [Object],
|
||||
value: '',
|
||||
},
|
||||
content: {
|
||||
type: String,
|
||||
},
|
||||
externalClasses: {
|
||||
type: Array,
|
||||
},
|
||||
overlayProps: {
|
||||
type: Object,
|
||||
value: {},
|
||||
},
|
||||
preventScrollThrough: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
showOverlay: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
},
|
||||
visible: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
zIndex: {
|
||||
type: Number,
|
||||
value: 11500,
|
||||
},
|
||||
};
|
||||
export default props;
|
||||
57
components/dialog/type.d.ts
vendored
Normal file
57
components/dialog/type.d.ts
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
import { ButtonProps } from '../button/index';
|
||||
export interface TdDialogProps {
|
||||
actions?: {
|
||||
type: ArrayConstructor;
|
||||
value?: Array<ButtonProps>;
|
||||
};
|
||||
buttonLayout?: {
|
||||
type: StringConstructor;
|
||||
value?: 'horizontal' | 'vertical';
|
||||
};
|
||||
cancelBtn?: {
|
||||
type: StringConstructor;
|
||||
optionalTypes: Array<ObjectConstructor>;
|
||||
value?: string | ButtonProps | null;
|
||||
};
|
||||
closeOnOverlayClick?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
confirmBtn?: {
|
||||
type: StringConstructor;
|
||||
optionalTypes: Array<ObjectConstructor>;
|
||||
value?: string | ButtonProps | null;
|
||||
};
|
||||
content?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
externalClasses?: {
|
||||
type: ArrayConstructor;
|
||||
value?: ['t-class', 't-class-content', 't-class-confirm', 't-class-cancel'];
|
||||
};
|
||||
overlayProps?: {
|
||||
type: ObjectConstructor;
|
||||
value?: object;
|
||||
};
|
||||
preventScrollThrough?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
showOverlay?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
title?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
visible?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
zIndex?: {
|
||||
type: NumberConstructor;
|
||||
value?: number;
|
||||
};
|
||||
}
|
||||
1
components/dialog/type.js
Normal file
1
components/dialog/type.js
Normal file
@@ -0,0 +1 @@
|
||||
export {};
|
||||
79
components/steps/README.md
Normal file
79
components/steps/README.md
Normal file
@@ -0,0 +1,79 @@
|
||||
---
|
||||
title: Steps 步骤条
|
||||
description: 用于任务步骤展示或任务进度展示。
|
||||
spline: navigation
|
||||
isComponent: true
|
||||
---
|
||||
|
||||
<span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20lines-98%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20functions-88%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20statements-96%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20branches-82%25-blue" /></span>
|
||||
## 引入
|
||||
|
||||
全局引入,在 miniprogram 根目录下的`app.json`中配置,局部引入,在需要引入的页面或组件的`index.json`中配置。
|
||||
|
||||
```json
|
||||
"usingComponents": {
|
||||
"t-steps": "tdesign-miniprogram/steps/steps",
|
||||
"t-step-item": "tdesign-miniprogram/steps/step-item",
|
||||
}
|
||||
```
|
||||
|
||||
## 代码演示
|
||||
|
||||
步骤条,方向可以横向和纵向,可以自定义步骤条显示内容以及是否可写
|
||||
|
||||
#### 横向可操作步骤条
|
||||
|
||||
{{ horizontal }}
|
||||
|
||||
#### 横向只读步骤条
|
||||
|
||||
{{ readonly }}
|
||||
|
||||
|
||||
#### 竖向只读步骤条
|
||||
|
||||
{{ vertical }}
|
||||
|
||||
#### 竖向简化只读步骤条
|
||||
|
||||
{{ theme }}
|
||||
|
||||
#### 竖向双层级只读步骤条
|
||||
|
||||
{{ double }}
|
||||
|
||||
#### 自定义内容步骤条
|
||||
|
||||
{{ customization }}
|
||||
|
||||
|
||||
|
||||
## API
|
||||
### Steps Props
|
||||
|
||||
名称 | 类型 | 默认值 | 说明 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
current | String / Number | 0 | 当前步骤,即整个步骤条进度,格式为`1`、`1-0`或`1-1`。默认根据步骤下标判断步骤的完成状态,当前步骤为进行中,当前步骤之前的步骤为已完成,当前步骤之后的步骤为未开始。若当前步骤条存在子步骤条,则会根据子步骤条重新判断当前步骤状态(子步骤条中存在error,则当前步骤error,子步骤条中存在process,当前步骤process,若最后一个子步骤条finish,当前步骤finish,优先级为`finish>error>process`)。注意:如果每个步骤条单独设置了status,则步骤条为设定的status,若传入`status:''`,将默认为未开始状态,传入的status优先级最高。 | N
|
||||
default-current | String / Number | undefined | 当前步骤,即整个步骤条进度。默认根据步骤下标判断步骤的完成状态,当前步骤为进行中,当前步骤之前的步骤为已完成,当前步骤之后的步骤为未开始。如果每个步骤没有设置 value,current 值为步骤长度则表示所有步骤已完成。如果每个步骤设置了自定义 value,则 current = 'FINISH' 表示所有状态完成。非受控属性 | N
|
||||
current-status | String | process | 用于控制 current 指向的步骤条的状态。可选项:default/process/finish/error | N
|
||||
external-classes | Array | - | 组件类名,用于设置组件外层元素元素类名。`['t-class']` | N
|
||||
layout | String | horizontal | 步骤条方向,有两种:横向和纵向。可选项:horizontal/vertical | N
|
||||
readonly | Boolean | false | 只读状态 | N
|
||||
theme | String | default | 步骤条风格。可选项:default/dot | N
|
||||
|
||||
### Steps Events
|
||||
|
||||
名称 | 参数 | 描述
|
||||
-- | -- | --
|
||||
change | `({current: string | number, previous: string | number})` | 当前步骤发生变化时触发
|
||||
|
||||
### StepItem Props
|
||||
|
||||
名称 | 类型 | 默认值 | 说明 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
content | String / Slot | '' | 步骤描述 | N
|
||||
external-classes | Array | - | 组件类名,用于设置组件外层元素元素类名。`['t-class', 't-class-inner', 't-class-content', 't-class-title', 't-class-description', 't-class-extra', 't-class-sub', 't-class-sub-dot', 't-class-sub-content']` | N
|
||||
icon | String / Slot | - | 图标。传入 slot 代表使用插槽,其他字符串代表使用内置图标 | N
|
||||
status | String | default | 当前步骤的状态。可选项:default/process/finish/error。TS 类型:`StepStatus` `type StepStatus = 'default' | 'process' | 'finish' | 'error'`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/steps/type.ts) | N
|
||||
sub-step-items | Array | [] | 子步骤条,仅支持 layout = 'vertical' 时。TS 类型:`SubStepItem[]` `interface SubStepItem { status: StepStatus, title: string }`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/steps/type.ts) | N
|
||||
title | String / Slot | '' | 标题 | N
|
||||
3
components/steps/props.d.ts
vendored
Normal file
3
components/steps/props.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import { TdStepsProps } from './type';
|
||||
declare const props: TdStepsProps;
|
||||
export default props;
|
||||
32
components/steps/props.js
Normal file
32
components/steps/props.js
Normal file
@@ -0,0 +1,32 @@
|
||||
const props = {
|
||||
current: {
|
||||
type: String,
|
||||
optionalTypes: [Number],
|
||||
value: null,
|
||||
},
|
||||
defaultCurrent: {
|
||||
type: String,
|
||||
optionalTypes: [Number],
|
||||
value: 0,
|
||||
},
|
||||
currentStatus: {
|
||||
type: String,
|
||||
value: 'process',
|
||||
},
|
||||
externalClasses: {
|
||||
type: Array,
|
||||
},
|
||||
layout: {
|
||||
type: String,
|
||||
value: 'horizontal',
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
theme: {
|
||||
type: String,
|
||||
value: 'default',
|
||||
},
|
||||
};
|
||||
export default props;
|
||||
3
components/steps/step-item-props.d.ts
vendored
Normal file
3
components/steps/step-item-props.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import { TdStepItemProps } from './type';
|
||||
declare const props: TdStepItemProps;
|
||||
export default props;
|
||||
25
components/steps/step-item-props.js
Normal file
25
components/steps/step-item-props.js
Normal file
@@ -0,0 +1,25 @@
|
||||
const props = {
|
||||
content: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
externalClasses: {
|
||||
type: Array,
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
},
|
||||
status: {
|
||||
type: String,
|
||||
value: 'default',
|
||||
},
|
||||
subStepItems: {
|
||||
type: Array,
|
||||
value: [],
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
};
|
||||
export default props;
|
||||
36
components/steps/step-item.d.ts
vendored
Normal file
36
components/steps/step-item.d.ts
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
import { SuperComponent, RelationsOptions } from '../common/src/index';
|
||||
export default class StepItem extends SuperComponent {
|
||||
options: {
|
||||
multipleSlots: boolean;
|
||||
};
|
||||
relations: RelationsOptions;
|
||||
externalClasses: string[];
|
||||
properties: import("./type").TdStepItemProps;
|
||||
parent: any;
|
||||
data: {
|
||||
classPrefix: string;
|
||||
prefix: string;
|
||||
rootClassName: string;
|
||||
index: number;
|
||||
isDot: boolean;
|
||||
curStatus: string;
|
||||
curSubStepItems: any[];
|
||||
curSubStepItemsStatus: any[];
|
||||
layout: string;
|
||||
type: string;
|
||||
isLastChild: boolean;
|
||||
isLarge: boolean;
|
||||
readonly: boolean;
|
||||
computedIcon: string;
|
||||
};
|
||||
observers: {
|
||||
icon(val: any): void;
|
||||
};
|
||||
lifetimes: {
|
||||
ready(): void;
|
||||
};
|
||||
methods: {
|
||||
updateStatus(current: any, currentStatus: any, index: any, theme: any, layout: any, steps: any, readonly: any): void;
|
||||
click(): void;
|
||||
};
|
||||
}
|
||||
150
components/steps/step-item.js
Normal file
150
components/steps/step-item.js
Normal file
@@ -0,0 +1,150 @@
|
||||
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 { wxComponent, SuperComponent } from '../common/src/index';
|
||||
import config from '../common/config';
|
||||
import props from './step-item-props';
|
||||
const { prefix } = config;
|
||||
let StepItem = class StepItem extends SuperComponent {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.options = {
|
||||
multipleSlots: true,
|
||||
};
|
||||
this.relations = {
|
||||
'./steps': {
|
||||
type: 'ancestor',
|
||||
},
|
||||
};
|
||||
this.externalClasses = [
|
||||
`${prefix}-class`,
|
||||
`${prefix}-class-inner`,
|
||||
`${prefix}-class-content`,
|
||||
`${prefix}-class-title`,
|
||||
`${prefix}-class-description`,
|
||||
`${prefix}-class-extra`,
|
||||
`${prefix}-class-sub`,
|
||||
`${prefix}-class-sub-dot`,
|
||||
`${prefix}-class-sub-content`,
|
||||
];
|
||||
this.properties = props;
|
||||
this.parent = null;
|
||||
this.data = {
|
||||
classPrefix: `${prefix}-steps-item`,
|
||||
prefix,
|
||||
rootClassName: '',
|
||||
index: 0,
|
||||
isDot: false,
|
||||
curStatus: '',
|
||||
curSubStepItems: [],
|
||||
curSubStepItemsStatus: [],
|
||||
layout: 'vertical',
|
||||
type: 'default',
|
||||
isLastChild: false,
|
||||
isLarge: false,
|
||||
readonly: false,
|
||||
computedIcon: '',
|
||||
};
|
||||
this.observers = {
|
||||
icon(val) {
|
||||
this.setData({
|
||||
computedIcon: val,
|
||||
});
|
||||
},
|
||||
};
|
||||
this.lifetimes = {
|
||||
ready() {
|
||||
const [parent] = this.getRelationNodes('./steps') || [];
|
||||
if (parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
},
|
||||
};
|
||||
this.methods = {
|
||||
updateStatus(current, currentStatus, index, theme, layout, steps, readonly) {
|
||||
const _current = String(current);
|
||||
const connectLine = '-';
|
||||
const judgeObjAttr = (data, attr) => {
|
||||
return Array.isArray(data[attr]) && data[attr].length;
|
||||
};
|
||||
const getStepLevel = (s) => {
|
||||
const reg = new RegExp(`(.*)${connectLine}{1}.*`);
|
||||
return s.replace(reg, '$1');
|
||||
};
|
||||
const isSameLevelStep = (stepsTag, current) => {
|
||||
return stepsTag.length < current.length && getStepLevel(stepsTag) === getStepLevel(current);
|
||||
};
|
||||
const stepFinalStatus = (item, itemTag, current, currentStatus) => {
|
||||
let tempStepStatus = '';
|
||||
if (item.status !== 'default' && item.status !== undefined) {
|
||||
tempStepStatus = item.status === '' ? 'default' : item.status;
|
||||
}
|
||||
else {
|
||||
tempStepStatus = 'default';
|
||||
if (itemTag < current) {
|
||||
tempStepStatus = 'finish';
|
||||
}
|
||||
else if (itemTag === current && item.status !== '') {
|
||||
tempStepStatus = currentStatus;
|
||||
}
|
||||
if (isSameLevelStep(itemTag, current)) {
|
||||
if (judgeObjAttr(item, 'subStepItems')) {
|
||||
const tempStepItemsStatus = item.subStepItems.map((subItem, subIndex) => {
|
||||
const subItemTag = `${itemTag}${connectLine}${subIndex}`;
|
||||
return stepFinalStatus(subItem, subItemTag, current, currentStatus);
|
||||
});
|
||||
if (tempStepItemsStatus[tempStepItemsStatus.length - 1] === 'finish') {
|
||||
tempStepStatus = 'finish';
|
||||
return tempStepStatus;
|
||||
}
|
||||
if (tempStepItemsStatus.includes('process') || tempStepItemsStatus.every((item) => item === 'default')) {
|
||||
tempStepStatus = 'process';
|
||||
}
|
||||
if (tempStepItemsStatus.includes('error')) {
|
||||
tempStepStatus = 'error';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return tempStepStatus;
|
||||
};
|
||||
this.data.tempStatus = stepFinalStatus(this.data, String(index), _current, currentStatus);
|
||||
const tempStatusList = [];
|
||||
if (judgeObjAttr(this.data, 'subStepItems')) {
|
||||
this.data.subStepItems.forEach((subItem, subIndex) => {
|
||||
tempStatusList.push(stepFinalStatus(subItem, `${index}${connectLine}${subIndex}`, _current, currentStatus));
|
||||
});
|
||||
}
|
||||
const tempIcon = new Map([
|
||||
['finish', 'check'],
|
||||
['error', 'close'],
|
||||
]);
|
||||
let iconStatus = '';
|
||||
if (readonly && tempIcon.has(this.data.tempStatus)) {
|
||||
iconStatus = tempIcon.get(this.data.tempStatus);
|
||||
}
|
||||
this.setData({
|
||||
curStatus: this.data.tempStatus,
|
||||
curSubStepItems: this.data.subStepItems || [],
|
||||
curSubStepItemsStatus: tempStatusList || [],
|
||||
computedIcon: this.data.icon || iconStatus,
|
||||
index,
|
||||
isDot: theme === 'dot' && layout === 'vertical',
|
||||
layout,
|
||||
theme,
|
||||
isLastChild: steps.length - 1 === index,
|
||||
});
|
||||
},
|
||||
click() {
|
||||
this.parent.handleClick(this.data.index);
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
StepItem = __decorate([
|
||||
wxComponent()
|
||||
], StepItem);
|
||||
export default StepItem;
|
||||
6
components/steps/step-item.json
Normal file
6
components/steps/step-item.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"t-icon": "../icon/icon"
|
||||
}
|
||||
}
|
||||
55
components/steps/step-item.wxml
Normal file
55
components/steps/step-item.wxml
Normal file
@@ -0,0 +1,55 @@
|
||||
<view
|
||||
class="{{prefix}}-step {{prefix}}-step--{{layout}} {{prefix}}-step--{{theme}}-anchor {{prefix}}-step--{{isLastChild ? 'last-child':'not-last-child'}} {{prefix}}-class {{readonly ? prefix + '-step--readonly' : ''}}"
|
||||
>
|
||||
<view class="{{classPrefix}} {{classPrefix}}--{{curStatus}}">
|
||||
<view class=" {{classPrefix}}__inner {{isLarge ? classPrefix + '__inner--large' : '' }} {{prefix}}-class-inner">
|
||||
<view class="{{classPrefix}}-wrapper">
|
||||
<!-- icon -->
|
||||
<view class="{{classPrefix}}__icon" bindtap="click">
|
||||
<view wx:if="{{isDot}}" class="{{classPrefix}}__icon-dot"></view>
|
||||
<view
|
||||
wx:elif="{{computedIcon}}"
|
||||
class="{{computedIcon === 'slot'? (classPrefix + '__icon-slot' ) : (classPrefix + '__icon-number')}} {{isLarge ? (classPrefix + '__icon-number--large') : ''}}"
|
||||
>
|
||||
<slot wx:if="{{computedIcon === 'slot'}}" name="icon" />
|
||||
<t-icon wx:else name="{{computedIcon}}" size="{{isLarge ? '24px' : '16px'}}" />
|
||||
</view>
|
||||
<view wx:else class="{{classPrefix}}__icon-number">{{index + 1}}</view>
|
||||
</view>
|
||||
<!-- content -->
|
||||
<view class="{{classPrefix}}__content {{prefix}}-class-content">
|
||||
<view class="{{classPrefix}}__title {{prefix}}-class-title">
|
||||
{{ title }}
|
||||
<slot name="title" />
|
||||
</view>
|
||||
<view class="{{classPrefix}}__description {{prefix}}-class-description">
|
||||
{{ content }}
|
||||
<slot name="content" />
|
||||
</view>
|
||||
<view class="{{classPrefix}}__extra {{prefix}}-class-extra">
|
||||
<slot name="extra" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 垂直 子步骤条 -->
|
||||
<view
|
||||
class="{{classPrefix}}__sub-wrapper"
|
||||
wx:if="{{ layout === 'vertical' && curSubStepItems.length && !isLastChild}}"
|
||||
>
|
||||
<!-- 子步骤条默认状态:default -->
|
||||
<view
|
||||
class="{{classPrefix}}-sub {{classPrefix}}-sub-status--default {{classPrefix}}-sub-status--{{curSubStepItemsStatus[index]}} {{prefix}}-class-sub"
|
||||
wx:for="{{curSubStepItems}}"
|
||||
wx:key="key"
|
||||
wx:item="item"
|
||||
>
|
||||
<view class="{{classPrefix}}-sub-dot">
|
||||
<view class="{{classPrefix}}-sub-dot-item {{prefix}}-class-sub-dot"></view>
|
||||
</view>
|
||||
<view class="{{classPrefix}}-sub__content {{prefix}}-class-sub-content"> {{ item.title }} </view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
309
components/steps/step-item.wxss
Normal file
309
components/steps/step-item.wxss
Normal file
@@ -0,0 +1,309 @@
|
||||
.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-steps-item {
|
||||
flex: 1;
|
||||
vertical-align: top;
|
||||
position: relative;
|
||||
}
|
||||
.t-steps-item__inner {
|
||||
position: relative;
|
||||
}
|
||||
.t-steps-item__icon {
|
||||
z-index: 1;
|
||||
vertical-align: top;
|
||||
font-size: 28rpx;
|
||||
position: relative;
|
||||
color: #ddd;
|
||||
}
|
||||
.t-steps-item__icon-number {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
text-align: center;
|
||||
border: 1px solid #c5c5c5;
|
||||
border-radius: 50%;
|
||||
background-color: #fff;
|
||||
color: #c5c5c5;
|
||||
}
|
||||
.t-steps-item__icon-slot {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
text-align: center;
|
||||
color: #c5c5c5;
|
||||
}
|
||||
.t-steps-item__content {
|
||||
text-align: center;
|
||||
}
|
||||
.t-steps-item__title {
|
||||
position: relative;
|
||||
color: rgba(0, 0, 0, 0.26);
|
||||
line-height: 22px;
|
||||
font-size: 28rpx;
|
||||
text-align: center;
|
||||
margin-bottom: 4px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.t-steps-item__description {
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
line-height: 20px;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.t-steps-item__extra:not(:empty) {
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
:host {
|
||||
flex: 1;
|
||||
vertical-align: top;
|
||||
position: relative;
|
||||
align-self: flex-start;
|
||||
width: inherit;
|
||||
}
|
||||
.t-step--horizontal .t-steps-item__content {
|
||||
max-width: 80px;
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
.t-step--horizontal .t-steps-item__inner .t-steps-item-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.t-step--horizontal .t-steps-item--finish .t-steps-item__icon-number {
|
||||
border-color: #0052d9;
|
||||
color: #0052d9;
|
||||
}
|
||||
.t-step--horizontal .t-steps-item--finish .t-steps-item__title {
|
||||
color: rgba(0, 0, 0, 0.9);
|
||||
}
|
||||
.t-step--horizontal .t-steps-item--process .t-steps-item__icon-number {
|
||||
background: #0052d9;
|
||||
color: #fff;
|
||||
border-color: #0052d9;
|
||||
}
|
||||
.t-step--horizontal .t-steps-item--process .t-steps-item__title {
|
||||
color: #0052d9;
|
||||
}
|
||||
.t-step--horizontal .t-steps-item--error .t-steps-item__icon-number {
|
||||
color: #e34d59;
|
||||
border-color: #e34d59;
|
||||
}
|
||||
.t-step--horizontal .t-steps-item--error .t-steps-item__title {
|
||||
color: #e34d59;
|
||||
}
|
||||
.t-step--horizontal .t-steps-item--default .t-steps-item__icon-number {
|
||||
border-color: #c5c5c5;
|
||||
color: #c5c5c5;
|
||||
}
|
||||
.t-step--horizontal .t-steps-item--default .t-steps-item__title,
|
||||
.t-step--horizontal .t-steps-item--default .t-steps-item__description {
|
||||
color: rgba(0, 0, 0, 0.26);
|
||||
}
|
||||
.t-step--horizontal.t-step--not-last-child .t-steps-item__inner:after {
|
||||
content: '';
|
||||
display: block;
|
||||
height: 1px;
|
||||
background: #0052d9;
|
||||
position: absolute;
|
||||
transform: translateY(-50%);
|
||||
width: 100%;
|
||||
top: 13px;
|
||||
left: 50%;
|
||||
}
|
||||
.t-step--horizontal.t-step--not-last-child .t-steps-item__inner.t-steps-item__inner--large:after {
|
||||
top: calc(40px / 2);
|
||||
}
|
||||
.t-step--horizontal.t-step--not-last-child.t-step--readonly .t-steps-item--process .t-steps-item__inner:after,
|
||||
.t-step--horizontal.t-step--not-last-child.t-step--readonly .t-steps-item--error .t-steps-item__inner:after,
|
||||
.t-step--horizontal.t-step--not-last-child.t-step--readonly .t-steps-item--default .t-steps-item__inner:after {
|
||||
background: #c5c5c5;
|
||||
}
|
||||
.t-step--vertical .t-steps-item {
|
||||
position: relative;
|
||||
}
|
||||
.t-step--vertical .t-steps-item-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.t-step--vertical .t-steps-item-wrapper:only-child {
|
||||
padding-bottom: 50rpx;
|
||||
}
|
||||
.t-step--vertical .t-steps-item-wrapper + .t-steps-item__sub-wrapper:not(:empty) {
|
||||
padding-top: 32rpx;
|
||||
padding-bottom: 48rpx;
|
||||
}
|
||||
.t-step--vertical .t-steps-item-sub {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 40rpx;
|
||||
align-items: center;
|
||||
padding-bottom: 8rpx;
|
||||
font-size: 24rpx;
|
||||
color: #0052d9;
|
||||
font-weight: 500;
|
||||
}
|
||||
.t-step--vertical .t-steps-item-sub-dot {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 24px;
|
||||
text-align: center;
|
||||
border: 1px solid transparent;
|
||||
color: #c5c5c5;
|
||||
z-index: 2;
|
||||
}
|
||||
.t-step--vertical .t-steps-item-sub-dot-item {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.t-step--vertical .t-steps-item-sub .t-steps-item-sub__content {
|
||||
margin-left: 16rpx;
|
||||
}
|
||||
.t-step--vertical .t-steps-item-sub-status--default {
|
||||
color: #c5c5c5;
|
||||
}
|
||||
.t-step--vertical .t-steps-item-sub-status--default .t-steps-item-sub-dot-item {
|
||||
background-color: #c5c5c5;
|
||||
}
|
||||
.t-step--vertical .t-steps-item-sub-status--finish {
|
||||
color: #000000;
|
||||
}
|
||||
.t-step--vertical .t-steps-item-sub-status--finish .t-steps-item-sub-dot-item {
|
||||
background-color: #0052d9;
|
||||
}
|
||||
.t-step--vertical .t-steps-item-sub-status--process {
|
||||
color: #0052d9;
|
||||
}
|
||||
.t-step--vertical .t-steps-item-sub-status--process .t-steps-item-sub-dot-item {
|
||||
background-color: #0052d9;
|
||||
}
|
||||
.t-step--vertical .t-steps-item-sub-status--error {
|
||||
color: #e34d59;
|
||||
}
|
||||
.t-step--vertical .t-steps-item-sub-status--error .t-steps-item-sub-dot-item {
|
||||
background-color: #e34d59;
|
||||
}
|
||||
.t-step--vertical .t-steps-item .t-steps-item-sub:last-child {
|
||||
padding-bottom: 0rpx;
|
||||
}
|
||||
.t-step--vertical .t-steps-item__content {
|
||||
margin-left: 16rpx;
|
||||
margin-right: 32rpx;
|
||||
flex: 1;
|
||||
}
|
||||
.t-step--vertical .t-steps-item__title {
|
||||
text-align: left;
|
||||
margin-top: 5px;
|
||||
line-height: 28rpx;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
.t-step--vertical .t-steps-item__description {
|
||||
text-align: left;
|
||||
}
|
||||
.t-step--vertical.t-step--default-anchor .t-steps-item--default .t-steps-item__icon-number {
|
||||
border-color: #c5c5c5;
|
||||
color: #c5c5c5;
|
||||
}
|
||||
.t-step--vertical.t-step--default-anchor .t-steps-item--finish .t-steps-item__icon-number {
|
||||
border-color: #0052d9;
|
||||
color: #0052d9;
|
||||
}
|
||||
.t-step--vertical.t-step--default-anchor .t-steps-item--finish .t-steps-item__title {
|
||||
color: rgba(0, 0, 0, 0.9);
|
||||
}
|
||||
.t-step--vertical.t-step--default-anchor .t-steps-item--process .t-steps-item__icon-number {
|
||||
background: #0052d9;
|
||||
color: #fff;
|
||||
border-color: #0052d9;
|
||||
}
|
||||
.t-step--vertical.t-step--default-anchor .t-steps-item--process .t-steps-item__title {
|
||||
color: #0052d9;
|
||||
}
|
||||
.t-step--vertical.t-step--default-anchor .t-steps-item--error .t-steps-item__icon-number {
|
||||
color: #e34d59;
|
||||
border-color: #e34d59;
|
||||
}
|
||||
.t-step--vertical.t-step--default-anchor .t-steps-item--error .t-steps-item__title {
|
||||
color: #e34d59;
|
||||
}
|
||||
.t-step--vertical.t-step--default-anchor.t-step--not-last-child .t-steps-item__inner::after {
|
||||
content: '';
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 1px;
|
||||
background: #c5c5c5;
|
||||
transform: translateX(-50%);
|
||||
position: absolute;
|
||||
left: 13px;
|
||||
top: 13px;
|
||||
}
|
||||
.t-step--vertical.t-step--default-anchor.t-step--not-last-child .t-steps-item--finish .t-steps-item__inner:after {
|
||||
background: #0052d9;
|
||||
}
|
||||
.t-step--vertical.t-step--default-anchor.t-step--not-last-child .t-steps-item--default .t-steps-item__inner:after {
|
||||
background: #c5c5c5;
|
||||
}
|
||||
.t-step--vertical.t-step--dot-anchor .t-steps-item__icon-dot {
|
||||
display: block;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
box-sizing: border-box;
|
||||
border: 2px solid #0052d9;
|
||||
border-radius: 50%;
|
||||
margin-top: 1px;
|
||||
}
|
||||
.t-step--vertical.t-step--dot-anchor .t-steps-item-sub-dot {
|
||||
width: 12px;
|
||||
box-sizing: border-box;
|
||||
border: 2px solid transparent;
|
||||
}
|
||||
.t-step--vertical.t-step--dot-anchor .t-steps-item__title {
|
||||
margin-top: 0;
|
||||
color: rgba(0, 0, 0, 0.9);
|
||||
}
|
||||
.t-step--vertical.t-step--dot-anchor.t-step--not-last-child .t-steps-item__inner::after {
|
||||
content: '';
|
||||
display: block;
|
||||
height: calc(100% - 12px);
|
||||
width: 1px;
|
||||
background: #ddd;
|
||||
transform: translateX(50%);
|
||||
position: absolute;
|
||||
left: 5px;
|
||||
top: 13px;
|
||||
}
|
||||
.t-steps-item__icon-number--large {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
21
components/steps/steps.d.ts
vendored
Normal file
21
components/steps/steps.d.ts
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
import { SuperComponent, RelationsOptions } from '../common/src/index';
|
||||
export default class Steps extends SuperComponent {
|
||||
relations: RelationsOptions;
|
||||
externalClasses: string[];
|
||||
properties: import("./type").TdStepsProps;
|
||||
controlledProps: {
|
||||
key: string;
|
||||
event: string;
|
||||
}[];
|
||||
data: {
|
||||
prefix: string;
|
||||
classPrefix: string;
|
||||
};
|
||||
observers: {
|
||||
current(): void;
|
||||
};
|
||||
methods: {
|
||||
updateChildren(): void;
|
||||
handleClick(index: any): void;
|
||||
};
|
||||
}
|
||||
78
components/steps/steps.js
Normal file
78
components/steps/steps.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 { wxComponent, SuperComponent } from '../common/src/index';
|
||||
import config from '../common/config';
|
||||
import props from './props';
|
||||
const { prefix } = config;
|
||||
const name = `${prefix}-steps`;
|
||||
let Steps = class Steps extends SuperComponent {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.relations = {
|
||||
'./step-item': {
|
||||
type: 'descendant',
|
||||
linked(child) {
|
||||
this.updateChildren();
|
||||
const { readonly, layout } = this.data;
|
||||
let isLarge = false;
|
||||
if (!readonly && layout === 'horizontal' && child.data.icon !== 'slot') {
|
||||
isLarge = !!child.data.icon;
|
||||
}
|
||||
child.setData({
|
||||
readonly,
|
||||
isLarge,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
this.externalClasses = [`${prefix}-class`];
|
||||
this.properties = props;
|
||||
this.controlledProps = [
|
||||
{
|
||||
key: 'current',
|
||||
event: 'change',
|
||||
},
|
||||
];
|
||||
this.data = {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
};
|
||||
this.observers = {
|
||||
current() {
|
||||
this.updateChildren();
|
||||
},
|
||||
};
|
||||
this.methods = {
|
||||
updateChildren() {
|
||||
const items = this.getRelationNodes('./step-item');
|
||||
const len = items.length;
|
||||
const { current, currentStatus, readonly } = this.data;
|
||||
if (len) {
|
||||
items.forEach((item, index) => {
|
||||
item.updateStatus(current, currentStatus, index, this.data.theme, this.data.layout, items, readonly);
|
||||
});
|
||||
}
|
||||
},
|
||||
handleClick(index) {
|
||||
if (this.data.layout === 'vertical') {
|
||||
return;
|
||||
}
|
||||
if (!this.data.readonly) {
|
||||
const preIndex = this.data.current;
|
||||
this._trigger('change', {
|
||||
previous: preIndex,
|
||||
current: index,
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
Steps = __decorate([
|
||||
wxComponent()
|
||||
], Steps);
|
||||
export default Steps;
|
||||
6
components/steps/steps.json
Normal file
6
components/steps/steps.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"t-step": "./step-item"
|
||||
}
|
||||
}
|
||||
5
components/steps/steps.wxml
Normal file
5
components/steps/steps.wxml
Normal file
@@ -0,0 +1,5 @@
|
||||
<view
|
||||
class="{{classPrefix}} {{classPrefix}}--{{layout}} {{classPrefix}}--{{type}}-anchor {{readonly ? classPrefix + '--readonly' : ''}} {{prefix}}-class"
|
||||
>
|
||||
<slot />
|
||||
</view>
|
||||
40
components/steps/steps.wxss
Normal file
40
components/steps/steps.wxss
Normal file
@@ -0,0 +1,40 @@
|
||||
.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);
|
||||
}
|
||||
:host {
|
||||
display: flex;
|
||||
}
|
||||
.t-step--vertical {
|
||||
padding-right: 32rpx;
|
||||
}
|
||||
.t-steps {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
.t-steps--vertical {
|
||||
flex-direction: column;
|
||||
}
|
||||
63
components/steps/type.d.ts
vendored
Normal file
63
components/steps/type.d.ts
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
export interface TdStepsProps {
|
||||
current?: {
|
||||
type: StringConstructor;
|
||||
optionalTypes: Array<NumberConstructor>;
|
||||
value?: string | number;
|
||||
};
|
||||
defaultCurrent?: {
|
||||
type: StringConstructor;
|
||||
optionalTypes: Array<NumberConstructor>;
|
||||
value?: string | number;
|
||||
};
|
||||
currentStatus?: {
|
||||
type: StringConstructor;
|
||||
value?: 'default' | 'process' | 'finish' | 'error';
|
||||
};
|
||||
externalClasses?: {
|
||||
type: ArrayConstructor;
|
||||
value?: ['t-class'];
|
||||
};
|
||||
layout?: {
|
||||
type: StringConstructor;
|
||||
value?: 'horizontal' | 'vertical';
|
||||
};
|
||||
readonly?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
theme?: {
|
||||
type: StringConstructor;
|
||||
value?: 'default' | 'dot';
|
||||
};
|
||||
}
|
||||
export interface TdStepItemProps {
|
||||
content?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
externalClasses?: {
|
||||
type: ArrayConstructor;
|
||||
value?: ['t-class', 't-class-content', 't-class-title', 't-class-description', 't-class-extra'];
|
||||
};
|
||||
icon?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
status?: {
|
||||
type: StringConstructor;
|
||||
value?: StepStatus;
|
||||
};
|
||||
subStepItems?: {
|
||||
type: ArrayConstructor;
|
||||
value?: SubStepItem[];
|
||||
};
|
||||
title?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
}
|
||||
export declare type StepStatus = 'default' | 'process' | 'finish' | 'error';
|
||||
export interface SubStepItem {
|
||||
status: StepStatus;
|
||||
title: string;
|
||||
}
|
||||
1
components/steps/type.js
Normal file
1
components/steps/type.js
Normal file
@@ -0,0 +1 @@
|
||||
export {};
|
||||
@@ -1,6 +1,6 @@
|
||||
<!--pages/message/index.wxml-->
|
||||
<t-message id="t-message" />
|
||||
<t-empty t-class="empty-cls" icon="{{isClick ? 'check-circle' : 'error-circle'}}" description="开通会员解锁完整功能">
|
||||
<t-empty t-class="empty-cls" icon="{{isClick ? 'check-circle' : 'error-circle'}}" description="{{isClick ? '请关注公众号,回复【VIP】!' : '开通会员享受完整功能'}}">
|
||||
<t-button wx:if="{{!isClick}}" slot="action" theme="danger" variant="plain" bind:tap="startVipButton">开通会员</t-button>
|
||||
</t-empty>
|
||||
<t-toast id="t-toast" />
|
||||
|
||||
@@ -1,10 +1,47 @@
|
||||
Page({
|
||||
data: {
|
||||
activeValues: [],
|
||||
customStepCurrent: 4,
|
||||
customStepItems: [
|
||||
{
|
||||
title: '二级步骤描述',
|
||||
content: '可自定义此处内容',
|
||||
extra: '可自定义此处内容',
|
||||
},
|
||||
handleChange(e) {
|
||||
{
|
||||
content: '可自定义此处内容',
|
||||
extra: '可自定义此处内容',
|
||||
},
|
||||
{
|
||||
content: '可自定义此处内容',
|
||||
extra: '可自定义此处内容',
|
||||
},
|
||||
{
|
||||
title: '二级步骤描述',
|
||||
extra: '可自定义此处内容',
|
||||
content: '可自定义此处内容',
|
||||
},
|
||||
{
|
||||
title: '二级步骤描述',
|
||||
extra: '可自定义此处内容',
|
||||
content: '可自定义此处内容',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
onShow() {
|
||||
const { customStepCurrent, customStepItems } = this.data;
|
||||
const newCustomStepItems = customStepItems.map((element, elementIndex) => {
|
||||
if (elementIndex < customStepCurrent) {
|
||||
element.status = 'finish';
|
||||
} else if (elementIndex === customStepCurrent) {
|
||||
element.status = 'active';
|
||||
} else {
|
||||
element.status = 'default';
|
||||
}
|
||||
return element;
|
||||
});
|
||||
this.setData({
|
||||
activeValues: e.detail.value,
|
||||
customStepItems: newCustomStepItems,
|
||||
});
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"t-collapse": "/components/collapse/collapse",
|
||||
"t-collapse-panel": "/components/collapse/collapse-panel"
|
||||
"t-steps": "/components/steps/steps",
|
||||
"t-step-item": "/components/steps/step-item"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,20 @@
|
||||
<wxs module="_"> module.exports.contains = function(arr, target) { return arr.indexOf(target) > -1; } </wxs>
|
||||
<t-collapse value="{{activeValues}}" bind:change="handleChange">
|
||||
<t-collapse-panel
|
||||
header="关于我们"
|
||||
header-right-content="{{_.contains(activeValues, 0) ? '收起' : '展开'}}"
|
||||
value="{{0}}"
|
||||
expandIcon
|
||||
<t-steps class="demo-steps" current="{{customStepCurrent}}" readonly="true" layout="vertical">
|
||||
<t-step-item
|
||||
wx:for="{{customStepItems}}"
|
||||
wx:key="key"
|
||||
wx:item="item"
|
||||
icon="slot"
|
||||
title="{{item.title}}"
|
||||
content="{{item.content}}"
|
||||
t-class-inner="t-class-inner t-class-inner--{{item.status}}"
|
||||
t-class-title="t-class-title {{item.title? '' : 't-class-title--no'}}"
|
||||
t-class-description="t-class-description"
|
||||
t-class-extra="t-class-extra"
|
||||
>
|
||||
我们很强真肉蛋
|
||||
</t-collapse-panel>
|
||||
</t-collapse>
|
||||
<view
|
||||
slot="icon"
|
||||
class="t-icon-slot t-icon-slot--{{item.status}} {{item.title? '' : 't-icon-slot--child'}}"
|
||||
></view>
|
||||
<view slot="extra">{{item.extra}}</view>
|
||||
</t-step-item>
|
||||
</t-steps>
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
.demo-steps {
|
||||
padding-top: 80rpx;
|
||||
padding-left: 32rpx;
|
||||
}
|
||||
|
||||
.t-icon-slot {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-radius: 50%;
|
||||
background-color: #c5c5c5;
|
||||
}
|
||||
|
||||
.t-icon-slot--child {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
.t-icon-slot--finish {
|
||||
background-color: #0052d9;
|
||||
}
|
||||
|
||||
.t-icon-slot--active {
|
||||
background-color: rgb(5, 150, 34);
|
||||
}
|
||||
|
||||
.t-icon-slot--default {
|
||||
background-color: #c5c5c5;
|
||||
}
|
||||
/** 自定义line颜色:
|
||||
* 方法1: 通过t-class-inner外部样式的 ::after
|
||||
* 方法2: 覆盖组件内部样式。
|
||||
*/
|
||||
.t-class-inner--finish::after {
|
||||
background-color: #0052d9;
|
||||
}
|
||||
|
||||
.t-class-inner--active::after {
|
||||
background-color: #c5c5c5;
|
||||
}
|
||||
|
||||
.t-class-inner--default::after {
|
||||
background-color: #c5c5c5;
|
||||
}
|
||||
|
||||
.t-class-title {
|
||||
color: #000 !important;
|
||||
}
|
||||
.t-class-title--no {
|
||||
margin: 0 !important;
|
||||
}
|
||||
.t-class-description {
|
||||
color: rgb(38, 37, 37) !important;
|
||||
}
|
||||
|
||||
.t-class-extra {
|
||||
color: #c5c5c5;
|
||||
text-align: left;
|
||||
font-size: 20rpx !important;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
|
||||
@@ -3,9 +3,31 @@ Page({
|
||||
messageList : [
|
||||
{"taskId":"2022","isRead":true,"title":"今天是任务的需要的","content":"任务【测试...】已延期","date":"2022-12-14"},
|
||||
{"taskId":"2022","isRead":false,"title":"任务延期","content":"点哦电脑玩i回家欧帝啊我你的破请问你的我i拿到钱哦i我你懂屁请问你oi","date":"2022-12-14"},
|
||||
{"taskId":"2022","isRead":true,"title":"任务【测试3213...】已延期","content":"点哦电脑玩i回家欧帝啊我你的破请问你的我i拿到钱哦i我你懂屁请问你oi","date":"2022-12-14"},
|
||||
{"taskId":"2022","isRead":true,"title":"任务【测试3213...】已延期","content":"","date":"2022-12-14"},
|
||||
{"taskId":"2022","isRead":false,"title":"任务【测试412312...】已延期","content":"任务【测试...】已延期","date":"2022-12-14"}
|
||||
],
|
||||
dialogKey: '',
|
||||
clearConfirm : false,
|
||||
checkConfirm : false
|
||||
},
|
||||
showDialog(e) {
|
||||
const { key } = e.currentTarget.dataset;
|
||||
this.setData({ [key]: true, dialogKey: key });
|
||||
},
|
||||
|
||||
closeDialog() {
|
||||
const { dialogKey } = this.data;
|
||||
this.setData({ [dialogKey]: false });
|
||||
},
|
||||
|
||||
clearMessage() {
|
||||
console.log("清除消息成功!")
|
||||
this.closeDialog();
|
||||
},
|
||||
|
||||
allRead() {
|
||||
console.log("全部已读成功!")
|
||||
this.closeDialog();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"t-badge": "/components/badge/badge"
|
||||
"t-badge": "/components/badge/badge",
|
||||
"t-dialog": "/components/dialog/dialog"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
<view class="msgTitle">
|
||||
<view class="clear"></view>
|
||||
<view class="clear"><t-icon name="app"></t-icon></view>
|
||||
<view class="read"><t-icon name="app"/></view>
|
||||
<view class="clear"><t-icon name="clear" data-key="clearConfirm" bind:tap="showDialog" /></view>
|
||||
<view class="read"><t-icon name="check" data-key="checkConfirm" bind:tap="showDialog"/></view>
|
||||
</view>
|
||||
<view wx:for="{{messageList}}">
|
||||
<view class="msgContent" wx:for="{{messageList}}">
|
||||
<t-cell title="{{item.title}}" description="{{item.content}}" wx:key="index">
|
||||
<view slot="description">
|
||||
{{item.date}}
|
||||
@@ -13,3 +12,21 @@
|
||||
</view>
|
||||
</t-cell>
|
||||
</view>
|
||||
<t-dialog
|
||||
visible="{{clearConfirm}}"
|
||||
title="确认清除所有消息?"
|
||||
t-class-confirm="custom-confirm-btn"
|
||||
confirm-btn="清除"
|
||||
cancel-btn="取消"
|
||||
bind:confirm="clearMessage"
|
||||
bind:cancel="closeDialog"
|
||||
/>
|
||||
<t-dialog
|
||||
visible="{{checkConfirm}}"
|
||||
title="全部标记已读"
|
||||
t-class-confirm="custom-confirm-btn"
|
||||
confirm-btn="确定"
|
||||
cancel-btn="取消"
|
||||
bind:confirm="allRead"
|
||||
bind:cancel="closeDialog"
|
||||
/>
|
||||
|
||||
@@ -3,6 +3,13 @@
|
||||
justify-content: space-between;
|
||||
padding: 20rpx 50rpx;
|
||||
}
|
||||
.msgContent {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.sendDate {
|
||||
padding-left: 20rpx;
|
||||
}
|
||||
.custom-confirm-btn {
|
||||
color: #ff4646 !important;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user