任务明细页面
This commit is contained in:
78
components/textarea/README.md
Normal file
78
components/textarea/README.md
Normal file
@@ -0,0 +1,78 @@
|
||||
---
|
||||
title: Textarea 多行文本框
|
||||
description: 用于多行文本信息输入。
|
||||
spline: form
|
||||
isComponent: true
|
||||
---
|
||||
|
||||
<span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20lines-100%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20functions-100%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20statements-100%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20branches-92%25-blue" /></span>
|
||||
## 引入
|
||||
|
||||
全局引入,在 miniprogram 根目录下的`app.json`中配置,局部引入,在需要引入的页面或组件的`index.json`中配置。
|
||||
|
||||
```json
|
||||
"usingComponents": {
|
||||
"t-textarea": "tdesign-miniprogram/textarea/textarea"
|
||||
}
|
||||
```
|
||||
|
||||
## 代码演示
|
||||
|
||||
### 基础多行文本框
|
||||
|
||||
<img src="https://tdesign.gtimg.com/miniprogram/readme/input-2.png" width="375px" height="50%">
|
||||
|
||||
{{ base }}
|
||||
|
||||
### 带标题多行文本框
|
||||
|
||||
{{ label }}
|
||||
|
||||
### 自动增高多行文本框
|
||||
|
||||
{{ autoSize }}
|
||||
|
||||
### 禁用多行文本框
|
||||
|
||||
{{ disabled }}
|
||||
|
||||
### 设置最大字符个数
|
||||
|
||||
{{ maxlength }}
|
||||
|
||||
### 设置最大字符个数,一个汉字表示两个字符
|
||||
|
||||
{{ maxcharacter }}
|
||||
|
||||
## 提示
|
||||
|
||||
- 如果需要在页面中调整 `textarea` 中 `placeholder` 样式,请使用名称为`t-textarea__placeholder`的Class选择器,直接覆盖组件内部样式(注意权重)。
|
||||
|
||||
## API
|
||||
### Textarea Props
|
||||
|
||||
名称 | 类型 | 默认值 | 说明 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
adjust-position | Boolean | true | 键盘弹起时,是否自动上推页面 | N
|
||||
autofocus | Boolean | false | 自动聚焦,拉起键盘 | N
|
||||
autosize | Boolean | false | 是否自动增高,值为 autosize 时,style.height 不生效 | N
|
||||
confirm-hold | Boolean | false | 点击键盘右下角按钮时是否保持键盘不收起点 | N
|
||||
confirm-type | String | done | 设置键盘右下角按钮的文字,仅在 type='text'时生效。可选项:send/search/next/go/done/return。TS 类型:`'send' | 'search' | 'next' | 'go' | 'done' | 'return'` | N
|
||||
disabled | Boolean | false | 是否禁用文本框 | N
|
||||
external-classes | Array | - | 组件类名,分别用于表示组件外层元素、输入框、占位符、标签名等元素类名。`['t-class', 't-class-textarea', 't-class-label']` | N
|
||||
focus | Boolean | false | 自动聚焦 | N
|
||||
label | String / Slot | - | 左侧文本 | N
|
||||
maxcharacter | Number | - | 用户最多可以输入的字符个数,一个中文汉字表示两个字符长度 | N
|
||||
maxlength | Number | - | 用户最多可以输入的字符个数 | N
|
||||
placeholder | String | undefined | 占位符 | N
|
||||
value | String | - | 文本框值 | N
|
||||
cursor-spacing | Number | - | 0 | 指定光标与键盘的距离。取textarea距离底部的距离和cursor-spacing指定的距离的最小值作为光标与键盘的距离 | N |
|
||||
### Textarea Events
|
||||
|
||||
名称 | 参数 | 描述
|
||||
-- | -- | --
|
||||
blur | `(value: TextareaValue)` | 失去焦点时触发
|
||||
change | `(value: TextareaValue)` | 输入内容变化时触发
|
||||
enter | `(value: TextareaValue)` | 点击完成时触发
|
||||
focus | `(value: TextareaValue)` | 获得焦点时触发
|
||||
line-change | `(value: TextareaValue)` | 行高发生变化时触发
|
||||
3
components/textarea/props.d.ts
vendored
Normal file
3
components/textarea/props.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import { TdTextareaProps } from './type';
|
||||
declare const props: TdTextareaProps;
|
||||
export default props;
|
||||
51
components/textarea/props.js
Normal file
51
components/textarea/props.js
Normal file
@@ -0,0 +1,51 @@
|
||||
const props = {
|
||||
adjustPosition: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
autofocus: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
autosize: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
confirmHold: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
confirmType: {
|
||||
type: String,
|
||||
value: 'done',
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
externalClasses: {
|
||||
type: Array,
|
||||
},
|
||||
focus: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
label: {
|
||||
type: String,
|
||||
},
|
||||
maxcharacter: {
|
||||
type: Number,
|
||||
},
|
||||
maxlength: {
|
||||
type: Number,
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
value: undefined,
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
value: null,
|
||||
},
|
||||
};
|
||||
export default props;
|
||||
95
components/textarea/textarea.d.ts
vendored
Normal file
95
components/textarea/textarea.d.ts
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
import { SuperComponent } from '../common/src/index';
|
||||
export default class Textarea extends SuperComponent {
|
||||
options: {
|
||||
multipleSlots: boolean;
|
||||
};
|
||||
behaviors: string[];
|
||||
externalClasses: string[];
|
||||
properties: {
|
||||
cursorSpacing: {
|
||||
type: NumberConstructor;
|
||||
value: number;
|
||||
};
|
||||
adjustPosition?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
required?: boolean;
|
||||
};
|
||||
autofocus?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
required?: boolean;
|
||||
};
|
||||
autosize?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
required?: boolean;
|
||||
};
|
||||
confirmHold?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
required?: boolean;
|
||||
};
|
||||
confirmType?: {
|
||||
type: StringConstructor;
|
||||
value?: "send" | "search" | "next" | "go" | "done";
|
||||
required?: boolean;
|
||||
};
|
||||
disabled?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
required?: boolean;
|
||||
};
|
||||
externalClasses?: {
|
||||
type: ArrayConstructor;
|
||||
value?: ["t-class", "t-class-textarea", "t-class-placeholder", "t-class-name"];
|
||||
required?: boolean;
|
||||
};
|
||||
focus?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
required?: boolean;
|
||||
};
|
||||
label?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
required?: boolean;
|
||||
};
|
||||
maxcharacter?: {
|
||||
type: NumberConstructor;
|
||||
value?: number;
|
||||
required?: boolean;
|
||||
};
|
||||
maxlength?: {
|
||||
type: NumberConstructor;
|
||||
value?: number;
|
||||
required?: boolean;
|
||||
};
|
||||
placeholder?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
required?: boolean;
|
||||
};
|
||||
value?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
required?: boolean;
|
||||
};
|
||||
};
|
||||
data: {
|
||||
prefix: string;
|
||||
classPrefix: string;
|
||||
count: number;
|
||||
};
|
||||
lifetimes: {
|
||||
ready(): void;
|
||||
};
|
||||
methods: {
|
||||
updateValue(value: any): void;
|
||||
onInput(event: any): void;
|
||||
onFocus(event: any): void;
|
||||
onBlur(event: any): void;
|
||||
onConfirm(event: any): void;
|
||||
onLineChange(event: any): void;
|
||||
};
|
||||
}
|
||||
83
components/textarea/textarea.js
Normal file
83
components/textarea/textarea.js
Normal file
@@ -0,0 +1,83 @@
|
||||
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 { getCharacterLength } from '../common/utils';
|
||||
const { prefix } = config;
|
||||
const name = `${prefix}-textarea`;
|
||||
let Textarea = class Textarea extends SuperComponent {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.options = {
|
||||
multipleSlots: true,
|
||||
};
|
||||
this.behaviors = ['wx://form-field'];
|
||||
this.externalClasses = [`${prefix}-class`, `${prefix}-class-textarea`, `${prefix}-class-label`];
|
||||
this.properties = Object.assign(Object.assign({}, props), { cursorSpacing: {
|
||||
type: Number,
|
||||
value: 0,
|
||||
} });
|
||||
this.data = {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
count: 0,
|
||||
};
|
||||
this.lifetimes = {
|
||||
ready() {
|
||||
const { value } = this.properties;
|
||||
this.updateValue(value);
|
||||
},
|
||||
};
|
||||
this.methods = {
|
||||
updateValue(value) {
|
||||
const { maxcharacter, maxlength } = this.properties;
|
||||
if (maxcharacter > 0 && !Number.isNaN(maxcharacter)) {
|
||||
const { length, characters } = getCharacterLength('maxcharacter', value, maxcharacter);
|
||||
this.setData({
|
||||
value: characters,
|
||||
count: length,
|
||||
});
|
||||
}
|
||||
else if (maxlength > 0 && !Number.isNaN(maxlength)) {
|
||||
const { length, characters } = getCharacterLength('maxlength', value, maxlength);
|
||||
this.setData({
|
||||
value: characters,
|
||||
count: length,
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.setData({
|
||||
value,
|
||||
count: value ? String(value).length : 0,
|
||||
});
|
||||
}
|
||||
},
|
||||
onInput(event) {
|
||||
const { value } = event.detail;
|
||||
this.updateValue(value);
|
||||
this.triggerEvent('change', { value: this.data.value });
|
||||
},
|
||||
onFocus(event) {
|
||||
this.triggerEvent('focus', Object.assign({}, event.detail));
|
||||
},
|
||||
onBlur(event) {
|
||||
this.triggerEvent('blur', Object.assign({}, event.detail));
|
||||
},
|
||||
onConfirm(event) {
|
||||
this.triggerEvent('enter', Object.assign({}, event.detail));
|
||||
},
|
||||
onLineChange(event) {
|
||||
this.triggerEvent('lineChange', Object.assign({}, event.detail));
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
Textarea = __decorate([
|
||||
wxComponent()
|
||||
], Textarea);
|
||||
export default Textarea;
|
||||
4
components/textarea/textarea.json
Normal file
4
components/textarea/textarea.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
30
components/textarea/textarea.wxml
Normal file
30
components/textarea/textarea.wxml
Normal file
@@ -0,0 +1,30 @@
|
||||
<view class="{{classPrefix}} {{prefix}}-class">
|
||||
<view class="{{classPrefix}}__name {{prefix}}-class-label">
|
||||
<view wx:if="{{ label && label.length > 0 }}">{{ label }}</view>
|
||||
<slot wx:else name="label" />
|
||||
</view>
|
||||
<view class="{{classPrefix}}__wrapper">
|
||||
<textarea
|
||||
disabled="{{disabled}}"
|
||||
placeholder="{{placeholder}}"
|
||||
class="{{classPrefix}}__wrapper-textarea {{prefix}}-class-textarea"
|
||||
placeholder-class="{{classPrefix}}__placeholder"
|
||||
value="{{value}}"
|
||||
auto-focus="{{autofocus}}"
|
||||
focus="{{focus}}"
|
||||
cursor-spacing="{{cursorSpacing}}"
|
||||
auto-height="{{autosize}}"
|
||||
adjust-position="{{adjustPosition}}"
|
||||
confirm-type="{{confirmType}}"
|
||||
confirm-hold="{{confirmHold}}"
|
||||
bindinput="onInput"
|
||||
bindfocus="onFocus"
|
||||
bindblur="onBlur"
|
||||
bindconfirm="onConfirm"
|
||||
bindlinechange="onLineChange"
|
||||
/>
|
||||
<view wx:if="{{maxcharacter || maxlength}}" class="{{classPrefix}}__count">
|
||||
{{count }} / {{maxcharacter || maxlength}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
81
components/textarea/textarea.wxss
Normal file
81
components/textarea/textarea.wxss
Normal file
@@ -0,0 +1,81 @@
|
||||
.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-textarea {
|
||||
position: relative;
|
||||
background-color: #fff;
|
||||
}
|
||||
.t-textarea__name:not(:empty) {
|
||||
position: relative;
|
||||
padding: 24rpx 32rpx;
|
||||
font-size: 32rpx;
|
||||
color: #000000;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.t-textarea__name:not(:empty)::after {
|
||||
position: absolute;
|
||||
box-sizing: border-box;
|
||||
content: ' ';
|
||||
pointer-events: none;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
border-bottom: 1px solid #e6e6e6;
|
||||
transform: scaleY(0.5);
|
||||
left: 32rpx;
|
||||
}
|
||||
.t-textarea__wrapper {
|
||||
padding: 24rpx 32rpx;
|
||||
font-size: 32rpx;
|
||||
color: #000000;
|
||||
}
|
||||
.t-textarea__wrapper-textarea {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
text-align: left;
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
resize: none;
|
||||
font-size: 32rpx;
|
||||
line-height: 48rpx;
|
||||
}
|
||||
.t-textarea__placeholder,
|
||||
.t-textarea__count {
|
||||
color: #888888;
|
||||
font-size: 32rpx;
|
||||
line-height: 48rpx;
|
||||
}
|
||||
.t-textarea__count {
|
||||
font-size: 24rpx;
|
||||
text-align: right;
|
||||
}
|
||||
67
components/textarea/type.d.ts
vendored
Normal file
67
components/textarea/type.d.ts
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
export interface TdTextareaProps {
|
||||
adjustPosition?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
required?: boolean;
|
||||
};
|
||||
autofocus?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
required?: boolean;
|
||||
};
|
||||
autosize?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
required?: boolean;
|
||||
};
|
||||
confirmHold?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
required?: boolean;
|
||||
};
|
||||
confirmType?: {
|
||||
type: StringConstructor;
|
||||
value?: 'send' | 'search' | 'next' | 'go' | 'done';
|
||||
required?: boolean;
|
||||
};
|
||||
disabled?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
required?: boolean;
|
||||
};
|
||||
externalClasses?: {
|
||||
type: ArrayConstructor;
|
||||
value?: ['t-class', 't-class-textarea', 't-class-placeholder', 't-class-name'];
|
||||
required?: boolean;
|
||||
};
|
||||
focus?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
required?: boolean;
|
||||
};
|
||||
label?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
required?: boolean;
|
||||
};
|
||||
maxcharacter?: {
|
||||
type: NumberConstructor;
|
||||
value?: number;
|
||||
required?: boolean;
|
||||
};
|
||||
maxlength?: {
|
||||
type: NumberConstructor;
|
||||
value?: number;
|
||||
required?: boolean;
|
||||
};
|
||||
placeholder?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
required?: boolean;
|
||||
};
|
||||
value?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
required?: boolean;
|
||||
};
|
||||
}
|
||||
1
components/textarea/type.js
Normal file
1
components/textarea/type.js
Normal file
@@ -0,0 +1 @@
|
||||
export {};
|
||||
Reference in New Issue
Block a user