1.22
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,28 @@
|
||||
import { SuperComponent, RelationsOptions } from '../common/src/index';
|
||||
export default class AvatarGroup extends SuperComponent {
|
||||
externalClasses: string[];
|
||||
properties: import("./type").TdAvatarGroupProps;
|
||||
data: {
|
||||
prefix: string;
|
||||
classPrefix: string;
|
||||
hasChild: boolean;
|
||||
length: number;
|
||||
className: string;
|
||||
};
|
||||
options: {
|
||||
multipleSlots: boolean;
|
||||
};
|
||||
relations: RelationsOptions;
|
||||
lifetimes: {
|
||||
attached(): void;
|
||||
ready(): void;
|
||||
};
|
||||
observers: {
|
||||
'cascading, size'(): void;
|
||||
};
|
||||
methods: {
|
||||
setClass(): void;
|
||||
handleMax(): void;
|
||||
handleChildCascading(): void;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
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 avatarGroupProps from './props';
|
||||
const { prefix } = config;
|
||||
const name = `${prefix}-avatar-group`;
|
||||
let AvatarGroup = class AvatarGroup extends SuperComponent {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.externalClasses = [`${prefix}-class`, `${prefix}-class-content`, `${prefix}-class-image`];
|
||||
this.properties = avatarGroupProps;
|
||||
this.data = {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
hasChild: true,
|
||||
length: 0,
|
||||
className: '',
|
||||
};
|
||||
this.options = {
|
||||
multipleSlots: true,
|
||||
};
|
||||
this.relations = {
|
||||
'../avatar/avatar': {
|
||||
type: 'descendant',
|
||||
},
|
||||
};
|
||||
this.lifetimes = {
|
||||
attached() {
|
||||
this.setClass();
|
||||
},
|
||||
ready() {
|
||||
this.setData({
|
||||
length: this.$children.length,
|
||||
});
|
||||
this.handleMax();
|
||||
this.handleChildCascading();
|
||||
},
|
||||
};
|
||||
this.observers = {
|
||||
'cascading, size'() {
|
||||
this.setClass();
|
||||
},
|
||||
};
|
||||
this.methods = {
|
||||
setClass() {
|
||||
const { cascading, size } = this.properties;
|
||||
const direction = cascading.split('-')[0];
|
||||
const classList = [
|
||||
name,
|
||||
`${prefix}-class`,
|
||||
`${name}-offset-${direction}-${size.indexOf('px') > -1 ? 'medium' : size}`,
|
||||
];
|
||||
this.setData({
|
||||
className: classList.join(' '),
|
||||
});
|
||||
},
|
||||
handleMax() {
|
||||
const { max } = this.data;
|
||||
const len = this.$children.length;
|
||||
if (!max || max > len)
|
||||
return;
|
||||
const restAvatars = this.$children.splice(max, len - max);
|
||||
restAvatars.forEach((child) => {
|
||||
child.hide();
|
||||
});
|
||||
},
|
||||
handleChildCascading() {
|
||||
if (this.properties.cascading === 'right-up')
|
||||
return;
|
||||
const defaultZIndex = 100;
|
||||
this.$children.forEach((child, index) => {
|
||||
child.updateCascading(defaultZIndex - index * 10);
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
AvatarGroup = __decorate([
|
||||
wxComponent()
|
||||
], AvatarGroup);
|
||||
export default AvatarGroup;
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"t-avatar": "../avatar/avatar"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<view style="{{ customStyle }}" class="{{className}}">
|
||||
<slot />
|
||||
<!-- 自定义折叠元素 -->
|
||||
<view class="{{classPrefix}}__collapse--slot">
|
||||
<slot name="collapse-avatar" />
|
||||
</view>
|
||||
<!-- 默认折叠元素 -->
|
||||
<view class="{{classPrefix}}__collapse--default" wx:if="{{max && (max < length)}}">
|
||||
<t-avatar
|
||||
t-class-image="{{prefix}}-class-image"
|
||||
t-class-content="{{prefix}}-class-content"
|
||||
bordered
|
||||
size="{{size}}"
|
||||
icon="{{ collapseAvatar ? '' : 'user-add'}}"
|
||||
aria-role="none"
|
||||
>{{collapseAvatar}}</t-avatar
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
@@ -0,0 +1,60 @@
|
||||
.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-avatar-group {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
.t-avatar-group-offset-left-small t-avatar:not(:first-child) {
|
||||
margin-left: var(--td-avatar-group-margin-left-small, -4px);
|
||||
}
|
||||
.t-avatar-group-offset-left-medium t-avatar:not(:first-child) {
|
||||
margin-left: var(--td-avatar-group-margin-left-medium, -6px);
|
||||
}
|
||||
.t-avatar-group-offset-left-large t-avatar:not(:first-child) {
|
||||
margin-left: var(--td-avatar-group-margin-left-large, -8px);
|
||||
}
|
||||
.t-avatar-group-offset-right-small t-avatar:not(:last-child) {
|
||||
margin-right: var(--td-avatar-group-margin-left-small, -4px);
|
||||
}
|
||||
.t-avatar-group-offset-right-medium t-avatar:not(:last-child) {
|
||||
margin-right: var(--td-avatar-group-margin-left-medium, -6px);
|
||||
}
|
||||
.t-avatar-group-offset-right-large t-avatar:not(:last-child) {
|
||||
margin-right: var(--td-avatar-group-margin-left-large, -8px);
|
||||
}
|
||||
.t-avatar-group__collapse--slot {
|
||||
float: left;
|
||||
}
|
||||
.t-avatar-group__collapse--slot:not(:empty) + .t-avatar-group__collapse--default {
|
||||
display: none;
|
||||
float: left;
|
||||
}
|
||||
.t-avatar-group__collapse--slot:empty + .t-avatar-group__collapse--default {
|
||||
display: block;
|
||||
float: left;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import { TdAvatarGroupProps } from './type';
|
||||
declare const props: TdAvatarGroupProps;
|
||||
export default props;
|
||||
@@ -0,0 +1,24 @@
|
||||
const props = {
|
||||
cascading: {
|
||||
type: String,
|
||||
value: 'right-up',
|
||||
},
|
||||
collapseAvatar: {
|
||||
type: String,
|
||||
},
|
||||
customStyle: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
externalClasses: {
|
||||
type: Array,
|
||||
},
|
||||
max: {
|
||||
type: Number,
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
value: 'medium',
|
||||
},
|
||||
};
|
||||
export default props;
|
||||
@@ -0,0 +1,27 @@
|
||||
export interface TdAvatarGroupProps {
|
||||
cascading?: {
|
||||
type: StringConstructor;
|
||||
value?: CascadingValue;
|
||||
};
|
||||
collapseAvatar?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
customStyle?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
externalClasses?: {
|
||||
type: ArrayConstructor;
|
||||
value?: ['t-class', 't-class-image', 't-class-content'];
|
||||
};
|
||||
max?: {
|
||||
type: NumberConstructor;
|
||||
value?: number;
|
||||
};
|
||||
size?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
}
|
||||
export declare type CascadingValue = 'left-up' | 'right-up';
|
||||
@@ -0,0 +1 @@
|
||||
export {};
|
||||
@@ -0,0 +1,35 @@
|
||||
:: BASE_DOC ::
|
||||
|
||||
## API
|
||||
### Avatar Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
alt | String | - | show it when url is not valid | N
|
||||
badge-props | Object | - | Typescript:`BadgeProps`,[Badge API Documents](./badge?tab=api)。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/avatar/type.ts) | N
|
||||
bordered | Boolean | false | \- | N
|
||||
custom-style | String | - | `0.25.0` | N
|
||||
external-classes | Array | - | `['t-class', 't-class-image', 't-class-icon', 't-class-alt', 't-class-content']` | N
|
||||
hide-on-load-failed | Boolean | false | hide image when loading image failed | N
|
||||
icon | String / Object | - | \- | N
|
||||
image | String | - | images url | N
|
||||
image-props | Object | - | \- | N
|
||||
shape | String | circle | shape。options:circle/round。Typescript:`ShapeEnum ` `type ShapeEnum = 'circle' \| 'round'`。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/avatar/type.ts) | N
|
||||
size | String | medium | size | N
|
||||
|
||||
### Avatar Events
|
||||
|
||||
name | params | description
|
||||
-- | -- | --
|
||||
error | \- | trigger on image load failed
|
||||
|
||||
### AvatarGroup Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
cascading | String | 'right-up' | multiple images cascading。options:left-up/right-up。Typescript:`CascadingValue` `type CascadingValue = 'left-up' \| 'right-up'`。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/avatar-group/type.ts) | N
|
||||
collapse-avatar | String / Slot | - | \- | N
|
||||
custom-style | String | - | `0.25.0` | N
|
||||
external-classes | Array | - | `['t-class', 't-class-image', 't-class-content']` | N
|
||||
max | Number | - | \- | N
|
||||
size | String | medium | size | N
|
||||
@@ -0,0 +1,89 @@
|
||||
---
|
||||
title: Avatar 头像
|
||||
description: 用于展示用户头像信息,除了纯展示也可点击进入个人详情等操作。
|
||||
spline: data
|
||||
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-99%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20branches-85%25-blue" /></span>
|
||||
## 引入
|
||||
|
||||
全局引入,在 miniprogram 根目录下的`app.json`中配置,局部引入,在需要引入的页面或组件的`index.json`中配置。
|
||||
|
||||
```json
|
||||
"usingComponents": {
|
||||
"t-avatar": "tdesign-miniprogram/avatar/avatar",
|
||||
"t-avatar-group": "tdesign-miniprogram/avatar-group/avatar-group"
|
||||
}
|
||||
```
|
||||
|
||||
## 代码演示
|
||||
|
||||
### 头像类型
|
||||
|
||||
图片头像
|
||||
|
||||
{{ image-avatar }}
|
||||
|
||||
字符头像
|
||||
|
||||
{{ character-avatar }}
|
||||
|
||||
图标头像
|
||||
|
||||
{{ icon-avatar }}
|
||||
|
||||
徽标头像
|
||||
|
||||
{{ badge-avatar }}
|
||||
|
||||
|
||||
### 组合头像
|
||||
|
||||
纯展示
|
||||
|
||||
{{ exhibition }}
|
||||
|
||||
带操作
|
||||
|
||||
{{ action }}
|
||||
|
||||
### 头像尺寸
|
||||
|
||||
头像 large/medium/small 尺寸
|
||||
|
||||
{{ size }}
|
||||
|
||||
## API
|
||||
### Avatar Props
|
||||
|
||||
名称 | 类型 | 默认值 | 说明 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
alt | String | - | 头像替换文本,仅当图片加载失败时有效 | N
|
||||
badge-props | Object | - | 头像右上角提示信息,继承 Badge 组件的全部特性。如:小红点,或者数字。TS 类型:`BadgeProps`,[Badge API Documents](./badge?tab=api)。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/avatar/type.ts) | N
|
||||
bordered | Boolean | false | 是否显示外边框 | N
|
||||
custom-style | String | - | `0.25.0`。自定义组件样式 | N
|
||||
external-classes | Array | - | 组件类名,用于设置组件外层元素类名。`['t-class', 't-class-image', 't-class-icon', 't-class-alt', 't-class-content']` | N
|
||||
hide-on-load-failed | Boolean | false | 加载失败时隐藏图片 | N
|
||||
icon | String / Object | - | 图标。值为字符串表示图标名称,值为 `Object` 类型,表示透传至 `icon`。 | N
|
||||
image | String | - | 图片地址 | N
|
||||
image-props | Object | - | 透传至 Image 组件 | N
|
||||
shape | String | circle | 形状。可选项:circle/round。TS 类型:`ShapeEnum ` `type ShapeEnum = 'circle' \| 'round'`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/avatar/type.ts) | N
|
||||
size | String | medium | 尺寸,示例值:small/medium/large/24px/38px 等 | N
|
||||
|
||||
### Avatar Events
|
||||
|
||||
名称 | 参数 | 描述
|
||||
-- | -- | --
|
||||
error | \- | 图片加载失败时触发
|
||||
|
||||
### AvatarGroup Props
|
||||
|
||||
名称 | 类型 | 默认值 | 说明 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
cascading | String | 'right-up' | 图片之间的层叠关系,可选值:左侧图片在上和右侧图片在上。可选项:left-up/right-up。TS 类型:`CascadingValue` `type CascadingValue = 'left-up' \| 'right-up'`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/avatar-group/type.ts) | N
|
||||
collapse-avatar | String / Slot | - | 头像数量超出时,会出现一个头像折叠元素。该元素内容可自定义。默认为 `+N`。示例:`+5`,`...`, `更多` | N
|
||||
custom-style | String | - | `0.25.0`。自定义组件样式 | N
|
||||
external-classes | Array | - | 组件类名,用于设置组件外层元素类名。`['t-class', 't-class-image', 't-class-content']` | N
|
||||
max | Number | - | 能够同时显示的最多头像数量 | N
|
||||
size | String | medium | 尺寸,示例值:small/medium/large/24px/38px 等。优先级低于 Avatar.size | N
|
||||
@@ -0,0 +1,23 @@
|
||||
import { SuperComponent, RelationsOptions } from '../common/src/index';
|
||||
export default class Avatar extends SuperComponent {
|
||||
options: {
|
||||
multipleSlots: boolean;
|
||||
};
|
||||
externalClasses: string[];
|
||||
properties: import("./type").TdAvatarProps;
|
||||
data: {
|
||||
prefix: string;
|
||||
classPrefix: string;
|
||||
isShow: boolean;
|
||||
zIndex: number;
|
||||
};
|
||||
relations: RelationsOptions;
|
||||
observers: {
|
||||
icon(icon: any): void;
|
||||
};
|
||||
methods: {
|
||||
hide(): void;
|
||||
updateCascading(zIndex: any): void;
|
||||
onLoadError(e: WechatMiniprogram.CustomEvent): void;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
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 avatarProps from './props';
|
||||
import { setIcon } from '../common/utils';
|
||||
const { prefix } = config;
|
||||
const name = `${prefix}-avatar`;
|
||||
let Avatar = class Avatar extends SuperComponent {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.options = {
|
||||
multipleSlots: true,
|
||||
};
|
||||
this.externalClasses = [
|
||||
`${prefix}-class`,
|
||||
`${prefix}-class-image`,
|
||||
`${prefix}-class-icon`,
|
||||
`${prefix}-class-alt`,
|
||||
`${prefix}-class-content`,
|
||||
];
|
||||
this.properties = avatarProps;
|
||||
this.data = {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
isShow: true,
|
||||
zIndex: 0,
|
||||
};
|
||||
this.relations = {
|
||||
'../avatar-group/avatar-group': {
|
||||
type: 'ancestor',
|
||||
linked(parent) {
|
||||
var _a;
|
||||
this.parent = parent;
|
||||
this.setData({
|
||||
size: (_a = this.data.size) !== null && _a !== void 0 ? _a : parent.data.size,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
this.observers = {
|
||||
icon(icon) {
|
||||
const obj = setIcon('icon', icon, '');
|
||||
this.setData(Object.assign({}, obj));
|
||||
},
|
||||
};
|
||||
this.methods = {
|
||||
hide() {
|
||||
this.setData({
|
||||
isShow: false,
|
||||
});
|
||||
},
|
||||
updateCascading(zIndex) {
|
||||
this.setData({ zIndex });
|
||||
},
|
||||
onLoadError(e) {
|
||||
if (this.properties.hideOnLoadFailed) {
|
||||
this.setData({
|
||||
isShow: false,
|
||||
});
|
||||
}
|
||||
this.triggerEvent('error', e.detail);
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
Avatar = __decorate([
|
||||
wxComponent()
|
||||
], Avatar);
|
||||
export default Avatar;
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"t-icon": "../icon/icon",
|
||||
"t-badge": "../badge/badge",
|
||||
"t-image": "../image/image"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<import src="../common/template/icon.wxml" />
|
||||
<wxs src="../common/utils.wxs" module="_" />
|
||||
<wxs src="./avatar.wxs" module="this" />
|
||||
|
||||
<view class="{{classPrefix}}__wrapper {{prefix}}-class" style="{{this.getStyles(isShow, zIndex, customStyle)}}">
|
||||
<t-badge
|
||||
color="{{badgeProps.color}}"
|
||||
content="{{badgeProps.content}}"
|
||||
count="{{badgeProps.count}}"
|
||||
dot="{{badgeProps.dot}}"
|
||||
max-count="{{badgeProps.maxCount || 99}}"
|
||||
offset="{{badgeProps.offset}}"
|
||||
shape="{{badgeProps.shape || 'circle'}}"
|
||||
show-zero="{{badgeProps.showZero}}"
|
||||
size="{{badgeProps.size || 'medium'}}"
|
||||
t-class="{{badgeProps.tClass}}"
|
||||
t-class-content="{{badgeProps.tClassContent}}"
|
||||
t-class-count="{{badgeProps.tClassCount}}"
|
||||
>
|
||||
<view
|
||||
class="{{this.getClass(classPrefix, size, shape, bordered)}} {{prefix}}-class-image"
|
||||
style="{{this.getSize(size)}}"
|
||||
aria-label="{{ ariaLabel || alt ||'头像'}}"
|
||||
aria-role="{{ ariaRole || 'img'}}"
|
||||
aria-hidden="{{ ariaHidden }}"
|
||||
>
|
||||
<t-image
|
||||
wx:if="{{image}}"
|
||||
class="{{prefix}}-image"
|
||||
t-class="{{classPrefix}}__image"
|
||||
t-class-load="{{prefix}}-class-alt"
|
||||
customStyle="{{imageProps.customStyle}}"
|
||||
src="{{image}}"
|
||||
mode="{{imageProps.mode || 'aspectFill'}}"
|
||||
lazy="{{imageProps.lazy}}"
|
||||
loading="{{imageProps.loading}}"
|
||||
shape="{{imageProps.shape || 'round'}}"
|
||||
webp="{{imageProps.webp}}"
|
||||
error="{{alt}}"
|
||||
bind:error="onLoadError"
|
||||
/>
|
||||
<template
|
||||
wx:elif="{{iconName || _.isNoEmptyObj(iconData)}}"
|
||||
is="icon"
|
||||
data="{{class: classPrefix + '__icon', tClass: prefix + '-class-icon', name: iconName, ...iconData}}"
|
||||
/>
|
||||
<view wx:else class="{{classPrefix}}__text {{prefix}}-class-content">
|
||||
<slot />
|
||||
</view>
|
||||
</view>
|
||||
</t-badge>
|
||||
</view>
|
||||
@@ -0,0 +1,26 @@
|
||||
module.exports = {
|
||||
getClass: function (classPrefix, size, shape, bordered) {
|
||||
var hasPx = (size || '').indexOf('px') > -1;
|
||||
var borderSize = hasPx ? 'medium' : size;
|
||||
var classNames = [
|
||||
classPrefix,
|
||||
classPrefix + (shape === 'round' ? '--round' : '--circle'),
|
||||
bordered ? classPrefix + '--border' + ' ' + classPrefix + '--border-' + borderSize : '',
|
||||
hasPx ? '' : classPrefix + '--' + size,
|
||||
];
|
||||
return classNames.join(' ');
|
||||
},
|
||||
|
||||
getSize: function (size = 'medium') {
|
||||
var pxIndex = size.indexOf('px');
|
||||
if (pxIndex > -1) {
|
||||
return 'width:' + size + ';height:' + size + ';font-size:' + ((size.slice(0, pxIndex) / 8) * 3 + 2) + 'px;';
|
||||
}
|
||||
},
|
||||
|
||||
getStyles: function (isShow, zIndex, customStyle) {
|
||||
var displayStyle = isShow ? '' : 'display: none;';
|
||||
var zIndexStyle = zIndex ? 'z-index:' + zIndex + ';' : '';
|
||||
return displayStyle + zIndexStyle + customStyle;
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,102 @@
|
||||
.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-avatar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
background-color: var(--td-avatar-bg-color, var(--td-primary-color-2, #d4e3fc));
|
||||
color: var(--td-avatar-content-color, var(--td-primary-color, #0052d9));
|
||||
}
|
||||
.t-avatar--large {
|
||||
width: var(--td-avatar-large-width, 128rpx);
|
||||
height: var(--td-avatar-large-width, 128rpx);
|
||||
font-size: var(--td-avatar-text-large-font-size, 16px);
|
||||
}
|
||||
.t-avatar--large .t-avatar__icon {
|
||||
font-size: var(--td-avatar-icon-large-font-size, 64rpx);
|
||||
}
|
||||
.t-avatar--medium {
|
||||
width: var(--td-avatar-medium-width, 96rpx);
|
||||
height: var(--td-avatar-medium-width, 96rpx);
|
||||
font-size: var(--td-avatar-text-medium-font-size, var(--td-font-size-base, 28rpx));
|
||||
}
|
||||
.t-avatar--medium .t-avatar__icon {
|
||||
font-size: var(--td-avatar-icon-medium-font-size, 48rpx);
|
||||
}
|
||||
.t-avatar--small {
|
||||
width: var(--td-avatar-small-width, 80rpx);
|
||||
height: var(--td-avatar-small-width, 80rpx);
|
||||
font-size: var(--td-avatar-text-small-font-size, var(--td-font-size-s, 24rpx));
|
||||
}
|
||||
.t-avatar--small .t-avatar__icon {
|
||||
font-size: var(--td-avatar-icon-small-font-size, 40rpx);
|
||||
}
|
||||
.t-avatar .t-image,
|
||||
.t-avatar__image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.t-avatar--circle {
|
||||
border-radius: var(--td-avatar-circle-border-radius, var(--td-radius-circle, 50%));
|
||||
overflow: hidden;
|
||||
}
|
||||
.t-avatar--round {
|
||||
border-radius: var(--td-avatar-round-border-radius, var(--td-radius-default, 12rpx));
|
||||
overflow: hidden;
|
||||
}
|
||||
.t-avatar__text,
|
||||
.t-avatar__icon {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.t-avatar__text:empty,
|
||||
.t-avatar__icon:empty {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
.t-avatar--border {
|
||||
border-color: var(--td-avatar-border-color, #fff);
|
||||
border-style: solid;
|
||||
}
|
||||
.t-avatar--border-small {
|
||||
border-width: var(--td-avatar-border-width-small, 4rpx);
|
||||
}
|
||||
.t-avatar--border-medium {
|
||||
border-width: var(--td-avatar-border-width-medium, 6rpx);
|
||||
}
|
||||
.t-avatar--border-large {
|
||||
border-width: var(--td-avatar-border-width-large, 8rpx);
|
||||
}
|
||||
.t-avatar__wrapper {
|
||||
display: inline-flex;
|
||||
position: relative;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import { TdAvatarProps } from './type';
|
||||
declare const props: TdAvatarProps;
|
||||
export default props;
|
||||
@@ -0,0 +1,43 @@
|
||||
const props = {
|
||||
alt: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
badgeProps: {
|
||||
type: Object,
|
||||
},
|
||||
bordered: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
customStyle: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
externalClasses: {
|
||||
type: Array,
|
||||
},
|
||||
hideOnLoadFailed: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
icon: {
|
||||
type: null,
|
||||
},
|
||||
image: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
imageProps: {
|
||||
type: Object,
|
||||
},
|
||||
shape: {
|
||||
type: String,
|
||||
value: 'circle',
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
value: 'medium',
|
||||
},
|
||||
};
|
||||
export default props;
|
||||
@@ -0,0 +1,48 @@
|
||||
import { BadgeProps } from '../badge/index';
|
||||
export interface TdAvatarProps {
|
||||
alt?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
badgeProps?: {
|
||||
type: ObjectConstructor;
|
||||
value?: BadgeProps;
|
||||
};
|
||||
bordered?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
customStyle?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
externalClasses?: {
|
||||
type: ArrayConstructor;
|
||||
value?: ['t-class', 't-class-image', 't-class-icon', 't-class-alt', 't-class-content'];
|
||||
};
|
||||
hideOnLoadFailed?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
icon?: {
|
||||
type: null;
|
||||
value?: string | object;
|
||||
};
|
||||
image?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
imageProps?: {
|
||||
type: ObjectConstructor;
|
||||
value?: object;
|
||||
};
|
||||
shape?: {
|
||||
type: StringConstructor;
|
||||
value?: ShapeEnum;
|
||||
};
|
||||
size?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
}
|
||||
export declare type ShapeEnum = 'circle' | 'round';
|
||||
@@ -0,0 +1 @@
|
||||
export {};
|
||||
@@ -0,0 +1,18 @@
|
||||
:: BASE_DOC ::
|
||||
|
||||
## API
|
||||
### Badge Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
color | String | - | \- | N
|
||||
content | String | - | \- | N
|
||||
count | String / Number / Slot | 0 | \- | N
|
||||
custom-style `v0.25.0` | String | - | \- | N
|
||||
dot | Boolean | false | \- | N
|
||||
external-classes | Array | - | `['t-class', 't-class-content', 't-class-count']` | N
|
||||
max-count | Number | 99 | \- | N
|
||||
offset | Array | - | Typescript:`Array<string \| number>` | N
|
||||
shape | String | circle | options:circle/round/ribbon/bubble | N
|
||||
show-zero | Boolean | false | \- | N
|
||||
size | String | medium | options:small/medium | N
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
title: Badge 徽标
|
||||
description: 用于告知用户,该区域的状态变化或者待处理任务的数量。
|
||||
spline: data
|
||||
isComponent: true
|
||||
---
|
||||
|
||||
<span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20lines-100%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20functions-100%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20statements-100%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20branches-100%25-blue" /></span>
|
||||
## 引入
|
||||
|
||||
全局引入,在 miniprogram 根目录下的`app.json`中配置,局部引入,在需要引入的页面或组件的`index.json`中配置。
|
||||
|
||||
```json
|
||||
"usingComponents": {
|
||||
"t-badge": "tdesign-miniprogram/badge/badge"
|
||||
}
|
||||
```
|
||||
|
||||
## 代码演示
|
||||
|
||||
### 组件类型
|
||||
|
||||
{{ base }}
|
||||
|
||||
### 组件样式
|
||||
|
||||
{{ theme }}
|
||||
|
||||
### 组件尺寸
|
||||
|
||||
{{ size }}
|
||||
|
||||
## API
|
||||
### Badge Props
|
||||
|
||||
名称 | 类型 | 默认值 | 说明 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
color | String | - | 颜色 | N
|
||||
content | String | - | 徽标内容,示例:`content='自定义内容'`。也可以使用默认插槽定义 | N
|
||||
count | String / Number / Slot | 0 | 徽标右上角内容。可以是数字,也可以是文字。如:'new'/3/99+。特殊:值为空表示使用插槽渲染 | N
|
||||
custom-style `v0.25.0` | String | - | 自定义组件样式 | N
|
||||
dot | Boolean | false | 是否为红点 | N
|
||||
external-classes | Array | - | 组件类名,分别用于设置外层元素、默认内容、右上角内容等元素类名。`['t-class', 't-class-content', 't-class-count']` | N
|
||||
max-count | Number | 99 | 封顶的数字值 | N
|
||||
offset | Array | - | 设置状态点的位置偏移,示例:[-10, 20] 或 ['10em', '8rem']。TS 类型:`Array<string \| number>` | N
|
||||
shape | String | circle | 形状。可选项:circle/round/ribbon/bubble | N
|
||||
show-zero | Boolean | false | 当数值为 0 时,是否展示徽标 | N
|
||||
size | String | medium | 尺寸。可选项:small/medium | N
|
||||
@@ -0,0 +1,21 @@
|
||||
import { SuperComponent } from '../common/src/index';
|
||||
import type { TdBadgeProps } from './type';
|
||||
export interface BadgeProps extends TdBadgeProps {
|
||||
}
|
||||
export default class Badge extends SuperComponent {
|
||||
options: {
|
||||
multipleSlots: boolean;
|
||||
};
|
||||
externalClasses: string[];
|
||||
properties: TdBadgeProps;
|
||||
data: {
|
||||
prefix: string;
|
||||
classPrefix: string;
|
||||
value: string;
|
||||
labelID: string;
|
||||
descriptionID: string;
|
||||
};
|
||||
lifetimes: {
|
||||
ready(): void;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
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 { uniqueFactory } from '../common/utils';
|
||||
const { prefix } = config;
|
||||
const name = `${prefix}-badge`;
|
||||
const getUniqueID = uniqueFactory('badge');
|
||||
let Badge = class Badge extends SuperComponent {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.options = {
|
||||
multipleSlots: true,
|
||||
};
|
||||
this.externalClasses = [`${prefix}-class`, `${prefix}-class-count`, `${prefix}-class-content`];
|
||||
this.properties = props;
|
||||
this.data = {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
value: '',
|
||||
labelID: '',
|
||||
descriptionID: '',
|
||||
};
|
||||
this.lifetimes = {
|
||||
ready() {
|
||||
const uniqueID = getUniqueID();
|
||||
this.setData({
|
||||
labelID: `${uniqueID}_label`,
|
||||
descriptionID: `${uniqueID}_description`,
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
Badge = __decorate([
|
||||
wxComponent()
|
||||
], Badge);
|
||||
export default Badge;
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<wxs src="./badge.wxs" module="this" />
|
||||
|
||||
<view
|
||||
style="{{ customStyle }}"
|
||||
class="{{this.getBadgeOuterClass({shape})}} {{prefix}}-class"
|
||||
aria-labelledby="{{labelID}}"
|
||||
aria-describedby="{{descriptionID}}"
|
||||
aria-role="{{ ariaRole || 'option'}}"
|
||||
>
|
||||
<view id="{{labelID}}" class="{{classPrefix}}__content {{prefix}}-class-content" aria-hidden="true">
|
||||
<slot wx:if="{{!content}}" class="{{classPrefix}}__content-slot" />
|
||||
<text wx:else class="{{classPrefix}}__content-text">{{content}}</text>
|
||||
</view>
|
||||
<view
|
||||
aria-hidden="true"
|
||||
aria-label="{{ ariaLabel || this.getBadgeAriaLabel({dot, count, maxCount}) }}"
|
||||
id="{{descriptionID}}"
|
||||
wx:if="{{count !== 'slot' && this.isShowBadge({dot,count,showZero})}}"
|
||||
class="{{this.getBadgeInnerClass({dot, size, shape, count})}} {{prefix}}-has-count {{prefix}}-class-count"
|
||||
style="{{this.getBadgeStyles({color, offset})}}"
|
||||
>{{ this.getBadgeValue({dot, count, maxCount}) }}
|
||||
</view>
|
||||
<slot name="count" wx:if="{{count === 'slot' || !count}}" />
|
||||
</view>
|
||||
@@ -0,0 +1,84 @@
|
||||
var getBadgeValue = function (props) {
|
||||
if (props.dot) {
|
||||
return '';
|
||||
}
|
||||
if (isNaN(props.count) || isNaN(props.maxCount)) {
|
||||
return props.count;
|
||||
}
|
||||
return parseInt(props.count) > props.maxCount ? props.maxCount + '+' : props.count;
|
||||
};
|
||||
|
||||
var hasUnit = function (unit) {
|
||||
return (
|
||||
unit.indexOf('px') > 0 ||
|
||||
unit.indexOf('rpx') > 0 ||
|
||||
unit.indexOf('em') > 0 ||
|
||||
unit.indexOf('rem') > 0 ||
|
||||
unit.indexOf('%') > 0 ||
|
||||
unit.indexOf('vh') > 0 ||
|
||||
unit.indexOf('vm') > 0
|
||||
);
|
||||
};
|
||||
|
||||
var getBadgeStyles = function (props) {
|
||||
var styleStr = '';
|
||||
if (props.color) {
|
||||
styleStr += 'background:' + props.color + ';';
|
||||
}
|
||||
if (props.offset[0]) {
|
||||
styleStr += 'right:' + (hasUnit(props.offset[0].toString()) ? props.offset[0] : props.offset[0] + 'px') + ';';
|
||||
}
|
||||
if (props.offset[1]) {
|
||||
styleStr += 'top:' + (hasUnit(props.offset[1].toString()) ? props.offset[1] : props.offset[1] + 'px') + ';';
|
||||
}
|
||||
return styleStr;
|
||||
};
|
||||
|
||||
var getBadgeOuterClass = function (props) {
|
||||
var baseClass = 't-badge';
|
||||
var classNames = [baseClass, props.shape === 'ribbon' ? baseClass + '__ribbon-outer' : ''];
|
||||
return classNames.join(' ');
|
||||
};
|
||||
|
||||
var getBadgeInnerClass = function (props) {
|
||||
var baseClass = 't-badge';
|
||||
var classNames = [
|
||||
baseClass + '--basic',
|
||||
props.dot ? baseClass + '--dot' : '',
|
||||
baseClass + '--' + props.size,
|
||||
baseClass + '--' + props.shape,
|
||||
!props.dot && props.count ? baseClass + '--count' : '',
|
||||
];
|
||||
return classNames.join(' ');
|
||||
};
|
||||
|
||||
var isShowBadge = function (props) {
|
||||
if (props.dot) {
|
||||
return true;
|
||||
}
|
||||
if (!props.showZero && !isNaN(props.count) && parseInt(props.count) === 0) {
|
||||
return false;
|
||||
}
|
||||
if (props.count == null) return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
var getBadgeAriaLabel = function (props) {
|
||||
if (props.dot) {
|
||||
return '有新的消息';
|
||||
}
|
||||
if (isNaN(props.count) || isNaN(props.maxCount)) {
|
||||
var str = '有' + props.count + '通知';
|
||||
return str;
|
||||
}
|
||||
var str1 = '有' + props.maxCount + '+条消息';
|
||||
var str2 = '有' + props.count + '条消息';
|
||||
return parseInt(props.count) > props.maxCount ? str1 : str2;
|
||||
};
|
||||
|
||||
module.exports.getBadgeValue = getBadgeValue;
|
||||
module.exports.getBadgeStyles = getBadgeStyles;
|
||||
module.exports.getBadgeOuterClass = getBadgeOuterClass;
|
||||
module.exports.getBadgeInnerClass = getBadgeInnerClass;
|
||||
module.exports.getBadgeAriaLabel = getBadgeAriaLabel;
|
||||
module.exports.isShowBadge = isShowBadge;
|
||||
@@ -0,0 +1,111 @@
|
||||
.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-badge {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
.t-badge--basic {
|
||||
display: inline-block;
|
||||
z-index: 100;
|
||||
padding: 0 var(--td-badge-basic-padding, 8rpx);
|
||||
font-size: var(--td-badge-font-size, var(--td-font-size-xs, var(--td-font-size, 20rpx)));
|
||||
color: var(--td-badge-text-color, var(--td-font-white-1, #ffffff));
|
||||
background-color: var(--td-badge-bg-color, var(--td-error-color, var(--td-error-color-6, #e34d59)));
|
||||
text-align: center;
|
||||
height: var(--td-badge-basic-height, 32rpx);
|
||||
line-height: var(--td-badge-basic-height, 32rpx);
|
||||
font-weight: var(--td-badge-font-weight, 600);
|
||||
border-radius: var(--td-badge-border-radius, 4rpx);
|
||||
}
|
||||
.t-badge--dot {
|
||||
height: var(--td-badge-dot-size, 16rpx);
|
||||
border-radius: 50%;
|
||||
min-width: var(--td-badge-dot-size, 16rpx);
|
||||
padding: 0;
|
||||
}
|
||||
.t-badge--count {
|
||||
min-width: var(--td-badge-basic-width, 32rpx);
|
||||
white-space: nowrap;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.t-badge--circle {
|
||||
border-radius: calc(var(--td-badge-basic-height, 32rpx) / 2);
|
||||
}
|
||||
.t-badge__ribbon-outer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
.t-badge--ribbon {
|
||||
transform: rotate(45deg);
|
||||
border-radius: 0;
|
||||
}
|
||||
.t-badge--ribbon::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
bottom: 0;
|
||||
left: calc(-1 * var(--td-badge-basic-height, 32rpx) + 1rpx);
|
||||
border-bottom: var(--td-badge-basic-height, 32rpx) solid var(--td-badge-bg-color, var(--td-error-color, var(--td-error-color-6, #e34d59)));
|
||||
border-left: var(--td-badge-basic-height, 32rpx) solid transparent;
|
||||
}
|
||||
.t-badge--ribbon::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
bottom: 0;
|
||||
right: calc(-1 * var(--td-badge-basic-height, 32rpx) + 1rpx);
|
||||
border-bottom: var(--td-badge-basic-height, 32rpx) solid var(--td-badge-bg-color, var(--td-error-color, var(--td-error-color-6, #e34d59)));
|
||||
border-right: var(--td-badge-basic-height, 32rpx) solid transparent;
|
||||
}
|
||||
.t-badge--bubble {
|
||||
border-radius: var(--td-badge-bubble-border-radius, 20rpx 20rpx 20rpx 1px);
|
||||
}
|
||||
.t-badge--large {
|
||||
font-size: var(--td-badge-large-font-size, var(--td-font-size-s, 24rpx));
|
||||
height: var(--td-badge-large-height, 40rpx);
|
||||
min-width: var(--td-badge-large-height, 40rpx);
|
||||
line-height: var(--td-badge-large-height, 40rpx);
|
||||
padding: 0 var(--td-badge-large-padding, 10rpx);
|
||||
}
|
||||
.t-badge--large.t-badge--circle {
|
||||
border-radius: calc(var(--td-badge-large-height, 40rpx) / 2);
|
||||
}
|
||||
.t-badge__content:not(:empty) + .t-has-count {
|
||||
transform: translate(50%, -50%);
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
.t-badge__content-text {
|
||||
display: block;
|
||||
line-height: 48rpx;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from './type';
|
||||
export * from './props';
|
||||
export * from './badge';
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from './type';
|
||||
export * from './props';
|
||||
export * from './badge';
|
||||
@@ -0,0 +1,3 @@
|
||||
import { TdBadgeProps } from './type';
|
||||
declare const props: TdBadgeProps;
|
||||
export default props;
|
||||
@@ -0,0 +1,45 @@
|
||||
const props = {
|
||||
color: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
content: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
count: {
|
||||
type: null,
|
||||
value: 0,
|
||||
},
|
||||
customStyle: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
dot: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
externalClasses: {
|
||||
type: Array,
|
||||
},
|
||||
maxCount: {
|
||||
type: Number,
|
||||
value: 99,
|
||||
},
|
||||
offset: {
|
||||
type: Array,
|
||||
},
|
||||
shape: {
|
||||
type: String,
|
||||
value: 'circle',
|
||||
},
|
||||
showZero: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
value: 'medium',
|
||||
},
|
||||
};
|
||||
export default props;
|
||||
@@ -0,0 +1,46 @@
|
||||
export interface TdBadgeProps {
|
||||
color?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
content?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
count?: {
|
||||
type: null;
|
||||
value?: string | number;
|
||||
};
|
||||
customStyle?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
dot?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
externalClasses?: {
|
||||
type: ArrayConstructor;
|
||||
value?: ['t-class', 't-class-content', 't-class-count'];
|
||||
};
|
||||
maxCount?: {
|
||||
type: NumberConstructor;
|
||||
value?: number;
|
||||
};
|
||||
offset?: {
|
||||
type: ArrayConstructor;
|
||||
value?: Array<string | number>;
|
||||
};
|
||||
shape?: {
|
||||
type: StringConstructor;
|
||||
value?: 'circle' | 'round' | 'ribbon' | 'bubble';
|
||||
};
|
||||
showZero?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
size?: {
|
||||
type: StringConstructor;
|
||||
value?: 'small' | 'medium';
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export {};
|
||||
@@ -0,0 +1,47 @@
|
||||
:: BASE_DOC ::
|
||||
|
||||
## API
|
||||
### Button Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
block | Boolean | false | make button to be a block-level element | N
|
||||
content | String / Slot | - | button's children elements | N
|
||||
custom-dataset | Object | - | Typescript:`any` | N
|
||||
custom-style `v0.25.0` | String | - | \- | N
|
||||
disabled | Boolean | false | disable the button, make it can not be clicked | N
|
||||
external-classes | Array | - | `['t-class', 't-class-icon', 't-class-loading']` | N
|
||||
ghost | Boolean | false | make background-color to be transparent | N
|
||||
icon | String | - | icon name | N
|
||||
icon-props | Object | {} | icon properties | N
|
||||
loading | Boolean | false | set button to be loading state | N
|
||||
loading-props | Object | - | Typescript:`LoadingProps`,[Loading API Documents](./loading?tab=api)。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/button/type.ts) | N
|
||||
shape | String | rectangle | button shape。options:rectangle/square/round/circle | N
|
||||
size | String | medium | a button has three size。options:small/medium/large。Typescript:`SizeEnum` | N
|
||||
theme | String | default | button theme。options:default/primary/danger | N
|
||||
type | String | - | type of button element, same as formType of Miniprogram。options:submit/reset | N
|
||||
variant | String | base | button variant。options:base/outline/text | N
|
||||
open-type | String | - | options:contact/share/getPhoneNumber/getUserInfo/launchApp/openSetting/feedback/chooseAvatar | N
|
||||
hover-stop-propagation | Boolean | false | \- | N
|
||||
hover-start-time | Number | 20 | \- | N
|
||||
hover-stay-time | Number | 70 | \- | N
|
||||
lang | String | en | options:en/zh_CN/zh_TW | N
|
||||
session-from | String | - | \- | N
|
||||
send-message-title | String | 当前标题 | \- | N
|
||||
send-message-path | String | 当前分享路径 | \- | N
|
||||
send-message-img | String | 截图 | \- | N
|
||||
app-parameter | String | - | \- | N
|
||||
show-message-card | Boolean | false | \- | N
|
||||
bindgetuserinfo | Eventhandle | - | \- | N
|
||||
bindcontact | Eventhandle | - | \- | N
|
||||
bindgetphonenumber | Eventhandle | - | \- | N
|
||||
binderror | Eventhandle | - | \- | N
|
||||
bindopensetting | Eventhandle | - | \- | N
|
||||
bindlaunchapp | Eventhandle | - | \- | N
|
||||
bindchooseavatar | Eventhandle | - | \- | N
|
||||
|
||||
### Button Events
|
||||
|
||||
name | params | description
|
||||
-- | -- | --
|
||||
tap | `event` | \-
|
||||
@@ -0,0 +1,106 @@
|
||||
---
|
||||
title: Button 按钮
|
||||
description: 用于开启一个闭环的操作任务,如“删除”对象、“购买”商品等。
|
||||
spline: base
|
||||
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-button": "tdesign-miniprogram/button/button"
|
||||
}
|
||||
```
|
||||
|
||||
## 代码演示
|
||||
|
||||
### 01 组件类型
|
||||
|
||||
基础按钮
|
||||
|
||||
{{ base }}
|
||||
|
||||
图标按钮
|
||||
|
||||
{{ icon-btn }}
|
||||
|
||||
幽灵按钮
|
||||
|
||||
{{ ghost-btn }}
|
||||
|
||||
组合按钮
|
||||
|
||||
{{ group-btn }}
|
||||
|
||||
通栏按钮
|
||||
|
||||
{{ block-btn }}
|
||||
|
||||
### 02 组件状态
|
||||
|
||||
按钮禁用态
|
||||
|
||||
{{ disabled }}
|
||||
|
||||
### 03 组件样式
|
||||
|
||||
按钮尺寸
|
||||
|
||||
{{ size }}
|
||||
|
||||
按钮形状
|
||||
|
||||
{{ shape }}
|
||||
|
||||
按钮主题
|
||||
|
||||
{{ theme }}
|
||||
|
||||
## API
|
||||
### Button Props
|
||||
|
||||
名称 | 类型 | 默认值 | 说明 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
block | Boolean | false | 是否为块级元素 | N
|
||||
content | String / Slot | - | 按钮内容 | N
|
||||
custom-dataset | Object | - | 自定义 dataset,可通过 event.currentTarget.dataset.custom 获取。TS 类型:`any` | N
|
||||
custom-style `v0.25.0` | String | - | 自定义组件样式 | N
|
||||
disabled | Boolean | false | 禁用状态 | N
|
||||
external-classes | Array | - | 组件类名。`['t-class', 't-class-icon', 't-class-loading']` | N
|
||||
ghost | Boolean | false | 是否为幽灵按钮(镂空按钮) | N
|
||||
icon | String / Object | - | 图标名称。值为字符串表示图标名称,值为 `Object` 类型,表示透传至 `icon`。 | N
|
||||
loading | Boolean | false | 是否显示为加载状态 | N
|
||||
loading-props | Object | - | 加载loading样式。TS 类型:`LoadingProps`,[Loading API Documents](./loading?tab=api)。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/button/type.ts) | N
|
||||
shape | String | rectangle | 按钮形状,有 4 种:长方形、正方形、圆角长方形、圆形。可选项:rectangle/square/round/circle | N
|
||||
size | String | medium | 组件尺寸。可选项:extra-small/small/medium/large。TS 类型:`SizeEnum` | N
|
||||
theme | String | default | 组件风格,依次为品牌色、危险色。可选项:default/primary/danger/light | N
|
||||
type | String | - | 同小程序的 formType。可选项:submit/reset | N
|
||||
variant | String | base | 按钮形式,基础、线框、文字。可选项:base/outline/dashed/text | N
|
||||
open-type | String | - | 微信开放能力。<br />具体释义:<br />`contact` 打开客服会话,如果用户在会话中点击消息卡片后返回小程序,可以从 bindcontact 回调中获得具体信息,<a href="https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/customer-message/customer-message.html">具体说明</a> (*小程序插件中不能使用*);<br />`share` 触发用户转发,使用前建议先阅读<a href="https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share.html#使用指引">使用指引</a>;<br />`getPhoneNumber` 获取用户手机号,可以从 bindgetphonenumber 回调中获取到用户信息,<a href="https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html">具体说明</a> (*小程序插件中不能使用*);<br />`getUserInfo` 获取用户信息,可以从 bindgetuserinfo 回调中获取到用户信息 (*小程序插件中不能使用*);<br />`launchApp` 打开APP,可以通过 app-parameter 属性设定向 APP 传的参数<a href="https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/launchApp.html">具体说明</a>;<br />`openSetting` 打开授权设置页;<br />`feedback` 打开“意见反馈”页面,用户可提交反馈内容并上传<a href="https://developers.weixin.qq.com/miniprogram/dev/api/base/debug/wx.getLogManager.html">日志</a>,开发者可以登录<a href="https://mp.weixin.qq.com/">小程序管理后台</a>后进入左侧菜单“客服反馈”页面获取到反馈内容;<br />`chooseAvatar` 获取用户头像,可以从 bindchooseavatar 回调中获取到头像信息。<br />[小程序官方文档](https://developers.weixin.qq.com/miniprogram/dev/component/button.html)。可选项:contact/share/getPhoneNumber/getUserInfo/launchApp/openSetting/feedback/chooseAvatar | N
|
||||
hover-stop-propagation | Boolean | false | 指定是否阻止本节点的祖先节点出现点击态 | N
|
||||
hover-start-time | Number | 20 | 按住后多久出现点击态,单位毫秒 | N
|
||||
hover-stay-time | Number | 70 | 手指松开后点击态保留时间,单位毫秒 | N
|
||||
lang | String | en | 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文。。<br />具体释义:<br />`en` 英文;<br />`zh_CN` 简体中文;<br />`zh_TW` 繁体中文。<br />[小程序官方文档](https://developers.weixin.qq.com/miniprogram/dev/component/button.html)。可选项:en/zh_CN/zh_TW | N
|
||||
session-from | String | - | 会话来源,open-type="contact"时有效 | N
|
||||
send-message-title | String | 当前标题 | 会话内消息卡片标题,open-type="contact"时有效 | N
|
||||
send-message-path | String | 当前分享路径 | 会话内消息卡片点击跳转小程序路径,open-type="contact"时有效 | N
|
||||
send-message-img | String | 截图 | 会话内消息卡片图片,open-type="contact"时有效 | N
|
||||
app-parameter | String | - | 打开 APP 时,向 APP 传递的参数,open-type=launchApp时有效 | N
|
||||
show-message-card | Boolean | false | 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,用户点击后可以快速发送小程序消息,open-type="contact"时有效 | N
|
||||
bindgetuserinfo | Eventhandle | - | 用户点击该按钮时,会返回获取到的用户信息,回调的 detail 数据与<a href="https://developers.weixin.qq.com/miniprogram/dev/api/open-api/user-info/wx.getUserInfo.html">wx.getUserInfo</a>返回的一致,open-type="getUserInfo"时有效 | N
|
||||
bindcontact | Eventhandle | - | 客服消息回调,open-type="contact"时有效 | N
|
||||
bindgetphonenumber | Eventhandle | - | 获取用户手机号回调,open-type=getPhoneNumber时有效 | N
|
||||
binderror | Eventhandle | - | 当使用开放能力时,发生错误的回调,open-type=launchApp时有效 | N
|
||||
bindopensetting | Eventhandle | - | 在打开授权设置页后回调,open-type=openSetting时有效 | N
|
||||
bindlaunchapp | Eventhandle | - | 打开 APP 成功的回调,open-type=launchApp时有效 | N
|
||||
bindchooseavatar | Eventhandle | - | 获取用户头像回调,open-type=chooseAvatar时有效 | N
|
||||
|
||||
### Button Events
|
||||
|
||||
名称 | 参数 | 描述
|
||||
-- | -- | --
|
||||
tap | `event` | 点击时触发
|
||||
@@ -0,0 +1,32 @@
|
||||
import { SuperComponent } from '../common/src/index';
|
||||
import type { TdButtonProps } from './type';
|
||||
export interface ButtonProps extends TdButtonProps {
|
||||
}
|
||||
export default class Button extends SuperComponent {
|
||||
externalClasses: string[];
|
||||
behaviors: string[];
|
||||
properties: TdButtonProps;
|
||||
data: {
|
||||
prefix: string;
|
||||
className: string;
|
||||
classPrefix: string;
|
||||
};
|
||||
observers: {
|
||||
'theme, size, plain, block, shape, disabled, loading'(): void;
|
||||
icon(icon: any): void;
|
||||
};
|
||||
lifetimes: {
|
||||
attached(): void;
|
||||
};
|
||||
methods: {
|
||||
setClass(): void;
|
||||
getuserinfo(e: any): void;
|
||||
contact(e: any): void;
|
||||
getphonenumber(e: any): void;
|
||||
error(e: any): void;
|
||||
opensetting(e: any): void;
|
||||
launchapp(e: any): void;
|
||||
chooseavatar(e: any): void;
|
||||
handleTap(e: any): void;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
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 { canIUseFormFieldButton } from '../common/version';
|
||||
import { setIcon } from '../common/utils';
|
||||
const { prefix } = config;
|
||||
const name = `${prefix}-button`;
|
||||
let Button = class Button extends SuperComponent {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.externalClasses = [`${prefix}-class`, `${prefix}-class-icon`, `${prefix}-class-loading`];
|
||||
this.behaviors = canIUseFormFieldButton() ? ['wx://form-field-button'] : [];
|
||||
this.properties = props;
|
||||
this.data = {
|
||||
prefix,
|
||||
className: '',
|
||||
classPrefix: name,
|
||||
};
|
||||
this.observers = {
|
||||
'theme, size, plain, block, shape, disabled, loading'() {
|
||||
this.setClass();
|
||||
},
|
||||
icon(icon) {
|
||||
const obj = setIcon('icon', icon, '');
|
||||
this.setData(Object.assign({}, obj));
|
||||
},
|
||||
};
|
||||
this.lifetimes = {
|
||||
attached() {
|
||||
this.setClass();
|
||||
},
|
||||
};
|
||||
this.methods = {
|
||||
setClass() {
|
||||
const classList = [
|
||||
name,
|
||||
`${prefix}-class`,
|
||||
`${name}--${this.data.theme || 'default'}`,
|
||||
`${name}--size-${this.data.size || 'medium'}`,
|
||||
`${name}--${this.data.shape || 'rectangle'}`,
|
||||
`${name}--${this.data.variant || 'base'}`,
|
||||
];
|
||||
if (this.data.block) {
|
||||
classList.push(`${name}--block`);
|
||||
}
|
||||
if (this.data.disabled) {
|
||||
classList.push(`${name}--disabled`);
|
||||
}
|
||||
if (this.data.ghost) {
|
||||
classList.push(`${name}--ghost`);
|
||||
}
|
||||
this.setData({
|
||||
className: classList.join(' '),
|
||||
});
|
||||
},
|
||||
getuserinfo(e) {
|
||||
this.triggerEvent('getuserinfo', e.detail);
|
||||
},
|
||||
contact(e) {
|
||||
this.triggerEvent('contact', e.detail);
|
||||
},
|
||||
getphonenumber(e) {
|
||||
this.triggerEvent('getphonenumber', e.detail);
|
||||
},
|
||||
error(e) {
|
||||
this.triggerEvent('error', e.detail);
|
||||
},
|
||||
opensetting(e) {
|
||||
this.triggerEvent('opensetting', e.detail);
|
||||
},
|
||||
launchapp(e) {
|
||||
this.triggerEvent('launchapp', e.detail);
|
||||
},
|
||||
chooseavatar(e) {
|
||||
this.triggerEvent('chooseavatar', e.detail);
|
||||
},
|
||||
handleTap(e) {
|
||||
if (this.data.disabled)
|
||||
return;
|
||||
this.triggerEvent('tap', e);
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
Button = __decorate([
|
||||
wxComponent()
|
||||
], Button);
|
||||
export default Button;
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"t-icon": "../icon/icon",
|
||||
"t-loading": "../loading/loading"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<import src="../common/template/icon.wxml" />
|
||||
<wxs src="../common/utils.wxs" module="_" />
|
||||
|
||||
<button
|
||||
style="{{ customStyle }}"
|
||||
data-custom="{{ customDataset }}"
|
||||
class="{{className}}"
|
||||
form-type="{{type}}"
|
||||
open-type="{{disabled ? '' : openType}}"
|
||||
hover-stop-propagation="{{hoverStopPropagation}}"
|
||||
hover-start-time="{{hoverStartTime}}"
|
||||
hover-stay-time="{{hoverStayTime}}"
|
||||
lang="{{lang}}"
|
||||
session-from="{{sessionFrom}}"
|
||||
hover-class="{{disabled ? '' : classPrefix + '--hover'}}"
|
||||
send-message-title="{{sendMessageTitle}}"
|
||||
send-message-path="{{sendMessagePath}}"
|
||||
send-message-img="{{sendMessageImg}}"
|
||||
app-parameter="{{appParameter}}"
|
||||
show-message-card="{{showMessageCard}}"
|
||||
catch:tap="handleTap"
|
||||
bind:getuserinfo="getuserinfo"
|
||||
bind:contact="contact"
|
||||
bind:getphonenumber="getphonenumber"
|
||||
bind:error="error"
|
||||
bind:opensetting="opensetting"
|
||||
bind:launchapp="launchapp"
|
||||
bind:chooseavatar="chooseavatar"
|
||||
aria-label="{{ariaLabel}}"
|
||||
>
|
||||
<template
|
||||
wx:if="{{iconName || _.isNoEmptyObj(iconData)}}"
|
||||
is="icon"
|
||||
data="{{class: classPrefix + '__icon', tClass: prefix + '-class-icon', ariaHidden: true, name: iconName, ...iconData}}"
|
||||
/>
|
||||
<t-loading
|
||||
wx:if="{{loading}}"
|
||||
class="{{classPrefix}}__loading"
|
||||
delay="{{loadingProps.delay || 0}}"
|
||||
duration="{{loadingProps.duration || 800}}"
|
||||
indicator="{{loadingProps.indicator || true}}"
|
||||
inheritColor="{{loadingProps.indicator || false}}"
|
||||
layout="{{loadingProps.layout || 'horizontal'}}"
|
||||
pause="{{loadingProps.pause || false}}"
|
||||
progress="{{loadingProps.progress}}"
|
||||
reverse="{{loadingProps.reverse}}"
|
||||
size="{{loadingProps.size || '40rpx'}}"
|
||||
text="{{loadingProps.text }}"
|
||||
theme="{{loadingProps.theme || 'circular'}}"
|
||||
loading
|
||||
t-class="{{classPrefix}}__loading--wrapper"
|
||||
t-class-indicator="{{classPrefix}}__loading--indicator {{prefix}}-class-loading"
|
||||
></t-loading>
|
||||
<view class="{{classPrefix}}__content">
|
||||
<slot name="content" />
|
||||
<block>{{content}}</block>
|
||||
<slot />
|
||||
</view>
|
||||
</button>
|
||||
@@ -0,0 +1,391 @@
|
||||
.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-button--size-extra-small {
|
||||
font-size: var(--td-button-extra-small-font-size, var(--td-font-size-base, 28rpx));
|
||||
padding-left: var(--td-button-extra-small-padding-horizontal, 16rpx);
|
||||
padding-right: var(--td-button-extra-small-padding-horizontal, 16rpx);
|
||||
height: var(--td-button-extra-small-height, 56rpx);
|
||||
line-height: var(--td-button-extra-small-height, 56rpx);
|
||||
}
|
||||
.t-button--size-extra-small .t-button__icon {
|
||||
font-size: var(--td-button-extra-small-icon-font-size, 36rpx);
|
||||
}
|
||||
.t-button--size-small {
|
||||
font-size: var(--td-button-small-font-size, var(--td-font-size-base, 28rpx));
|
||||
padding-left: var(--td-button-small-padding-horizontal, 24rpx);
|
||||
padding-right: var(--td-button-small-padding-horizontal, 24rpx);
|
||||
height: var(--td-button-small-height, 64rpx);
|
||||
line-height: var(--td-button-small-height, 64rpx);
|
||||
}
|
||||
.t-button--size-small .t-button__icon {
|
||||
font-size: var(--td-button-small-icon-font-size, 36rpx);
|
||||
}
|
||||
.t-button--size-medium {
|
||||
font-size: var(--td-button-medium-font-size, var(--td-font-size-m, 32rpx));
|
||||
padding-left: var(--td-button-medium-padding-horizontal, 32rpx);
|
||||
padding-right: var(--td-button-medium-padding-horizontal, 32rpx);
|
||||
height: var(--td-button-medium-height, 80rpx);
|
||||
line-height: var(--td-button-medium-height, 80rpx);
|
||||
}
|
||||
.t-button--size-medium .t-button__icon {
|
||||
font-size: var(--td-button-medium-icon-font-size, 40rpx);
|
||||
}
|
||||
.t-button--size-large {
|
||||
font-size: var(--td-button-large-font-size, var(--td-font-size-m, 32rpx));
|
||||
padding-left: var(--td-button-large-padding-horizontal, 40rpx);
|
||||
padding-right: var(--td-button-large-padding-horizontal, 40rpx);
|
||||
height: var(--td-button-large-height, 96rpx);
|
||||
line-height: var(--td-button-large-height, 96rpx);
|
||||
}
|
||||
.t-button--size-large .t-button__icon {
|
||||
font-size: var(--td-button-large-icon-font-size, 48rpx);
|
||||
}
|
||||
.t-button--default {
|
||||
color: var(--td-button-default-color, var(--td-font-gray-1, rgba(0, 0, 0, 0.9)));
|
||||
background-color: var(--td-button-default-bg-color, var(--td-gray-color-3, #e7e7e7));
|
||||
}
|
||||
.t-button--default::after {
|
||||
border-width: var(--td-button-border-width, 4rpx);
|
||||
border-color: var(--td-button-default-border-color, var(--td-gray-color-3, #e7e7e7));
|
||||
}
|
||||
.t-button--default.t-button--hover {
|
||||
z-index: 0;
|
||||
}
|
||||
.t-button--default.t-button--hover::after {
|
||||
background-color: var(--td-button-default-active-bg-color, var(--td-gray-color-5, #c5c5c5));
|
||||
}
|
||||
.t-button--default.t-button--disabled {
|
||||
color: var(--td-button-default-disabled-color, var(--td-font-gray-4, rgba(0, 0, 0, 0.26)));
|
||||
background-color: var(--td-button-default-disabled-bg, var(--td-gray-color-2, #eeeeee));
|
||||
}
|
||||
.t-button--default.t-button--disabled::after {
|
||||
border-color: var(--td-button-default-disabled-border-color, var(--td-gray-color-2, #eeeeee));
|
||||
}
|
||||
.t-button--primary {
|
||||
color: var(--td-button-primary-color, var(--td-text-anti-primary-color, #fff));
|
||||
background-color: var(--td-button-primary-bg-color, var(--td-primary-color, #0052d9));
|
||||
}
|
||||
.t-button--primary::after {
|
||||
border-width: var(--td-button-border-width, 4rpx);
|
||||
border-color: var(--td-button-primary-border-color, var(--td-primary-color, #0052d9));
|
||||
}
|
||||
.t-button--primary.t-button--hover {
|
||||
z-index: 0;
|
||||
}
|
||||
.t-button--primary.t-button--hover::after {
|
||||
background-color: var(--td-button-primary-active-bg-color, var(--td-primary-color-9, #0034b5));
|
||||
}
|
||||
.t-button--primary.t-button--disabled {
|
||||
color: var(--td-button-primary-disabled-color, var(--td-text-anti-primary-color, #fff));
|
||||
background-color: var(--td-button-primary-disabled-bg, var(--td-primary-color-3, #bbd3fb));
|
||||
}
|
||||
.t-button--primary.t-button--disabled::after {
|
||||
border-color: var(--td-button-primary-disabled-border-color, var(--td-primary-color-3, #bbd3fb));
|
||||
}
|
||||
.t-button--light {
|
||||
color: var(--td-button-light-color, var(--td-primary-color, #0052d9));
|
||||
background-color: var(--td-button-light-bg-color, var(--td-primary-color-1, #ecf2fe));
|
||||
}
|
||||
.t-button--light::after {
|
||||
border-width: var(--td-button-border-width, 4rpx);
|
||||
border-color: var(--td-button-light-border-color, var(--td-primary-color-1, #ecf2fe));
|
||||
}
|
||||
.t-button--light.t-button--hover {
|
||||
z-index: 0;
|
||||
}
|
||||
.t-button--light.t-button--hover::after {
|
||||
background-color: var(--td-button-light-active-bg-color, var(--td-primary-color-2, #d4e3fc));
|
||||
}
|
||||
.t-button--light.t-button--disabled {
|
||||
color: var(--td-button-light-disabled-color, var(--td-primary-color-3, #bbd3fb));
|
||||
background-color: var(--td-button-light-disabled-bg, var(--td-primary-color-1, #ecf2fe));
|
||||
}
|
||||
.t-button--light.t-button--disabled::after {
|
||||
border-color: var(--td-button-light-disabled-border-color, var(--td-primary-color-1, #ecf2fe));
|
||||
}
|
||||
.t-button--gdxz {
|
||||
color: var(--td-button-danger-color, var(--td-text-anti-primary-color, #fff));
|
||||
background-color: var(--td-button-danger-bg-color, var(--td-error-color, var(--td-error-color-6, #3CC7C0)));
|
||||
}
|
||||
.t-button--danger {
|
||||
color: var(--td-button-danger-color, var(--td-text-anti-primary-color, #fff));
|
||||
background-color: var(--td-button-danger-bg-color, var(--td-error-color, var(--td-error-color-6, #e34d59)));
|
||||
}
|
||||
.t-button--danger::after {
|
||||
border-width: var(--td-button-border-width, 4rpx);
|
||||
border-color: var(--td-button-danger-border-color, var(--td-error-color, var(--td-error-color-6, #e34d59)));
|
||||
}
|
||||
.t-button--danger.t-button--hover {
|
||||
z-index: 0;
|
||||
}
|
||||
.t-button--danger.t-button--hover::after {
|
||||
background-color: var(--td-button-danger-active-bg-color, var(--td-error-color-7, #c9353f));
|
||||
}
|
||||
.t-button--danger.t-button--disabled {
|
||||
color: var(--td-button-danger-disabled-color, var(--td-text-anti-primary-color, #fff));
|
||||
background-color: var(--td-button-danger-disabled-bg, var(--td-error-color-3, #f8b9be));
|
||||
}
|
||||
.t-button--danger.t-button--disabled::after {
|
||||
border-color: var(--td-button-danger-disabled-border-color, var(--td-error-color-3, #f8b9be));
|
||||
}
|
||||
.t-button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
background-image: none;
|
||||
transition: all 0.3s;
|
||||
touch-action: manipulation;
|
||||
border-radius: var(--td-button-border-radius, var(--td-radius-default, 12rpx));
|
||||
outline: none;
|
||||
font-family: PingFang SC, Microsoft YaHei, Arial Regular;
|
||||
font-weight: var(--td-button-font-weight, 600);
|
||||
cursor: pointer;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
/* stylelint-disable-next-line */
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
.t-button::after {
|
||||
border-radius: calc(var(--td-button-border-radius, var(--td-radius-default, 12rpx)) * 2);
|
||||
}
|
||||
.t-button--text {
|
||||
color: var(--td-button-default-color, var(--td-font-gray-1, rgba(0, 0, 0, 0.9)));
|
||||
background: none;
|
||||
}
|
||||
.t-button--text::after {
|
||||
border: 0;
|
||||
}
|
||||
.t-button--text.t-button--hover::after {
|
||||
background-color: var(--td-button-text-active-bg-color, var(--td-primary-color-1, #ecf2fe));
|
||||
}
|
||||
.t-button--text.t-button--primary {
|
||||
color: var(--td-button-primary-text-color, var(--td-primary-color, #0052d9));
|
||||
background: none;
|
||||
}
|
||||
.t-button--text.t-button--primary.t-button--disabled {
|
||||
color: var(--td-button-primary-text-disabled-color, var(--td-primary-color-3, #bbd3fb));
|
||||
background: none;
|
||||
}
|
||||
.t-button--text.t-button--danger {
|
||||
color: var(--td-button-danger-text-color, var(--td-error-color, var(--td-error-color-6, #e34d59)));
|
||||
background: none;
|
||||
}
|
||||
.t-button--text.t-button--danger.t-button--disabled {
|
||||
color: var(--td-button-danger-text-disabled-color, var(--td-button-danger-disabled-color, var(--td-text-anti-primary-color, #fff)));
|
||||
background: none;
|
||||
}
|
||||
.t-button--text.t-button--light {
|
||||
color: var(--td-button-light-text-color, var(--td-primary-color, #0052d9));
|
||||
background: none;
|
||||
}
|
||||
.t-button--text.t-button--disabled {
|
||||
color: var(--td-button-default-disabled-color, var(--td-font-gray-4, rgba(0, 0, 0, 0.26)));
|
||||
}
|
||||
.t-button--ghost {
|
||||
background-color: transparent;
|
||||
color: var(--td-button-ghost-color, var(--td-bg-color-block, #fff));
|
||||
}
|
||||
.t-button--ghost::after {
|
||||
border-color: var(--td-button-ghost-border-color, var(--td-button-ghost-color, var(--td-bg-color-block, #fff)));
|
||||
}
|
||||
.t-button--ghost.t-button--hover::after {
|
||||
background: none;
|
||||
}
|
||||
.t-button--ghost.t-button--primary {
|
||||
color: var(--td-button-ghost-primary-color, var(--td-primary-color, #0052d9));
|
||||
}
|
||||
.t-button--ghost.t-button--primary::after {
|
||||
border-color: var(--td-button-ghost-primary-border-color, var(--td-primary-color, #0052d9));
|
||||
}
|
||||
.t-button--ghost.t-button--danger {
|
||||
color: var(--td-button-ghost-danger-color, var(--td-error-color, var(--td-error-color-6, #e34d59)));
|
||||
}
|
||||
.t-button--ghost.t-button--danger::after {
|
||||
border-color: var(--td-button-ghost-danger-border-color, var(--td-error-color, var(--td-error-color-6, #e34d59)));
|
||||
}
|
||||
.t-button--ghost.t-button--disabled {
|
||||
background-color: transparent;
|
||||
color: var(--td-button-ghost-disabled-color, rgba(255, 255, 255, 0.35));
|
||||
}
|
||||
.t-button--ghost.t-button--disabled::after {
|
||||
border-color: var(--td-button-ghost-disabled-color, rgba(255, 255, 255, 0.35));
|
||||
}
|
||||
.t-button--outline {
|
||||
background-color: transparent;
|
||||
}
|
||||
.t-button--outline::after {
|
||||
border-color: var(--td-button-default-border-color, var(--td-gray-color-3, #e7e7e7));
|
||||
}
|
||||
.t-button--outline.t-button--hover::after {
|
||||
background-color: var(--td-button-outline-active-bg-color, var(--td-gray-color-1, #f3f3f3));
|
||||
}
|
||||
.t-button--outline.t-button--primary {
|
||||
color: var(--td-button-primary-outline-color, var(--td-primary-color, #0052d9));
|
||||
}
|
||||
.t-button--outline.t-button--primary::after {
|
||||
border-color: var(--td-button-primary-outline-border-color, var(--td-button-primary-outline-color, var(--td-primary-color, #0052d9)));
|
||||
}
|
||||
.t-button--outline.t-button--primary.t-button--disabled {
|
||||
background-color: transparent;
|
||||
color: var(--td-button-primary-outline-disabled-color, var(--td-primary-color-3, #bbd3fb));
|
||||
}
|
||||
.t-button--outline.t-button--primary.t-button--disabled::after {
|
||||
border-color: var(--td-button-primary-outline-disabled-color, var(--td-primary-color-3, #bbd3fb));
|
||||
}
|
||||
.t-button--outline.t-button--danger {
|
||||
color: var(--td-button-danger-outline-color, var(--td-error-color, var(--td-error-color-6, #e34d59)));
|
||||
}
|
||||
.t-button--outline.t-button--danger::after {
|
||||
border-color: var(--td-button-danger-outline-border-color, var(--td-button-danger-outline-color, var(--td-error-color, var(--td-error-color-6, #e34d59))));
|
||||
}
|
||||
.t-button--outline.t-button--danger.t-button--disabled {
|
||||
background-color: transparent;
|
||||
color: var(--td-button-danger-outline-disabled-color, var(--td-button-danger-disabled-color, var(--td-text-anti-primary-color, #fff)));
|
||||
}
|
||||
.t-button--outline.t-button--danger.t-button--disabled::after {
|
||||
border-color: var(--td-button-danger-outline-disabled-color, var(--td-button-danger-disabled-color, var(--td-text-anti-primary-color, #fff)));
|
||||
}
|
||||
.t-button--outline.t-button--light {
|
||||
color: var(--td-button-light-outline-color, var(--td-primary-color, #0052d9));
|
||||
background-color: var(--td-button-light-outline-bg-color, var(--td-primary-color-1, #ecf2fe));
|
||||
}
|
||||
.t-button--outline.t-button--light::after {
|
||||
border-color: var(--td-button-light-outline-border-color, var(--td-button-light-outline-color, var(--td-primary-color, #0052d9)));
|
||||
}
|
||||
.t-button--outline.t-button--light.t-button--disabled {
|
||||
background-color: transparent;
|
||||
color: var(--td-button-light-outline-disabled-color, var(--td-primary-color-3, #bbd3fb));
|
||||
}
|
||||
.t-button--outline.t-button--light.t-button--disabled::after {
|
||||
border-color: var(--td-button-light-outline-disabled-color, var(--td-primary-color-3, #bbd3fb));
|
||||
}
|
||||
.t-button--dashed {
|
||||
background-color: transparent;
|
||||
border-style: dashed;
|
||||
}
|
||||
.t-button--dashed.t-button--primary {
|
||||
color: var(--td-button-primary-dashed-color, var(--td-primary-color, #0052d9));
|
||||
}
|
||||
.t-button--dashed.t-button--primary::after {
|
||||
border-color: var(--td-button-primary-dashed-border-color, var(--td-button-primary-dashed-color, var(--td-primary-color, #0052d9)));
|
||||
}
|
||||
.t-button--dashed.t-button--primary.t-button--disabled {
|
||||
background-color: transparent;
|
||||
color: var(--td-button-primary-dashed-disabled-color, var(--td-primary-color-3, #bbd3fb));
|
||||
}
|
||||
.t-button--dashed.t-button--primary.t-button--disabled::after {
|
||||
border-color: var(--td-button-primary-dashed-disabled-color, var(--td-primary-color-3, #bbd3fb));
|
||||
}
|
||||
.t-button--dashed.t-button--danger {
|
||||
color: var(--td-button-danger-dashed-color, var(--td-error-color, var(--td-error-color-6, #e34d59)));
|
||||
}
|
||||
.t-button--dashed.t-button--danger::after {
|
||||
border-color: var(--td-button-danger-dashed-border-color, var(--td-button-danger-dashed-color, var(--td-error-color, var(--td-error-color-6, #e34d59))));
|
||||
}
|
||||
.t-button--dashed.t-button--danger.t-button--disabled {
|
||||
background-color: transparent;
|
||||
color: var(--td-button-danger-dashed-disabled-color, var(--td-button-danger-disabled-color, var(--td-text-anti-primary-color, #fff)));
|
||||
}
|
||||
.t-button--dashed.t-button--danger.t-button--disabled::after {
|
||||
border-color: var(--td-button-danger-dashed-disabled-color, var(--td-button-danger-disabled-color, var(--td-text-anti-primary-color, #fff)));
|
||||
}
|
||||
.t-button__loading + .t-button__content:not(:empty),
|
||||
.t-button__icon + .t-button__content:not(:empty) {
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
.t-button__icon {
|
||||
border-radius: var(--td-button-icon-border-radius, 8rpx);
|
||||
}
|
||||
.t-button--round.t-button--size-large {
|
||||
border-radius: calc(var(--td-button-large-height, 96rpx) / 2);
|
||||
}
|
||||
.t-button--round.t-button--size-medium {
|
||||
border-radius: calc(var(--td-button-medium-height, 80rpx) / 2);
|
||||
}
|
||||
.t-button--round.t-button--size-small {
|
||||
border-radius: calc(var(--td-button-small-height, 64rpx) / 2);
|
||||
}
|
||||
.t-button--round.t-button--size-extra-small {
|
||||
border-radius: calc(28px / 2);
|
||||
}
|
||||
.t-button--square {
|
||||
padding: 0;
|
||||
}
|
||||
.t-button--square.t-button--size-large {
|
||||
width: var(--td-button-large-height, 96rpx);
|
||||
}
|
||||
.t-button--square.t-button--size-medium {
|
||||
width: var(--td-button-medium-height, 80rpx);
|
||||
}
|
||||
.t-button--square.t-button--size-small {
|
||||
width: var(--td-button-small-height, 64rpx);
|
||||
}
|
||||
.t-button--square.t-button--size-extra-small {
|
||||
width: 28px;
|
||||
}
|
||||
.t-button--circle {
|
||||
padding: 0;
|
||||
}
|
||||
.t-button--circle.t-button--size-large {
|
||||
border-radius: 50%;
|
||||
width: var(--td-button-large-height, 96rpx);
|
||||
}
|
||||
.t-button--circle.t-button--size-medium {
|
||||
border-radius: 50%;
|
||||
width: var(--td-button-medium-height, 80rpx);
|
||||
}
|
||||
.t-button--circle.t-button--size-small {
|
||||
border-radius: 50%;
|
||||
width: var(--td-button-small-height, 64rpx);
|
||||
}
|
||||
.t-button--circle.t-button--size-extra-small {
|
||||
border-radius: 50%;
|
||||
width: 28px;
|
||||
}
|
||||
.t-button--block {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
.t-button--disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.t-button__loading--wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.t-button__loading--indicator {
|
||||
color: var(--td-white-color-1, #fff);
|
||||
}
|
||||
.t-button.t-button--hover::after {
|
||||
z-index: -1;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from './props';
|
||||
export * from './type';
|
||||
export * from './button';
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from './props';
|
||||
export * from './type';
|
||||
export * from './button';
|
||||
@@ -0,0 +1,3 @@
|
||||
import { TdButtonProps } from './type';
|
||||
declare const props: TdButtonProps;
|
||||
export default props;
|
||||
@@ -0,0 +1,100 @@
|
||||
const props = {
|
||||
block: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
content: {
|
||||
type: String,
|
||||
},
|
||||
customDataset: {
|
||||
type: null,
|
||||
},
|
||||
customStyle: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
externalClasses: {
|
||||
type: Array,
|
||||
},
|
||||
ghost: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
icon: {
|
||||
type: null,
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
loadingProps: {
|
||||
type: Object,
|
||||
},
|
||||
shape: {
|
||||
type: String,
|
||||
value: 'rectangle',
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
value: 'medium',
|
||||
},
|
||||
theme: {
|
||||
type: String,
|
||||
value: 'default',
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
},
|
||||
variant: {
|
||||
type: String,
|
||||
value: 'base',
|
||||
},
|
||||
openType: {
|
||||
type: String,
|
||||
},
|
||||
hoverStopPropagation: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
hoverStartTime: {
|
||||
type: Number,
|
||||
value: 20,
|
||||
},
|
||||
hoverStayTime: {
|
||||
type: Number,
|
||||
value: 70,
|
||||
},
|
||||
lang: {
|
||||
type: String,
|
||||
value: 'en',
|
||||
},
|
||||
sessionFrom: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
sendMessageTitle: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
sendMessagePath: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
sendMessageImg: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
appParameter: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
showMessageCard: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
};
|
||||
export default props;
|
||||
@@ -0,0 +1,108 @@
|
||||
import { LoadingProps } from '../loading/index';
|
||||
import { SizeEnum } from '../common/common';
|
||||
export interface TdButtonProps {
|
||||
block?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
content?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
customDataset?: {
|
||||
type: ObjectConstructor;
|
||||
value?: any;
|
||||
};
|
||||
customStyle?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
disabled?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
externalClasses?: {
|
||||
type: ArrayConstructor;
|
||||
value?: ['t-class', 't-class-icon', 't-class-loading'];
|
||||
};
|
||||
ghost?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
icon?: {
|
||||
type: null;
|
||||
value?: string | object;
|
||||
};
|
||||
loading?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
loadingProps?: {
|
||||
type: ObjectConstructor;
|
||||
value?: LoadingProps;
|
||||
};
|
||||
shape?: {
|
||||
type: StringConstructor;
|
||||
value?: 'rectangle' | 'square' | 'round' | 'circle';
|
||||
};
|
||||
size?: {
|
||||
type: StringConstructor;
|
||||
value?: SizeEnum;
|
||||
};
|
||||
theme?: {
|
||||
type: StringConstructor;
|
||||
value?: 'default' | 'primary' | 'danger' | 'gdxz';
|
||||
};
|
||||
type?: {
|
||||
type: StringConstructor;
|
||||
value?: 'submit' | 'reset';
|
||||
};
|
||||
variant?: {
|
||||
type: StringConstructor;
|
||||
value?: 'base' | 'outline' | 'text';
|
||||
};
|
||||
openType?: {
|
||||
type: StringConstructor;
|
||||
value?: 'contact' | 'share' | 'getPhoneNumber' | 'getUserInfo' | 'launchApp' | 'openSetting' | 'feedback' | 'chooseAvatar';
|
||||
};
|
||||
hoverStopPropagation?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
hoverStartTime?: {
|
||||
type: NumberConstructor;
|
||||
value?: number;
|
||||
};
|
||||
hoverStayTime?: {
|
||||
type: NumberConstructor;
|
||||
value?: number;
|
||||
};
|
||||
lang?: {
|
||||
type: StringConstructor;
|
||||
value?: 'en' | 'zh_CN' | 'zh_TW';
|
||||
};
|
||||
sessionFrom?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
sendMessageTitle?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
sendMessagePath?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
sendMessageImg?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
appParameter?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
showMessageCard?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export {};
|
||||
@@ -0,0 +1,17 @@
|
||||
:: BASE_DOC ::
|
||||
|
||||
## API
|
||||
### Cascader Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
close-btn | Boolean / Slot | true | \- | N
|
||||
keys | Object | - | Typescript:`KeysType` | N
|
||||
custom-style `v0.25.0` | String | - | \- | N
|
||||
options | Array | [] | Typescript:`Array<CascaderOption>` | N
|
||||
sub-titles | Array | [] | Typescript:`Array<string>` | N
|
||||
theme | String | 'step' | options:step/tab | N
|
||||
title | String / Slot | - | \- | N
|
||||
value | String / Number | null | \- | N
|
||||
default-value | String / Number | undefined | uncontrolled property | N
|
||||
visible | Boolean | false | \- | N
|
||||
@@ -0,0 +1,63 @@
|
||||
---
|
||||
title: Cascader 级联选择器
|
||||
description: 级联选择器适用于有清晰层级结构的数据集合,用户可以通过逐级查看并选择。
|
||||
spline: form
|
||||
isComponent: true
|
||||
---
|
||||
|
||||
<div style="background: #ecf2fe; display: flex; align-items: center; line-height: 20px; padding: 14px 24px; border-radius: 3px; color: #555a65">
|
||||
<svg fill="none" viewBox="0 0 16 16" width="16px" height="16px" style="margin-right: 5px">
|
||||
<path fill="#0052d9" d="M8 15A7 7 0 108 1a7 7 0 000 14zM7.4 4h1.2v1.2H7.4V4zm.1 2.5h1V12h-1V6.5z" fillOpacity="0.9"></path>
|
||||
</svg>
|
||||
该组件于 0.23.0 版本上线,请留意版本。
|
||||
</div>
|
||||
|
||||
## 引入
|
||||
|
||||
全局引入,在 miniprogram 根目录下的`app.json`中配置,局部引入,在需要引入的页面或组件的`index.json`中配置。
|
||||
|
||||
```json
|
||||
"usingComponents": {
|
||||
"t-cascader": "tdesign-miniprogram/cascader/cascader"
|
||||
}
|
||||
```
|
||||
|
||||
## 代码演示
|
||||
|
||||
### 基础用法
|
||||
|
||||
{{ base }}
|
||||
|
||||
### 选项卡风格
|
||||
|
||||
{{ theme-tab }}
|
||||
|
||||
### 进阶
|
||||
|
||||
#### 带初始值
|
||||
|
||||
{{ with-value }}
|
||||
|
||||
#### 自定义 keys
|
||||
|
||||
{{ keys }}
|
||||
|
||||
#### 使用次级标题
|
||||
|
||||
{{ with-title }}
|
||||
|
||||
## API
|
||||
### Cascader Props
|
||||
|
||||
名称 | 类型 | 默认值 | 说明 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
close-btn | Boolean / Slot | true | 关闭按钮 | N
|
||||
keys | Object | - | 用来定义 value / label 在 `options` 中对应的字段别名。TS 类型:`KeysType` | N
|
||||
custom-style `v0.25.0` | String | - | 自定义组件样式 | N
|
||||
options | Array | [] | 可选项数据源。TS 类型:`Array<CascaderOption>` | N
|
||||
sub-titles | Array | [] | 每级展示的次标题。TS 类型:`Array<string>` | N
|
||||
theme | String | 'step' | 展示风格。可选项:step/tab | N
|
||||
title | String / Slot | - | 标题 | N
|
||||
value | String / Number | null | 选项值 | N
|
||||
default-value | String / Number | undefined | 选项值。非受控属性 | N
|
||||
visible | Boolean | false | 是否展示 | N
|
||||
@@ -0,0 +1,33 @@
|
||||
import { SuperComponent } from '../common/src/index';
|
||||
import { TdCascaderProps } from './type';
|
||||
export interface CascaderProps extends TdCascaderProps {
|
||||
}
|
||||
export default class Cascader extends SuperComponent {
|
||||
externalClasses: string[];
|
||||
properties: TdCascaderProps<import("../common/common").TreeOptionData>;
|
||||
data: {
|
||||
prefix: string;
|
||||
name: string;
|
||||
stepIndex: number;
|
||||
selectedIndexes: any[];
|
||||
selectedValue: any[];
|
||||
defaultOptionLabel: string;
|
||||
scrollTopList: any[];
|
||||
steps: string[];
|
||||
};
|
||||
observers: {
|
||||
visible(v: any): void;
|
||||
'value, options'(): void;
|
||||
'selectedIndexes, options'(): void;
|
||||
stepIndex(): Promise<void>;
|
||||
};
|
||||
methods: {
|
||||
initWithValue(): void;
|
||||
getIndexesByValue(options: import("../common/common").TreeOptionData[], value: any): any[];
|
||||
updateScrollTop(): void;
|
||||
hide(): void;
|
||||
onStepClick(e: any): void;
|
||||
onTabChange(e: any): void;
|
||||
handleSelect(e: any): void;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
import { SuperComponent, wxComponent } from '../common/src/index';
|
||||
import config from '../common/config';
|
||||
import props from './props';
|
||||
import { getRect } from '../common/utils';
|
||||
const { prefix } = config;
|
||||
const name = `${prefix}-cascader`;
|
||||
const defaultOptionLabel = '选择选项';
|
||||
let Cascader = class Cascader extends SuperComponent {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.externalClasses = [`${prefix}-class`];
|
||||
this.properties = props;
|
||||
this.data = {
|
||||
prefix,
|
||||
name,
|
||||
stepIndex: 0,
|
||||
selectedIndexes: [],
|
||||
selectedValue: [],
|
||||
defaultOptionLabel,
|
||||
scrollTopList: [],
|
||||
steps: [defaultOptionLabel],
|
||||
};
|
||||
this.observers = {
|
||||
visible(v) {
|
||||
if (v) {
|
||||
const $tabs = this.selectComponent('#tabs');
|
||||
$tabs === null || $tabs === void 0 ? void 0 : $tabs.setTrack();
|
||||
this.updateScrollTop();
|
||||
}
|
||||
},
|
||||
'value, options'() {
|
||||
this.initWithValue();
|
||||
},
|
||||
'selectedIndexes, options'() {
|
||||
var _a, _b, _c, _d;
|
||||
const { options, selectedIndexes, keys } = this.data;
|
||||
const selectedValue = [];
|
||||
const steps = [];
|
||||
const items = [options];
|
||||
if (options.length > 0) {
|
||||
for (let i = 0, size = selectedIndexes.length; i < size; i += 1) {
|
||||
const index = selectedIndexes[i];
|
||||
const next = items[i][index];
|
||||
selectedValue.push(next[(_a = keys === null || keys === void 0 ? void 0 : keys.value) !== null && _a !== void 0 ? _a : 'value']);
|
||||
steps.push(next[(_b = keys === null || keys === void 0 ? void 0 : keys.label) !== null && _b !== void 0 ? _b : 'label']);
|
||||
if (next[(_c = keys === null || keys === void 0 ? void 0 : keys.children) !== null && _c !== void 0 ? _c : 'children']) {
|
||||
items.push(next[(_d = keys === null || keys === void 0 ? void 0 : keys.children) !== null && _d !== void 0 ? _d : 'children']);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (steps.length < items.length) {
|
||||
steps.push(defaultOptionLabel);
|
||||
}
|
||||
this.setData({
|
||||
steps,
|
||||
items,
|
||||
selectedValue,
|
||||
stepIndex: items.length - 1,
|
||||
});
|
||||
},
|
||||
stepIndex() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const { visible } = this.data;
|
||||
if (visible) {
|
||||
this.updateScrollTop();
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
this.methods = {
|
||||
initWithValue() {
|
||||
if (this.data.value != null) {
|
||||
const selectedIndexes = this.getIndexesByValue(this.data.options, this.data.value);
|
||||
if (selectedIndexes) {
|
||||
this.setData({ selectedIndexes });
|
||||
}
|
||||
}
|
||||
},
|
||||
getIndexesByValue(options, value) {
|
||||
var _a, _b, _c;
|
||||
const { keys } = this.data;
|
||||
for (let i = 0, size = options.length; i < size; i += 1) {
|
||||
const opt = options[i];
|
||||
if (opt[(_a = keys === null || keys === void 0 ? void 0 : keys.value) !== null && _a !== void 0 ? _a : 'value'] === value) {
|
||||
return [i];
|
||||
}
|
||||
if (opt[(_b = keys === null || keys === void 0 ? void 0 : keys.children) !== null && _b !== void 0 ? _b : 'children']) {
|
||||
const res = this.getIndexesByValue(opt[(_c = keys === null || keys === void 0 ? void 0 : keys.children) !== null && _c !== void 0 ? _c : 'children'], value);
|
||||
if (res) {
|
||||
return [i, ...res];
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
updateScrollTop() {
|
||||
const { visible, items, selectedIndexes, stepIndex } = this.data;
|
||||
if (visible) {
|
||||
getRect(this, '.cascader-radio-group-0').then((rect) => {
|
||||
var _a;
|
||||
const eachRadioHeight = rect.height / ((_a = items[0]) === null || _a === void 0 ? void 0 : _a.length);
|
||||
this.setData({
|
||||
[`scrollTopList[${stepIndex}]`]: eachRadioHeight * selectedIndexes[stepIndex],
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
hide(e) {
|
||||
this.setData({ visible: false });
|
||||
if(e != false){
|
||||
this.triggerEvent('close');
|
||||
}
|
||||
},
|
||||
onStepClick(e) {
|
||||
const { index } = e.currentTarget.dataset;
|
||||
this.setData({ stepIndex: index });
|
||||
},
|
||||
onTabChange(e) {
|
||||
const { value } = e.detail;
|
||||
this.setData({
|
||||
stepIndex: value,
|
||||
});
|
||||
},
|
||||
handleSelect(e) {
|
||||
var _a, _b, _c;
|
||||
const { level } = e.target.dataset;
|
||||
const { value } = e.detail;
|
||||
const { selectedIndexes, items, keys } = this.data;
|
||||
const index = items[level].findIndex((item) => { var _a; return item[(_a = keys === null || keys === void 0 ? void 0 : keys.value) !== null && _a !== void 0 ? _a : 'value'] === value; });
|
||||
const item = items[level][index];
|
||||
if (item.disabled) {
|
||||
return;
|
||||
}
|
||||
selectedIndexes[level] = index;
|
||||
selectedIndexes.length = level + 1;
|
||||
this.triggerEvent('pick', item[(_a = keys === null || keys === void 0 ? void 0 : keys.value) !== null && _a !== void 0 ? _a : 'value'], index);
|
||||
if ((_c = item === null || item === void 0 ? void 0 : item[(_b = keys === null || keys === void 0 ? void 0 : keys.children) !== null && _b !== void 0 ? _b : 'children']) === null || _c === void 0 ? void 0 : _c.length) {
|
||||
this.setData({ selectedIndexes });
|
||||
}
|
||||
else {
|
||||
this.setData({ selectedIndexes }, () => {
|
||||
var _a;
|
||||
const { items } = this.data;
|
||||
this.triggerEvent('change', {
|
||||
value: item[(_a = keys === null || keys === void 0 ? void 0 : keys.value) !== null && _a !== void 0 ? _a : 'value'],
|
||||
selectedOptions: items.map((item, index) => item[selectedIndexes[index]]),
|
||||
});
|
||||
});
|
||||
this.hide(false);
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
Cascader = __decorate([
|
||||
wxComponent()
|
||||
], Cascader);
|
||||
export default Cascader;
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"t-icon": "../icon/icon",
|
||||
"t-popup": "../popup/popup",
|
||||
"t-tabs": "../tabs/tabs",
|
||||
"t-tab-panel": "../tab-panel/tab-panel",
|
||||
"t-radio-group": "../radio-group/radio-group"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<t-popup visible="{{visible}}" placement="bottom" bind:visible-change="hide">
|
||||
<view style="{{ customStyle }}" class="{{name}}">
|
||||
<view class="{{name}}__title">
|
||||
<slot name="title" />
|
||||
{{title}}
|
||||
</view>
|
||||
<view class="{{name}}__close-btn" bind:tap="hide">
|
||||
<slot name="close-btn" />
|
||||
<t-icon wx:if="{{closeBtn}}" size="24" name="close" />
|
||||
</view>
|
||||
<view class="{{name}}__content">
|
||||
<block wx:if="{{steps && steps.length}}">
|
||||
<view wx:if="{{theme == 'step'}}" class="{{name}}__steps">
|
||||
<view wx:for="{{steps}}" wx:key="index" class="{{name}}__step" bind:tap="onStepClick" data-index="{{index}}">
|
||||
<view
|
||||
class="{{name}}__step-dot {{name}}__step-dot--{{item !== defaultOptionLabel ? 'active' : ''}} {{name}}__step-dot--{{index === steps.length - 1 ? 'last' : ''}}"
|
||||
></view>
|
||||
<view class="{{name}}__step-label {{name}}__step-label--{{index === stepIndex ? 'active' : ''}}">
|
||||
{{ item }}
|
||||
</view>
|
||||
<t-icon name="chevron-right" size="22" class="{{name}}__step-arrow" />
|
||||
</view>
|
||||
</view>
|
||||
<block wx:if="{{theme == 'tab'}}">
|
||||
<t-tabs id="tabs" value="{{stepIndex}}" bind:change="onTabChange" space-evenly="{{false}}">
|
||||
<t-tab-panel wx:for="{{steps}}" wx:key="index" value="{{index}}" label="{{item}}" />
|
||||
</t-tabs>
|
||||
</block>
|
||||
</block>
|
||||
<view wx:if="{{ subTitles && subTitles[stepIndex] }}" class="{{name}}__options-title"
|
||||
>{{subTitles[stepIndex]}}</view
|
||||
>
|
||||
<view
|
||||
class="{{name}}__options-container"
|
||||
style="width: {{items.length + 1}}00vw; transform: translateX(-{{stepIndex}}00vw)"
|
||||
>
|
||||
<scroll-view
|
||||
wx:for="{{items}}"
|
||||
wx:for-item="options"
|
||||
wx:key="index"
|
||||
class="{{name}}__options"
|
||||
scroll-y
|
||||
scroll-top="{{scrollTopList[index]}}"
|
||||
>
|
||||
<t-radio-group
|
||||
class="cascader-radio-group-{{index}}"
|
||||
value="{{selectedValue[index]}}"
|
||||
keys="{{keys}}"
|
||||
options="{{options}}"
|
||||
bind:change="handleSelect"
|
||||
data-level="{{index}}"
|
||||
align="right"
|
||||
icon="line"
|
||||
borderless
|
||||
>
|
||||
</t-radio-group>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</t-popup>
|
||||
@@ -0,0 +1,136 @@
|
||||
.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-cascader {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #fff;
|
||||
color: var(--td-cascader-title-color, var(--td-text-level-1-color, #000000));
|
||||
border-radius: 24rpx 24rpx 0 0;
|
||||
--td-radio-icon-checked-color: var(--td-cascader-active-color, var(--td-primary-color, #0052d9));
|
||||
--td-tab-item-active-color: var(--td-cascader-active-color, var(--td-primary-color, #0052d9));
|
||||
--td-tab-track-color: var(--td-cascader-active-color, var(--td-primary-color, #0052d9));
|
||||
}
|
||||
.t-cascader__close-btn {
|
||||
right: 16px;
|
||||
top: 12px;
|
||||
position: absolute;
|
||||
}
|
||||
.t-cascader__title {
|
||||
position: relative;
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
line-height: 48px;
|
||||
font-size: var(--td-cascder-title-font-size, 36rpx);
|
||||
}
|
||||
.t-cascader__content {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.t-cascader__options {
|
||||
width: 100vw;
|
||||
height: var(--td-cascader-options-height, 640rpx);
|
||||
}
|
||||
.t-cascader__options-title {
|
||||
margin-top: 40rpx;
|
||||
color: var(--td-cascader-options-title-color, var(--td-text-placeholder-color, rgba(0, 0, 0, 0.4)));
|
||||
font-size: 28rpx;
|
||||
line-height: 44rpx;
|
||||
padding-left: 16px;
|
||||
}
|
||||
.t-cascader__options-content {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
padding-left: 16px;
|
||||
}
|
||||
.t-cascader__options-container {
|
||||
display: flex;
|
||||
transition: all ease 0.3s;
|
||||
}
|
||||
.t-cascader__step {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: var(--td-cascader-step-height, 88rpx);
|
||||
}
|
||||
.t-cascader__steps {
|
||||
padding: 0 32rpx 10rpx;
|
||||
position: relative;
|
||||
}
|
||||
.t-cascader__steps::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: unset;
|
||||
bottom: 0;
|
||||
left: unset;
|
||||
right: unset;
|
||||
background-color: var(--td-cascader-border-color, var(--td-border-level-1-color, #e6e6e6));
|
||||
}
|
||||
.t-cascader__steps::after {
|
||||
height: 1px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
.t-cascader__step-dot {
|
||||
position: relative;
|
||||
width: var(--td-cascader-step-dot-size, 16rpx);
|
||||
height: var(--td-cascader-step-dot-size, 16rpx);
|
||||
border-radius: 50%;
|
||||
border: 1px solid var(--td-cascader-active-color, var(--td-primary-color, #0052d9));
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.t-cascader__step-dot:not(.t-cascader__step-dot--last)::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: calc(var(--td-cascader-step-dot-size, 16rpx) + 14rpx);
|
||||
height: 36rpx;
|
||||
width: 1px;
|
||||
background: var(--td-cascader-active-color, var(--td-primary-color, #0052d9));
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
.t-cascader__step-dot--active {
|
||||
background: var(--td-cascader-active-color, var(--td-primary-color, #0052d9));
|
||||
border-color: var(--td-cascader-active-color, var(--td-primary-color, #0052d9));
|
||||
}
|
||||
.t-cascader__step-label {
|
||||
padding-left: 16px;
|
||||
font-size: 16px;
|
||||
}
|
||||
.t-cascader__step-label--active {
|
||||
color: var(--td-cascader-active-color, var(--td-primary-color, #0052d9));
|
||||
font-weight: 600;
|
||||
}
|
||||
.t-cascader__step-arrow {
|
||||
color: var(--td-cascader-step-arrow-color, var(--td-text-placeholder-color, rgba(0, 0, 0, 0.4)));
|
||||
margin-left: auto;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import { TdCascaderProps } from './type';
|
||||
declare const props: TdCascaderProps;
|
||||
export default props;
|
||||
@@ -0,0 +1,41 @@
|
||||
const props = {
|
||||
closeBtn: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
keys: {
|
||||
type: Object,
|
||||
},
|
||||
customStyle: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
options: {
|
||||
type: Array,
|
||||
value: [],
|
||||
},
|
||||
subTitles: {
|
||||
type: Array,
|
||||
value: [],
|
||||
},
|
||||
theme: {
|
||||
type: String,
|
||||
value: 'step',
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
},
|
||||
value: {
|
||||
type: null,
|
||||
value: null,
|
||||
},
|
||||
defaultValue: {
|
||||
type: null,
|
||||
value: null,
|
||||
},
|
||||
visible: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
};
|
||||
export default props;
|
||||
@@ -0,0 +1,43 @@
|
||||
import { TreeOptionData, KeysType } from '../common/common';
|
||||
export interface TdCascaderProps<CascaderOption extends TreeOptionData = TreeOptionData> {
|
||||
closeBtn?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
keys?: {
|
||||
type: ObjectConstructor;
|
||||
value?: KeysType;
|
||||
};
|
||||
customStyle?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
options?: {
|
||||
type: ArrayConstructor;
|
||||
value?: Array<CascaderOption>;
|
||||
};
|
||||
subTitles?: {
|
||||
type: ArrayConstructor;
|
||||
value?: Array<string>;
|
||||
};
|
||||
theme?: {
|
||||
type: StringConstructor;
|
||||
value?: 'step' | 'tab';
|
||||
};
|
||||
title?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
value?: {
|
||||
type: null;
|
||||
value?: string | number;
|
||||
};
|
||||
defaultValue?: {
|
||||
type: null;
|
||||
value?: string | number;
|
||||
};
|
||||
visible?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export {};
|
||||
@@ -0,0 +1,12 @@
|
||||
:: BASE_DOC ::
|
||||
|
||||
## API
|
||||
### CellGroup Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
bordered | Boolean | - | \- | N
|
||||
custom-style `v0.25.0` | String | - | \- | N
|
||||
external-classes | Array | - | `['t-class']` | N
|
||||
theme | String | default | options:default/card | N
|
||||
title | String | - | \- | N
|
||||
@@ -0,0 +1,12 @@
|
||||
:: BASE_DOC ::
|
||||
|
||||
## API
|
||||
### CellGroup Props
|
||||
|
||||
名称 | 类型 | 默认值 | 说明 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
bordered | Boolean | - | 是否显示组边框 | N
|
||||
custom-style `v0.25.0` | String | - | 自定义组件样式 | N
|
||||
external-classes | Array | - | 组件类名。`['t-class']` | N
|
||||
theme | String | default | 单元格风格。可选项:default/card | N
|
||||
title | String | - | 单元格组标题 | N
|
||||
@@ -0,0 +1,12 @@
|
||||
import { SuperComponent } from '../common/src/index';
|
||||
export default class CellGroup extends SuperComponent {
|
||||
externalClasses: string[];
|
||||
options: {
|
||||
addGlobalClass: boolean;
|
||||
};
|
||||
properties: import("./type").TdCellGroupProps;
|
||||
data: {
|
||||
prefix: string;
|
||||
classPrefix: string;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
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}-cell-group`;
|
||||
let CellGroup = class CellGroup extends SuperComponent {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.externalClasses = [`${prefix}-class`, `${prefix}-class-title`];
|
||||
this.options = {
|
||||
addGlobalClass: true,
|
||||
};
|
||||
this.properties = props;
|
||||
this.data = {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
};
|
||||
}
|
||||
};
|
||||
CellGroup = __decorate([
|
||||
wxComponent()
|
||||
], CellGroup);
|
||||
export default CellGroup;
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"component": true
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<wxs src="../common/utils.wxs" module="_" />
|
||||
|
||||
<view wx:if="{{ title }}" class="{{ classPrefix }}__title {{prefix}}-class-title"> {{ title }} </view>
|
||||
<view style="{{ customStyle }}" class="{{_.cls(classPrefix, [[bordered, 'bordered'], theme])}} {{prefix}}-class">
|
||||
<slot />
|
||||
</view>
|
||||
@@ -0,0 +1,68 @@
|
||||
.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-cell-group {
|
||||
position: relative;
|
||||
}
|
||||
.t-cell-group__title {
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: var(--td-cell-group-title-font-size, 28rpx);
|
||||
color: var(--td-cell-group-title-color, var(--td-text-level-3-color, #888888));
|
||||
text-align: left;
|
||||
line-height: var(--td-cell-group-title-line-height, 90rpx);
|
||||
background-color: var(--td-cell-group-title-bg-color, var(--td-bg-color-fade, #fbfbfb));
|
||||
padding-left: var(--td-cell-group-title-padding-left, 32rpx);
|
||||
}
|
||||
.t-cell-group--bordered::before {
|
||||
position: absolute;
|
||||
box-sizing: border-box;
|
||||
content: ' ';
|
||||
pointer-events: none;
|
||||
right: 0;
|
||||
left: 0;
|
||||
top: 0;
|
||||
border-top: 1px solid var(--td-cell-group-border-color, var(--td-border-level-1-color, #e6e6e6));
|
||||
transform: scaleY(0.5);
|
||||
z-index: 1;
|
||||
}
|
||||
.t-cell-group--bordered::after {
|
||||
position: absolute;
|
||||
box-sizing: border-box;
|
||||
content: ' ';
|
||||
pointer-events: none;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
border-bottom: 1px solid var(--td-cell-group-border-color, var(--td-border-level-1-color, #e6e6e6));
|
||||
transform: scaleY(0.5);
|
||||
z-index: 1;
|
||||
}
|
||||
.t-cell-group--card {
|
||||
margin: 0 32rpx;
|
||||
border-radius: var(--td-radius-large, 18rpx);
|
||||
overflow: hidden;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import { TdCellGroupProps } from './type';
|
||||
declare const props: TdCellGroupProps;
|
||||
export default props;
|
||||
@@ -0,0 +1,21 @@
|
||||
const props = {
|
||||
bordered: {
|
||||
type: Boolean,
|
||||
},
|
||||
customStyle: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
externalClasses: {
|
||||
type: Array,
|
||||
},
|
||||
theme: {
|
||||
type: String,
|
||||
value: 'default',
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
};
|
||||
export default props;
|
||||
@@ -0,0 +1,22 @@
|
||||
export interface TdCellGroupProps {
|
||||
bordered?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
customStyle?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
externalClasses?: {
|
||||
type: ArrayConstructor;
|
||||
value?: ['t-class'];
|
||||
};
|
||||
theme?: {
|
||||
type: StringConstructor;
|
||||
value?: 'default' | 'card';
|
||||
};
|
||||
title?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export {};
|
||||
@@ -0,0 +1,28 @@
|
||||
:: BASE_DOC ::
|
||||
|
||||
## API
|
||||
### Cell Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
align | String | middle | options:top/middle/bottom | N
|
||||
arrow | Boolean | false | \- | N
|
||||
bordered | Boolean | true | \- | N
|
||||
custom-style `v0.25.0` | String | - | \- | N
|
||||
description | String / Slot | - | \- | N
|
||||
external-classes | Array | - | `['t-class', 't-class-title', 't-class-note', 't-class-description', 't-class-thumb', 't-class-hover', 't-class-left', 't-class-right']` | N
|
||||
hover | Boolean | - | \- | N
|
||||
image | String / Slot | - | \- | N
|
||||
jump-type | String | navigateTo | options:switchTab/reLaunch/redirectTo/navigateTo | N
|
||||
left-icon | String / Slot | - | \- | N
|
||||
note | String / Slot | - | \- | N
|
||||
required | Boolean | false | \- | N
|
||||
right-icon | String / Slot | - | \- | N
|
||||
title | String / Slot | - | \- | N
|
||||
url | String | - | \- | N
|
||||
|
||||
### Cell Events
|
||||
|
||||
name | params | description
|
||||
-- | -- | --
|
||||
click | - | \-
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
title: Cell 单元格
|
||||
description: 用于各个类别行的信息展示。
|
||||
spline: data
|
||||
isComponent: true
|
||||
---
|
||||
|
||||
<span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20lines-100%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20functions-100%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20statements-100%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20branches-100%25-blue" /></span>
|
||||
## 引入
|
||||
|
||||
全局引入,在 miniprogram 根目录下的`app.json`中配置,局部引入,在需要引入的页面或组件的`index.json`中配置。
|
||||
|
||||
```json
|
||||
"usingComponents": {
|
||||
"t-cell": "tdesign-miniprogram/cell/cell"
|
||||
}
|
||||
```
|
||||
|
||||
## 代码演示
|
||||
|
||||
### 类型
|
||||
|
||||
单行单元格
|
||||
|
||||
<img src="https://tdesign.gtimg.com/miniprogram/readme/cell-1.png" width="375px" height="50%">
|
||||
|
||||
{{ base }}
|
||||
|
||||
多行单元格
|
||||
|
||||
<img src="https://tdesign.gtimg.com/miniprogram/readme/cell-2.png" width="375px" height="50%">
|
||||
|
||||
{{ multiple }}
|
||||
|
||||
### 样式
|
||||
|
||||
卡片单元格
|
||||
|
||||
{{ theme }}
|
||||
|
||||
## API
|
||||
### Cell Props
|
||||
|
||||
名称 | 类型 | 默认值 | 说明 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
align | String | middle | 内容的对齐方式,默认居中对齐。可选项:top/middle/bottom | N
|
||||
arrow | Boolean | false | 是否显示右侧箭头 | N
|
||||
bordered | Boolean | true | 是否显示下边框 | N
|
||||
custom-style `v0.25.0` | String | - | 自定义组件样式 | N
|
||||
description | String / Slot | - | 下方内容描述 | N
|
||||
external-classes | Array | - | 组件类名,分别用于设置 组件外层类名、标题类名、下方描述内容类名、右侧说明文字类名、激活态类名、图片类名、左侧内容、左侧图标类名、右侧内容、右侧图标类名 等。`['t-class', 't-class-title', 't-class-description', 't-class-note', 't-class-hover', 't-class-image', 't-class-left', 't-class-left-icon', 't-class-right', 't-class-right-icon']` | N
|
||||
hover | Boolean | - | 是否开启点击反馈 | N
|
||||
image | String / Slot | - | 主图 | N
|
||||
jump-type | String | navigateTo | 链接跳转类型。可选项:switchTab/reLaunch/redirectTo/navigateTo | N
|
||||
left-icon | String / Slot | - | 左侧图标,出现在单元格标题的左侧 | N
|
||||
note | String / Slot | - | 和标题同行的说明文字 | N
|
||||
required | Boolean | false | 是否显示表单必填星号 | N
|
||||
right-icon | String / Slot | - | 最右侧图标 | N
|
||||
title | String / Slot | - | 标题 | N
|
||||
url | String | - | 点击后跳转链接地址。如果值为空,则表示不需要跳转 | N
|
||||
|
||||
### Cell Events
|
||||
|
||||
名称 | 参数 | 描述
|
||||
-- | -- | --
|
||||
click | - | 右侧内容
|
||||
@@ -0,0 +1,14 @@
|
||||
import { SuperComponent } from '../common/src/index';
|
||||
export default class Cell extends SuperComponent {
|
||||
externalClasses: string[];
|
||||
options: {
|
||||
multipleSlots: boolean;
|
||||
};
|
||||
properties: import("./type").TdCellProps;
|
||||
data: {
|
||||
prefix: string;
|
||||
classPrefix: string;
|
||||
};
|
||||
onClick(e: any): void;
|
||||
jumpLink(urlKey?: string, link?: string): void;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
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}-cell`;
|
||||
let Cell = class Cell extends SuperComponent {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.externalClasses = [
|
||||
`${prefix}-class`,
|
||||
`${prefix}-class-title`,
|
||||
`${prefix}-class-description`,
|
||||
`${prefix}-class-note`,
|
||||
`${prefix}-class-hover`,
|
||||
`${prefix}-class-image`,
|
||||
`${prefix}-class-left`,
|
||||
`${prefix}-class-left-icon`,
|
||||
`${prefix}-class-right`,
|
||||
`${prefix}-class-right-icon`,
|
||||
];
|
||||
this.options = {
|
||||
multipleSlots: true,
|
||||
};
|
||||
this.properties = props;
|
||||
this.data = {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
};
|
||||
}
|
||||
onClick(e) {
|
||||
this.triggerEvent('click', e.detail);
|
||||
this.jumpLink();
|
||||
}
|
||||
jumpLink(urlKey = 'url', link = 'jumpType') {
|
||||
const url = this.data[urlKey];
|
||||
const jumpType = this.data[link];
|
||||
if (url) {
|
||||
wx[jumpType]({ url });
|
||||
}
|
||||
}
|
||||
};
|
||||
Cell = __decorate([
|
||||
wxComponent()
|
||||
], Cell);
|
||||
export default Cell;
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"t-icon": "../icon/icon",
|
||||
"t-image": "../image/image"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<view
|
||||
style="{{ customStyle }}"
|
||||
class="{{prefix}}-class {{classPrefix}} {{ hover ? classPrefix + '--hover' : ''}} {{ !bordered ? classPrefix + '--borderless' : ''}} {{classPrefix}}--{{align}}"
|
||||
hover-class="{{classPrefix}}--hover-class"
|
||||
hover-stay-time="70"
|
||||
bind:tap="onClick"
|
||||
aria-role="{{ariaRole || (arrow ? 'button' : '')}}"
|
||||
aria-label="{{ariaLabel}}"
|
||||
>
|
||||
<view class="{{classPrefix}}__left {{prefix}}-class-left">
|
||||
<t-icon wx:if="{{ leftIcon }}" name="{{leftIcon}}" class="{{classPrefix}}__left-icon {{prefix}}-class-left-icon" />
|
||||
<slot name="left-icon" />
|
||||
<t-image
|
||||
wx:if="{{ image }}"
|
||||
class="{{classPrefix}}__left-image"
|
||||
shape="round"
|
||||
t-class="{{classPrefix}}__left-image {{prefix}}-class-image"
|
||||
src="{{ image }}"
|
||||
/>
|
||||
<slot name="image" />
|
||||
</view>
|
||||
<view class="{{classPrefix}}__title {{prefix}}-class-title">
|
||||
<view class="{{classPrefix}}__title-text">
|
||||
<block wx:if="{{ title }}"> {{ title}} </block>
|
||||
<slot name="title" />
|
||||
<block wx:if="{{required}}">
|
||||
<text decode class="{{classPrefix}}--required"> *</text>
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<view class="{{classPrefix}}__description {{prefix}}-class-description">
|
||||
<view wx:if="{{ description }}" class="{{classPrefix}}__description-text">{{description}}</view>
|
||||
<slot name="description" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="{{classPrefix}}__note {{prefix}}-class-note">
|
||||
<text wx:if="{{ note }}">{{note}}</text>
|
||||
<slot name="note" />
|
||||
</view>
|
||||
|
||||
<view class="{{classPrefix}}__right {{prefix}}-class-right">
|
||||
<t-icon wx:if="{{ arrow }}" name="chevron-right" class="{{classPrefix}}__right-icon {{prefix}}-class-right-icon" />
|
||||
<block wx:else>
|
||||
<t-icon name="{{rightIcon}}" class="{{classPrefix}}__right-icon {{prefix}}-class-right-icon" />
|
||||
<slot name="right-icon" />
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
@@ -0,0 +1,126 @@
|
||||
.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-cell {
|
||||
position: relative;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
padding: var(--td-cell-vertical-padding, 32rpx) var(--td-cell-horizontal-padding, 32rpx);
|
||||
font-size: var(--td-cell-font-size, var(--td-font-size-m, 32rpx));
|
||||
line-height: var(--td-cell-line-height, 48rpx);
|
||||
height: var(--td-cell-height, auto);
|
||||
color: var(--td-cell-text-color, var(--td-font-gray-1, rgba(0, 0, 0, 0.9)));
|
||||
background-color: var(--td-cell-bg-color, var(--td-bg-color-block, #fff));
|
||||
}
|
||||
.t-cell::after {
|
||||
position: absolute;
|
||||
box-sizing: border-box;
|
||||
content: ' ';
|
||||
pointer-events: none;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
border-bottom: 1px solid var(--td-cell-border-color, var(--td-gray-color-3, #e7e7e7));
|
||||
transform: scaleY(0.5);
|
||||
left: 32rpx;
|
||||
}
|
||||
.t-cell--borderless::after {
|
||||
display: none;
|
||||
}
|
||||
.t-cell__description {
|
||||
font-size: var(--td-cell-description-font-size, var(--td-font-size-base, 28rpx));
|
||||
line-height: var(--td-cell-description-line-height, 44rpx);
|
||||
color: var(--td-cell-description-color, var(--td-font-gray-2, rgba(0, 0, 0, 0.6)));
|
||||
}
|
||||
.t-cell__description-text {
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
.t-cell__note {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
overflow: hidden;
|
||||
color: var(--td-cell-note-color, var(--td-font-gray-3, rgba(0, 0, 0, 0.4)));
|
||||
font-size: var(--td-cell-note-font-size, var(--td-font-size-m, 32rpx));
|
||||
}
|
||||
.t-cell__title,
|
||||
.t-cell__note {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
.t-cell__title:empty,
|
||||
.t-cell__note:empty {
|
||||
display: none;
|
||||
}
|
||||
.t-cell__title-text {
|
||||
display: flex;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
}
|
||||
.t-cell__left,
|
||||
.t-cell__right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: var(--td-cell-icon-size, 48rpx);
|
||||
line-height: var(--td-cell-line-height, 48rpx);
|
||||
}
|
||||
.t-cell__left:not(:empty) {
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
.t-cell__left-icon {
|
||||
font-size: var(--td-cell-icon-size, 48rpx);
|
||||
}
|
||||
.t-cell__left-image {
|
||||
height: var(--td-cell-image-height, 96rpx);
|
||||
width: var(--td-cell-image-width, 96rpx);
|
||||
}
|
||||
.t-cell__right {
|
||||
margin-left: 8rpx;
|
||||
color: var(--td-cell-right-icon-color, var(--td-font-gray-3, rgba(0, 0, 0, 0.4)));
|
||||
}
|
||||
.t-cell__right-icon {
|
||||
color: var(--td-cell-right-icon-color, var(--td-font-gray-3, rgba(0, 0, 0, 0.4)));
|
||||
font-size: var(--td-cell-icon-size, 48rpx);
|
||||
line-height: var(--td-cell-line-height, 48rpx);
|
||||
}
|
||||
.t-cell--hover.t-cell--hover-class {
|
||||
background-color: var(--td-cell-hover-color, var(--td-gray-color-1, #f3f3f3));
|
||||
}
|
||||
.t-cell--required {
|
||||
font-size: var(--td-cell-font-size, var(--td-font-size-m, 32rpx));
|
||||
color: var(--td-cell-required-color, var(--td-error-color-6, #e34d59));
|
||||
}
|
||||
.t-cell--middle {
|
||||
align-items: center;
|
||||
}
|
||||
.t-cell--top {
|
||||
align-items: flex-start;
|
||||
}
|
||||
.t-cell--bottom {
|
||||
align-items: flex-end;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import { TdCellProps } from './type';
|
||||
declare const props: TdCellProps;
|
||||
export default props;
|
||||
@@ -0,0 +1,55 @@
|
||||
const props = {
|
||||
align: {
|
||||
type: String,
|
||||
value: 'middle',
|
||||
},
|
||||
arrow: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
bordered: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
customStyle: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
},
|
||||
externalClasses: {
|
||||
type: Array,
|
||||
},
|
||||
hover: {
|
||||
type: Boolean,
|
||||
},
|
||||
image: {
|
||||
type: String,
|
||||
},
|
||||
jumpType: {
|
||||
type: String,
|
||||
value: 'navigateTo',
|
||||
},
|
||||
leftIcon: {
|
||||
type: String,
|
||||
},
|
||||
note: {
|
||||
type: String,
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
rightIcon: {
|
||||
type: String,
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
},
|
||||
url: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
};
|
||||
export default props;
|
||||
@@ -0,0 +1,71 @@
|
||||
export interface TdCellProps {
|
||||
align?: {
|
||||
type: StringConstructor;
|
||||
value?: 'top' | 'middle' | 'bottom';
|
||||
};
|
||||
arrow?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
bordered?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
customStyle?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
description?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
externalClasses?: {
|
||||
type: ArrayConstructor;
|
||||
value?: [
|
||||
't-class',
|
||||
't-class-title',
|
||||
't-class-note',
|
||||
't-class-description',
|
||||
't-class-thumb',
|
||||
't-class-hover',
|
||||
't-class-left',
|
||||
't-class-right'
|
||||
];
|
||||
};
|
||||
hover?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
image?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
jumpType?: {
|
||||
type: StringConstructor;
|
||||
value?: 'switchTab' | 'reLaunch' | 'redirectTo' | 'navigateTo';
|
||||
};
|
||||
leftIcon?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
note?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
required?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
rightIcon?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
title?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
url?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export {};
|
||||
@@ -0,0 +1,59 @@
|
||||
---
|
||||
title: checkbox-group
|
||||
description: 组合多选框
|
||||
spline: form
|
||||
isComponent: true
|
||||
---
|
||||
|
||||
### 特性及兼容性
|
||||
|
||||
无
|
||||
|
||||
## 引入
|
||||
|
||||
### 引入组件
|
||||
|
||||
在 `app.json` 或 `page.json` 中引入组件:
|
||||
|
||||
```json
|
||||
"usingComponents": {
|
||||
"t-checkbox": "tdesign-miniprogram/checkbox/checkbox",
|
||||
"t-checkbox-group": "tdesign-miniprogram/checkbox-group/checkbox-group"
|
||||
}
|
||||
```
|
||||
|
||||
## 用法
|
||||
|
||||
### 组件方式
|
||||
|
||||
```html
|
||||
<!-- page.wxml -->
|
||||
<t-checkbox-group defaultValue="checkbox1" bind:change="onChange">
|
||||
<t-checkbox title="单行标题" value="checkbox1" />
|
||||
<t-checkbox title="单行标题" label="辅助信息" value="checkbox2" />
|
||||
</t-checkbox-group>
|
||||
```
|
||||
<t-checkbox title="单行标题" value="checkbox1" defaultChecked="{{true}}"/>
|
||||
## API
|
||||
|
||||
### `<t-checkbox-group>` 组件
|
||||
|
||||
组件路径:`tdesign-miniprogram/checkbox-group/checkbox-group`
|
||||
|
||||
#### Props
|
||||
|
||||
| 属性 | 值类型 | 默认值 | 必传 | 说明 |
|
||||
| -------- | --------- | ------ | ---- | ---------------------- |
|
||||
| value | `Array` | `[]` | N | 当前选中项的标识符 |
|
||||
| name | `String` | - | N | 在表单内提交时的标识符 |
|
||||
### Slots
|
||||
|
||||
| 名称 | 说明 |
|
||||
| ---- | ----------------- |
|
||||
| 默认 | `t-checkbox` 组件 |
|
||||
|
||||
#### Events
|
||||
|
||||
| 事件 | event.detail | 说明 |
|
||||
| ----------- | -------------------------- | ------------------------ |
|
||||
| bind:change | {names:当前选中项的标识符} | 当绑定值变化时触发的事件 |
|
||||
@@ -0,0 +1,69 @@
|
||||
import { SuperComponent, RelationsOptions } from '../common/src/index';
|
||||
export default class CheckBoxGroup extends SuperComponent {
|
||||
externalClasses: string[];
|
||||
relations: RelationsOptions;
|
||||
data: {
|
||||
prefix: string;
|
||||
classPrefix: string;
|
||||
checkboxOptions: any[];
|
||||
};
|
||||
properties: {
|
||||
borderless: {
|
||||
type: BooleanConstructor;
|
||||
value: boolean;
|
||||
};
|
||||
customStyle?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
disabled?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
max?: {
|
||||
type: NumberConstructor;
|
||||
value?: number;
|
||||
};
|
||||
name?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
options?: {
|
||||
type: ArrayConstructor;
|
||||
value?: import("./type").CheckboxOption[];
|
||||
};
|
||||
value?: {
|
||||
type: ArrayConstructor;
|
||||
value?: import("./type").CheckboxGroupValue;
|
||||
};
|
||||
defaultValue?: {
|
||||
type: ArrayConstructor;
|
||||
value?: import("./type").CheckboxGroupValue;
|
||||
};
|
||||
};
|
||||
observers: {
|
||||
value(): void;
|
||||
};
|
||||
lifetimes: {
|
||||
attached(): void;
|
||||
ready(): void;
|
||||
};
|
||||
controlledProps: {
|
||||
key: string;
|
||||
event: string;
|
||||
}[];
|
||||
$checkAll: any;
|
||||
methods: {
|
||||
getChilds(): any;
|
||||
updateChildren(): void;
|
||||
updateValue({ value, checked, checkAll, indeterminate }: {
|
||||
value: any;
|
||||
checked: any;
|
||||
checkAll: any;
|
||||
indeterminate: any;
|
||||
}): void;
|
||||
initWithOptions(): void;
|
||||
handleInnerChildChange(e: any): void;
|
||||
setCheckall(): void;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
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}-checkbox-group`;
|
||||
let CheckBoxGroup = class CheckBoxGroup extends SuperComponent {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.externalClasses = [`${prefix}-class`];
|
||||
this.relations = {
|
||||
'../checkbox/checkbox': {
|
||||
type: 'descendant',
|
||||
},
|
||||
};
|
||||
this.data = {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
checkboxOptions: [],
|
||||
};
|
||||
this.properties = Object.assign(Object.assign({}, props), { borderless: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
} });
|
||||
this.observers = {
|
||||
value() {
|
||||
this.updateChildren();
|
||||
},
|
||||
};
|
||||
this.lifetimes = {
|
||||
attached() {
|
||||
this.initWithOptions();
|
||||
},
|
||||
ready() {
|
||||
this.setCheckall();
|
||||
},
|
||||
};
|
||||
this.controlledProps = [
|
||||
{
|
||||
key: 'value',
|
||||
event: 'change',
|
||||
},
|
||||
];
|
||||
this.$checkAll = null;
|
||||
this.methods = {
|
||||
getChilds() {
|
||||
let items = this.$children;
|
||||
if (!items.length) {
|
||||
items = this.selectAllComponents(`.${prefix}-checkbox-option`);
|
||||
}
|
||||
return items || [];
|
||||
},
|
||||
updateChildren() {
|
||||
const items = this.getChilds();
|
||||
const { value } = this.data;
|
||||
if (items.length > 0) {
|
||||
items.forEach((item) => {
|
||||
!item.data.checkAll &&
|
||||
item.setData({
|
||||
checked: value === null || value === void 0 ? void 0 : value.includes(item.data.value),
|
||||
});
|
||||
});
|
||||
if (items.some((item) => item.data.checkAll)) {
|
||||
this.setCheckall();
|
||||
}
|
||||
}
|
||||
},
|
||||
updateValue({ value, checked, checkAll, indeterminate }) {
|
||||
let { value: newValue } = this.data;
|
||||
const { max } = this.data;
|
||||
const keySet = new Set(this.getChilds().map((item) => item.data.value));
|
||||
newValue = newValue.filter((value) => keySet.has(value));
|
||||
if (max && checked && newValue.length === max)
|
||||
return;
|
||||
if (checkAll) {
|
||||
const items = this.getChilds();
|
||||
newValue =
|
||||
!checked && indeterminate
|
||||
? items.map((item) => item.data.value)
|
||||
: items
|
||||
.filter(({ data }) => {
|
||||
if (data.disabled) {
|
||||
return newValue.includes(data.value);
|
||||
}
|
||||
return checked && !data.checkAll;
|
||||
})
|
||||
.map(({ data }) => data.value);
|
||||
}
|
||||
else if (checked) {
|
||||
newValue = newValue.concat(value);
|
||||
}
|
||||
else {
|
||||
const index = newValue.findIndex((v) => v === value);
|
||||
newValue.splice(index, 1);
|
||||
}
|
||||
this._trigger('change', { value: newValue });
|
||||
},
|
||||
initWithOptions() {
|
||||
const { options } = this.data;
|
||||
if (!(options === null || options === void 0 ? void 0 : options.length) || !Array.isArray(options))
|
||||
return;
|
||||
const checkboxOptions = options.map((item) => {
|
||||
const isLabel = ['number', 'string'].includes(typeof item);
|
||||
return isLabel
|
||||
? {
|
||||
label: `${item}`,
|
||||
value: item,
|
||||
}
|
||||
: Object.assign({}, item);
|
||||
});
|
||||
this.setData({
|
||||
checkboxOptions,
|
||||
});
|
||||
},
|
||||
handleInnerChildChange(e) {
|
||||
var _a;
|
||||
const { item } = e.target.dataset;
|
||||
const { checked } = e.detail;
|
||||
const rect = {};
|
||||
if (item.checkAll) {
|
||||
rect.indeterminate = (_a = this.$checkAll) === null || _a === void 0 ? void 0 : _a.data.indeterminate;
|
||||
}
|
||||
this.updateValue(Object.assign(Object.assign(Object.assign({}, item), { checked }), rect));
|
||||
},
|
||||
setCheckall() {
|
||||
const items = this.getChilds();
|
||||
if (!this.$checkAll) {
|
||||
this.$checkAll = items.find((item) => item.data.checkAll);
|
||||
}
|
||||
if (!this.$checkAll)
|
||||
return;
|
||||
const { value } = this.data;
|
||||
const valueSet = new Set(value.filter((val) => val !== this.$checkAll.data.value));
|
||||
const isCheckall = items.every((item) => (item.data.checkAll ? true : valueSet.has(item.data.value)));
|
||||
this.$checkAll.setData({
|
||||
checked: valueSet.size > 0,
|
||||
indeterminate: !isCheckall,
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
CheckBoxGroup = __decorate([
|
||||
wxComponent()
|
||||
], CheckBoxGroup);
|
||||
export default CheckBoxGroup;
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"t-checkbox": "../checkbox/checkbox"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<view class="{{ classPrefix }} {{prefix}}-class" style="{{customStyle}}">
|
||||
<slot />
|
||||
<block wx:for="{{checkboxOptions}}" wx:key="value">
|
||||
<t-checkbox
|
||||
class="{{prefix}}-checkbox-option"
|
||||
label="{{item.label || item.text || ''}}"
|
||||
value="{{item.value || ''}}"
|
||||
content="{{item.content || ''}}"
|
||||
check-all="{{item.checkAll}}"
|
||||
disabled="{{item.disabled}}"
|
||||
data-item="{{item}}"
|
||||
bind:change="handleInnerChildChange"
|
||||
></t-checkbox>
|
||||
</block>
|
||||
</view>
|
||||
@@ -0,0 +1,3 @@
|
||||
import { TdCheckboxGroupProps } from './type';
|
||||
declare const props: TdCheckboxGroupProps;
|
||||
export default props;
|
||||
@@ -0,0 +1,31 @@
|
||||
const props = {
|
||||
customStyle: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
max: {
|
||||
type: Number,
|
||||
value: undefined,
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
options: {
|
||||
type: Array,
|
||||
value: [],
|
||||
},
|
||||
value: {
|
||||
type: Array,
|
||||
value: null,
|
||||
},
|
||||
defaultValue: {
|
||||
type: Array,
|
||||
value: [],
|
||||
},
|
||||
};
|
||||
export default props;
|
||||
@@ -0,0 +1,38 @@
|
||||
export interface TdCheckboxGroupProps {
|
||||
customStyle?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
disabled?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
max?: {
|
||||
type: NumberConstructor;
|
||||
value?: number;
|
||||
};
|
||||
name?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
options?: {
|
||||
type: ArrayConstructor;
|
||||
value?: Array<CheckboxOption>;
|
||||
};
|
||||
value?: {
|
||||
type: ArrayConstructor;
|
||||
value?: CheckboxGroupValue;
|
||||
};
|
||||
defaultValue?: {
|
||||
type: ArrayConstructor;
|
||||
value?: CheckboxGroupValue;
|
||||
};
|
||||
}
|
||||
export declare type CheckboxOption = string | number | CheckboxOptionObj;
|
||||
export interface CheckboxOptionObj {
|
||||
label?: string;
|
||||
value?: string | number;
|
||||
disabled?: boolean;
|
||||
checkAll?: true;
|
||||
}
|
||||
export declare type CheckboxGroupValue = Array<string | number>;
|
||||
@@ -0,0 +1 @@
|
||||
export {};
|
||||
@@ -0,0 +1,49 @@
|
||||
:: BASE_DOC ::
|
||||
|
||||
## API
|
||||
### Checkbox Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
align | String | left | options:left/right | N
|
||||
block | Boolean | true | \- | N
|
||||
check-all | Boolean | false | \- | N
|
||||
checked | Boolean | false | \- | N
|
||||
default-checked | Boolean | undefined | uncontrolled property | N
|
||||
content | String / Slot | - | \- | N
|
||||
content-disabled | Boolean | - | \- | N
|
||||
custom-style | String | - | `0.25.0` | N
|
||||
disabled | Boolean | undefined | \- | N
|
||||
external-classes | Array | - | `['t-class', 't-class-icon', 't-class-label', 't-class-content', 't-class-border']` | N
|
||||
icon | String / Array | 'circle' | Typescript:`'circle' \| 'line' \| 'rectangle' \| string[]` | N
|
||||
indeterminate | Boolean | false | \- | N
|
||||
label | String / Slot | - | \- | N
|
||||
max-content-row | Number | 5 | \- | N
|
||||
max-label-row | Number | 3 | \- | N
|
||||
name | String | - | \- | N
|
||||
readonly | Boolean | false | \- | N
|
||||
value | String / Number | - | Typescript:`string \| number \| boolean` | N
|
||||
|
||||
### Checkbox Events
|
||||
|
||||
name | params | description
|
||||
-- | -- | --
|
||||
change | `(checked: boolean)` | \-
|
||||
|
||||
### CheckboxGroup Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | String | - | `0.25.0` | N
|
||||
disabled | Boolean | false | \- | N
|
||||
max | Number | undefined | \- | N
|
||||
name | String | - | \- | N
|
||||
options | Array | [] | Typescript:`Array<CheckboxOption>` `type CheckboxOption = string \| number \| CheckboxOptionObj` `interface CheckboxOptionObj { label?: string; value?: string \| number; disabled?: boolean; checkAll?: true }`。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/checkbox-group/type.ts) | N
|
||||
value | Array | [] | Typescript:`CheckboxGroupValue` `type CheckboxGroupValue = Array<string \| number>`。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/checkbox-group/type.ts) | N
|
||||
default-value | Array | undefined | uncontrolled property。Typescript:`CheckboxGroupValue` `type CheckboxGroupValue = Array<string \| number>`。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/checkbox-group/type.ts) | N
|
||||
|
||||
### CheckboxGroup Events
|
||||
|
||||
name | params | description
|
||||
-- | -- | --
|
||||
change | `(value: CheckboxGroupValue, context: CheckboxGroupChangeContext)` | [see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/checkbox-group/type.ts)。<br/>`interface CheckboxGroupChangeContext { e: Event; current: string \| number; option: CheckboxOption \| TdCheckboxProps; type: 'check' \| 'uncheck' }`<br/>
|
||||
@@ -0,0 +1,108 @@
|
||||
---
|
||||
title: Checkbox 复选框
|
||||
description: 用于预设的一组选项中执行多项选择,并呈现选择结果。
|
||||
spline: form
|
||||
isComponent: true
|
||||
---
|
||||
|
||||
<span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20lines-85%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20functions-87%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20statements-86%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20branches-76%25-red" /></span>
|
||||
## 引入
|
||||
|
||||
全局引入,在 miniprogram 根目录下的`app.json`中配置,局部引入,在需要引入的页面或组件的`index.json`中配置。
|
||||
|
||||
```json
|
||||
"usingComponents": {
|
||||
"t-checkbox": "tdesign-miniprogram/checkbox/checkbox",
|
||||
"t-checkbox-group": "tdesign-miniprogram/checkbox-group/checkbox-group"
|
||||
}
|
||||
```
|
||||
|
||||
## 代码演示
|
||||
|
||||
### 组件类型
|
||||
|
||||
纵向多选框
|
||||
|
||||
{{ base }}
|
||||
|
||||
横向多选框
|
||||
|
||||
{{ horizontal }}
|
||||
|
||||
带全选多选框
|
||||
|
||||
{{ all }}
|
||||
|
||||
### 组件状态
|
||||
|
||||
多选框状态
|
||||
|
||||
{{ status }}
|
||||
|
||||
### 组件样式
|
||||
|
||||
勾选样式
|
||||
|
||||
{{ type }}
|
||||
|
||||
勾选显示位置
|
||||
|
||||
{{ right }}
|
||||
|
||||
非通栏多选样式
|
||||
|
||||
{{ card }}
|
||||
|
||||
### 组件规格
|
||||
|
||||
多选框尺寸规格
|
||||
|
||||
{{ special }}
|
||||
|
||||
## API
|
||||
### Checkbox Props
|
||||
|
||||
名称 | 类型 | 默认值 | 说明 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
align | String | left | 多选框和内容相对位置。可选项:left/right | N
|
||||
block | Boolean | true | 是否为块级元素 | N
|
||||
check-all | Boolean | false | 用于标识是否为「全选选项」。单独使用无效,需在 CheckboxGroup 中使用 | N
|
||||
checked | Boolean | false | 是否选中 | N
|
||||
default-checked | Boolean | undefined | 是否选中。非受控属性 | N
|
||||
content | String / Slot | - | 多选框内容 | N
|
||||
content-disabled | Boolean | - | 是否禁用组件内容(content)触发选中 | N
|
||||
custom-style | String | - | `0.25.0`。自定义组件样式 | N
|
||||
disabled | Boolean | undefined | 是否禁用组件 | N
|
||||
external-classes | Array | - | 组件类名,分别用于设置 组件外层、多选框图标、主文案、内容 等元素类名。`['t-class', 't-class-icon', 't-class-label', 't-class-content', 't-class-border']` | N
|
||||
icon | String / Array | 'circle' | 自定义选中图标和非选中图标。使用 Array 时表示:`[选中态图标,非选中态图标]`。使用 String 时,值为 circle 表示填充圆形图标、值为 line 表示描边型图标、值为 rectangle 表示填充矩形图标。TS 类型:`'circle' \| 'line' \| 'rectangle' \| string[]` | N
|
||||
indeterminate | Boolean | false | 是否为半选 | N
|
||||
label | String / Slot | - | 主文案 | N
|
||||
max-content-row | Number | 5 | 内容最大行数限制 | N
|
||||
max-label-row | Number | 3 | 主文案最大行数限制 | N
|
||||
name | String | - | HTML 元素原生属性 | N
|
||||
readonly | Boolean | false | 只读状态 | N
|
||||
value | String / Number | - | 多选框的值。TS 类型:`string \| number` | N
|
||||
|
||||
### Checkbox Events
|
||||
|
||||
名称 | 参数 | 描述
|
||||
-- | -- | --
|
||||
change | `(checked: boolean)` | 值变化时触发
|
||||
|
||||
### CheckboxGroup Props
|
||||
|
||||
名称 | 类型 | 默认值 | 说明 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | String | - | `0.25.0`。自定义组件样式 | N
|
||||
disabled | Boolean | false | 是否禁用组件 | N
|
||||
max | Number | undefined | 支持最多选中的数量 | N
|
||||
name | String | - | 统一设置内部复选框 HTML 属性 | N
|
||||
options | Array | [] | 以配置形式设置子元素。示例1:`['北京', '上海']` ,示例2: `[{ label: '全选', checkAll: true }, { label: '上海', value: 'shanghai' }]`。checkAll 值为 true 表示当前选项为「全选选项」。TS 类型:`Array<CheckboxOption>` `type CheckboxOption = string \| number \| CheckboxOptionObj` `interface CheckboxOptionObj { label?: string; value?: string \| number; disabled?: boolean; checkAll?: true }`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/checkbox-group/type.ts) | N
|
||||
value | Array | [] | 选中值。TS 类型:`CheckboxGroupValue` `type CheckboxGroupValue = Array<string \| number>`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/checkbox-group/type.ts) | N
|
||||
default-value | Array | undefined | 选中值。非受控属性。TS 类型:`CheckboxGroupValue` `type CheckboxGroupValue = Array<string \| number>`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/checkbox-group/type.ts) | N
|
||||
|
||||
### CheckboxGroup Events
|
||||
|
||||
名称 | 参数 | 描述
|
||||
-- | -- | --
|
||||
change | `(value: CheckboxGroupValue, context: CheckboxGroupChangeContext)` | 值变化时触发。`context.current` 表示当前变化的数据项,如果是全选则为空;`context.type` 表示引起选中数据变化的是选中或是取消选中,`context.option` 表示当前变化的数据项。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/checkbox-group/type.ts)。<br/>`interface CheckboxGroupChangeContext { e: Event; current: string \| number; option: CheckboxOption \| TdCheckboxProps; type: 'check' \| 'uncheck' }`<br/>
|
||||
@@ -0,0 +1,100 @@
|
||||
import { SuperComponent, ComponentsOptionsType, RelationsOptions } from '../common/src/index';
|
||||
export default class CheckBox extends SuperComponent {
|
||||
externalClasses: string[];
|
||||
behaviors: string[];
|
||||
relations: RelationsOptions;
|
||||
options: ComponentsOptionsType;
|
||||
properties: {
|
||||
theme: {
|
||||
type: StringConstructor;
|
||||
value: string;
|
||||
};
|
||||
borderless: {
|
||||
type: BooleanConstructor;
|
||||
value: boolean;
|
||||
};
|
||||
align?: {
|
||||
type: StringConstructor;
|
||||
value?: "left" | "right";
|
||||
};
|
||||
block?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
checkAll?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
checked?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
defaultChecked?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
content?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
contentDisabled?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
customStyle?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
disabled?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
externalClasses?: {
|
||||
type: ArrayConstructor;
|
||||
value?: ["t-class", "t-class-icon", "t-class-label", "t-class-content", "t-class-border"];
|
||||
};
|
||||
icon?: {
|
||||
type: null;
|
||||
value?: string[] | "circle" | "rectangle" | "line";
|
||||
};
|
||||
indeterminate?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
label?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
maxContentRow?: {
|
||||
type: NumberConstructor;
|
||||
value?: number;
|
||||
};
|
||||
maxLabelRow?: {
|
||||
type: NumberConstructor;
|
||||
value?: number;
|
||||
};
|
||||
name?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
readonly?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
value?: {
|
||||
type: null;
|
||||
value?: string | number | boolean;
|
||||
};
|
||||
};
|
||||
data: {
|
||||
prefix: string;
|
||||
classPrefix: string;
|
||||
};
|
||||
controlledProps: {
|
||||
key: string;
|
||||
event: string;
|
||||
}[];
|
||||
methods: {
|
||||
onChange(e: WechatMiniprogram.TouchEvent): void;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
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}-checkbox`;
|
||||
let CheckBox = class CheckBox extends SuperComponent {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.externalClasses = [
|
||||
`${prefix}-class`,
|
||||
`${prefix}-class-label`,
|
||||
`${prefix}-class-icon`,
|
||||
`${prefix}-class-content`,
|
||||
`${prefix}-class-border`,
|
||||
];
|
||||
this.behaviors = ['wx://form-field'];
|
||||
this.relations = {
|
||||
'../checkbox-group/checkbox-group': {
|
||||
type: 'ancestor',
|
||||
linked(parent) {
|
||||
const { value, disabled, borderless } = parent.data;
|
||||
const valueSet = new Set(value);
|
||||
const data = {
|
||||
disabled: disabled || this.data.disabled,
|
||||
};
|
||||
if (borderless) {
|
||||
data.borderless = true;
|
||||
}
|
||||
data.checked = valueSet.has(this.data.value);
|
||||
if (this.data.checkAll) {
|
||||
data.checked = valueSet.size > 0;
|
||||
}
|
||||
this.setData(data);
|
||||
},
|
||||
},
|
||||
};
|
||||
this.options = {
|
||||
multipleSlots: true,
|
||||
};
|
||||
this.properties = Object.assign(Object.assign({}, Props), { theme: {
|
||||
type: String,
|
||||
value: 'default',
|
||||
}, borderless: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
} });
|
||||
this.data = {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
};
|
||||
this.controlledProps = [
|
||||
{
|
||||
key: 'checked',
|
||||
event: 'change',
|
||||
},
|
||||
];
|
||||
this.methods = {
|
||||
onChange(e) {
|
||||
const { disabled, readonly } = this.data;
|
||||
if (disabled || readonly)
|
||||
return;
|
||||
const { target } = e.currentTarget.dataset;
|
||||
const { contentDisabled } = this.data;
|
||||
if (target === 'text' && contentDisabled) {
|
||||
return;
|
||||
}
|
||||
const checked = !this.data.checked;
|
||||
const parent = this.$parent;
|
||||
if (parent) {
|
||||
parent.updateValue(Object.assign(Object.assign({}, this.data), { checked }));
|
||||
}
|
||||
else {
|
||||
this._trigger('change', { checked });
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
CheckBox = __decorate([
|
||||
wxComponent()
|
||||
], CheckBox);
|
||||
export default CheckBox;
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"t-cell": "../cell/cell",
|
||||
"t-icon": "../icon/icon"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<wxs src="../common/utils.wxs" module="_" />
|
||||
|
||||
<view
|
||||
style="{{ customStyle }}"
|
||||
class="{{_.cls(classPrefix, [align, theme, ['checked', checked], ['block', block]])}} {{prefix}}-class"
|
||||
aria-role="checkbox"
|
||||
aria-checked="{{checked ? (indeterminate ? 'mixed' : true) : false}}"
|
||||
aria-disabled="{{disabled ? true : false}}"
|
||||
bind:tap="onChange"
|
||||
tabindex="{{tabindex}}"
|
||||
>
|
||||
<view
|
||||
wx:if="{{theme == 'default'}}"
|
||||
class="{{_.cls(classPrefix + '__icon', [align, ['checked', checked], ['disabled', disabled]])}} {{prefix}}-class-icon"
|
||||
>
|
||||
<view wx:if="{{_.isArray(icon)}}" class="{{classPrefix}}__icon">
|
||||
<image src="{{checked ? icon[0] : icon[1]}}" class="{{classPrefix}}__icon-image" webp />
|
||||
</view>
|
||||
<block wx:else>
|
||||
<t-icon
|
||||
wx:if="{{checked && (icon == 'circle' || icon == 'rectangle')}}"
|
||||
name="{{indeterminate ? ('minus-' + icon + '-filled') : ('check-' + icon + '-filled')}}"
|
||||
class="{{_.cls(classPrefix + '__icon-wrapper', [])}}"
|
||||
/>
|
||||
<t-icon
|
||||
wx:if="{{checked && icon == 'line'}}"
|
||||
name="{{indeterminate ? ('minus-' + icon + '-filled') : 'check'}}"
|
||||
class="{{_.cls(classPrefix + '__icon-wrapper', [])}}"
|
||||
/>
|
||||
<view
|
||||
wx:elif="{{!checked && (icon == 'circle' || icon == 'rectangle')}}"
|
||||
class="{{_.cls(classPrefix + '__icon-' + icon, [['disabled', disabled]])}}"
|
||||
/>
|
||||
<view wx:if="{{!checked && icon == 'line'}}" class="placeholder"></view>
|
||||
</block>
|
||||
</view>
|
||||
<view class="{{classPrefix}}__content" data-target="text" catch:tap="onChange">
|
||||
<view
|
||||
class="{{_.cls(classPrefix + '__title', [['disabled', disabled], ['checked', checked]])}} {{prefix}}-class-label"
|
||||
style="-webkit-line-clamp:{{maxLabelRow}}"
|
||||
>
|
||||
{{label}}
|
||||
<slot />
|
||||
<slot name="label" />
|
||||
</view>
|
||||
<view
|
||||
class="{{_.cls(classPrefix + '__description', [['disabled', disabled]])}} {{prefix}}-class-content "
|
||||
style="-webkit-line-clamp:{{maxContentRow}}"
|
||||
>{{content}}<slot name="content"
|
||||
/></view>
|
||||
</view>
|
||||
<view
|
||||
wx:if="{{theme == 'default' && !borderless}}"
|
||||
class="{{_.cls(classPrefix + '__border', [align])}} {{prefix}}-class-border"
|
||||
/>
|
||||
</view>
|
||||
@@ -0,0 +1,202 @@
|
||||
.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-checkbox {
|
||||
display: inline-flex;
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
font-size: var(--td-checkbox-font-size, 32rpx);
|
||||
background: var(--td-checkbox-bg-color, var(--td-bg-color-block, #fff));
|
||||
}
|
||||
.t-checkbox:focus {
|
||||
outline: 0;
|
||||
}
|
||||
.t-checkbox--block {
|
||||
display: flex;
|
||||
padding: var(--td-checkbox-vertical-padding, 32rpx);
|
||||
}
|
||||
.t-checkbox--right {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
.t-checkbox .limit-title-row {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
.t-checkbox .image-center {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
.t-checkbox__icon-left {
|
||||
margin-right: 20rpx;
|
||||
width: 40rpx;
|
||||
}
|
||||
.t-checkbox__icon-right {
|
||||
right: 0px;
|
||||
display: contents;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
.t-checkbox__icon-image {
|
||||
width: var(--td-checkbox-icon-size, 48rpx);
|
||||
height: var(--td-checkbox-icon-size, 48rpx);
|
||||
vertical-align: top;
|
||||
}
|
||||
.t-checkbox__icon {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: var(--td-checkbox-icon-size, 48rpx);
|
||||
height: var(--td-checkbox-icon-size, 48rpx);
|
||||
color: var(--td-checkbox-icon-color, var(--td-gray-color-4, #dcdcdc));
|
||||
font-size: var(--td-checkbox-icon-size, 48rpx);
|
||||
}
|
||||
.t-checkbox__icon:empty {
|
||||
display: none;
|
||||
}
|
||||
.t-checkbox__icon--checked {
|
||||
color: var(--td-checkbox-icon-checked-color, var(--td-primary-color, #0052d9));
|
||||
}
|
||||
.t-checkbox__icon--disabled {
|
||||
cursor: not-allowed;
|
||||
color: var(--td-checkbox-icon-disabled-color, var(--td-primary-color-3, #bbd3fb));
|
||||
}
|
||||
.t-checkbox__icon--left {
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
.t-checkbox__icon-circle {
|
||||
width: 84rpx;
|
||||
height: 84rpx;
|
||||
border: 3px solid var(--td-checkbox-icon-color, var(--td-gray-color-4, #dcdcdc));
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%) scale(0.5);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.t-checkbox__icon-circle--disabled {
|
||||
background: var(--td-checkbox-icon-disabled-bg-color, var(--td-gray-color-2, #eeeeee));
|
||||
}
|
||||
.t-checkbox__icon-rectangle {
|
||||
width: 72rpx;
|
||||
height: 72rpx;
|
||||
border: 3px solid var(--td-checkbox-icon-color, var(--td-gray-color-4, #dcdcdc));
|
||||
border-radius: 4rpx;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%) scale(0.5);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.t-checkbox__icon-rectangle--disabled {
|
||||
background: var(--td-checkbox-icon-disabled-bg-color, var(--td-gray-color-2, #eeeeee));
|
||||
}
|
||||
.t-checkbox__icon-line:before,
|
||||
.t-checkbox__icon-line:after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 5rpx;
|
||||
border-radius: 2rpx;
|
||||
background: var(--td-checkbox-icon-checked-color, var(--td-primary-color, #0052d9));
|
||||
transform-origin: top center;
|
||||
}
|
||||
.t-checkbox__icon-line:before {
|
||||
height: 16rpx;
|
||||
left: 8rpx;
|
||||
top: 22rpx;
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
.t-checkbox__icon-line::after {
|
||||
height: 26rpx;
|
||||
right: 8rpx;
|
||||
top: 14rpx;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
.t-checkbox__icon-line--disabled::before,
|
||||
.t-checkbox__icon-line--disabled::after {
|
||||
background: var(--td-checkbox-icon-disabled-color, var(--td-primary-color-3, #bbd3fb));
|
||||
}
|
||||
.t-checkbox__content {
|
||||
flex: 1;
|
||||
}
|
||||
.t-checkbox__title {
|
||||
color: var(--td-checkbox-title-color, var(--td-font-gray-1, rgba(0, 0, 0, 0.9)));
|
||||
line-height: var(--td-checkbox-title-line-height, 48rpx);
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
.t-checkbox__title--disabled {
|
||||
color: var(--td-checkbox-title-disabled-color, var(--td-font-gray-4, rgba(0, 0, 0, 0.26)));
|
||||
}
|
||||
.t-checkbox__description {
|
||||
color: var(--td-checkbox-description-color, var(--td-font-gray-2, rgba(0, 0, 0, 0.6)));
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
font-size: 28rpx;
|
||||
line-height: var(--td-checkbox-description-line-height, 44rpx);
|
||||
}
|
||||
.t-checkbox__description--disabled {
|
||||
color: var(--td-checkbox-description-disabled-color, var(--td-font-gray-4, rgba(0, 0, 0, 0.26)));
|
||||
}
|
||||
.t-checkbox__title + .t-checkbox__description:not(:empty) {
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
.t-checkbox__border {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 96rpx;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
background: var(--td-checkbox-border-color, var(--td-gray-color-3, #e7e7e7));
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
.t-checkbox__border--right {
|
||||
left: 32rpx;
|
||||
}
|
||||
.t-checkbox--tag {
|
||||
font-size: 28rpx;
|
||||
padding-top: 16rpx;
|
||||
padding-bottom: 16rpx;
|
||||
text-align: center;
|
||||
background-color: #f3f3f3;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
.t-checkbox--tag.t-checkbox--checked {
|
||||
color: var(--td-checkbox-tag-active-color, var(--td-primary-color, #0052d9));
|
||||
background-color: var(--td-checkbox-tag-active-bg-color, var(--td-primary-color-1, #ecf2fe));
|
||||
}
|
||||
.t-checkbox--tag .t-checkbox__title--checked {
|
||||
color: var(--td-checkbox-tag-active-color, var(--td-primary-color, #0052d9));
|
||||
}
|
||||
.t-checkbox--tag .t-checkbox__content {
|
||||
margin-right: 0;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import { TdCheckboxProps } from './type';
|
||||
declare const props: TdCheckboxProps;
|
||||
export default props;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user