[refactor] Field & Stepper 自定义组件改造 (#168)

* [refactor] Field & Stepper 自定义组件改造

* Field & Stepper remove componentId
This commit is contained in:
张敏 2018-03-28 15:10:35 +08:00 committed by Yao
parent 9d2ad7e092
commit a0dcec4dc5
17 changed files with 437 additions and 338 deletions

View File

@ -54,6 +54,7 @@ module.exports = {
// Form 中使用输入框
form: {
name: {
name: 'name',
placeholder: '请输入收货人姓名',
componentId: 'form:test:name'
},

View File

@ -1,7 +1,6 @@
const Zan = require('../../dist/index');
const config = require('./config');
Page(Object.assign({}, Zan.Field, {
Page(Object.assign({}, {
data: {
config,
value: 'test',
@ -24,21 +23,21 @@ Page(Object.assign({}, Zan.Field, {
},
handleZanFieldChange(e) {
const { componentId, detail } = e;
const { detail } = e;
console.log('[zan:field:change]', componentId, detail);
console.log('[zan:field:change]', detail);
},
handleZanFieldFocus(e) {
const { componentId, detail } = e;
const { detail } = e;
console.log('[zan:field:focus]', componentId, detail);
console.log('[zan:field:focus]', detail);
},
handleZanFieldBlur(e) {
const { componentId, detail } = e;
const { detail } = e;
console.log('[zan:field:blur]', componentId, detail);
console.log('[zan:field:blur]', detail);
},
clearInput() {

View File

@ -1,3 +1,6 @@
{
"navigationBarTitleText": "Field 输入框"
"navigationBarTitleText": "Field 输入框",
"usingComponents": {
"zan-field": "../../dist/field/index"
}
}

View File

@ -1,67 +1,106 @@
<import src="/dist/field/index.wxml" />
<view class="container">
<view class="doc-title zan-hairline--bottom">Field</view>
<doc-page title="Field">
<!-- Field 基础用法 -->
<view class="zan-panel-title">基础用法</view>
<view class="zan-panel">
<template
is="zan-field"
data="{{ ...config.base.name, value }}"></template>
<template
is="zan-field"
data="{{ ...config.base.tel }}"></template>
<template
is="zan-field"
data="{{ ...config.base.address }}"></template>
<template
is="zan-field"
data="{{ ...config.base.disabled }}"></template>
<zan-field
title="{{ config.base.name.title }}"
placeholder="{{ config.base.name.placeholder }}"
focus="{{ config.base.name.focus }}"
value="{{ value }}"
>
</zan-field>
<zan-field
title="{{ config.base.tel.title }}"
placeholder="{{ config.base.tel.placeholder }}"
error="{{ config.base.tel.error }}"
input-type="{{ config.base.tel.inputType }}"
>
</zan-field>
<zan-field
title="{{ config.base.address.title }}"
type="{{ config.base.address.type }}"
placeholder="{{ config.base.address.placeholder }}"
>
</zan-field>
<zan-field
title="{{ config.base.disabled.title }}"
value="{{ config.base.disabled.value }}"
disabled="{{ config.base.disabled.disabled }}"
>
</zan-field>
</view>
<view class="zan-btns">
<button
class="zan-btn zan-btn--primary"
bindtap="clearInput">清除输入</button>
bindtap="clearInput"
>
清除输入
</button>
</view>
<!-- 去除标题后的输入框样式 -->
<view class="zan-panel-title">无标题输入框</view>
<view class="zan-panel">
<template
is="zan-field"
data="{{ ...config.notitle, value: textareaValue }}"></template>
<zan-field
placeholder="{{ config.notitle.placeholder }}"
value="{{ textareaValue }}"
>
</zan-field>
</view>
<view class="zan-btns">
<button
class="zan-btn zan-btn--primary"
bindtap="clearTextarea">清除输入</button>
bindtap="clearTextarea"
>
清除输入
</button>
</view>
<!-- 使用 Field 圆角样式 -->
<view class="zan-panel-title field__title--radius">圆角输入框</view>
<template
is="zan-field"
data="{{ ...config.radius.totalPrice }}"></template>
<template
is="zan-field"
data="{{ ...config.radius.excludePrice }}"></template>
<template
is="zan-field"
data="{{ ...config.radius.notitle }}"></template>
<zan-field
title="{{ config.radius.totalPrice.title }}"
type="{{ config.radius.totalPrice.type }}"
placeholder="{{ config.radius.totalPrice.placeholder }}"
right="{{ config.radius.totalPrice.right }}"
mode="{{ config.radius.totalPrice.mode }}"
>
</zan-field>
<zan-field
class="zan-field--radius"
title="{{ config.radius.excludePrice.title }}"
type="{{ config.radius.excludePrice.type }}"
placeholder="{{ config.radius.excludePrice.placeholder }}"
right="{{ config.radius.excludePrice.right }}"
mode="{{ config.radius.excludePrice.mode }}"
error="{{ config.radius.excludePrice.error }}"
>
</zan-field>
<zan-field
placeholder="{{ config.radius.notitle.placeholder }}"
mode="{{ config.radius.notitle.mode }}"
input-type="{{ config.radius.notitle.inputTitle }}"
>
</zan-field>
<!-- form 中使用 Field -->
<view class="zan-panel-title">Form 表单中的field应用</view>
<form bindsubmit="formSubmit" bindreset="formReset">
<view class="zan-panel">
<template
is="zan-field"
data="{{ ...config.form.name }}"></template>
<template
is="zan-field"
data="{{ ...config.form.tel }}"></template>
<zan-field
name="{{ config.form.name.name }}"
placeholder="{{ config.form.name.placeholder }}"
>
</zan-field>
<zan-field
name="{{ config.form.tel.name }}"
placeholder="{{ config.form.tel.placeholder }}"
input-type="{{ config.form.tel.inputType }}"
>
</zan-field>
<view class="zan-btns">
<button
class="zan-btn zan-btn--primary"
@ -75,45 +114,6 @@
<view class="zan-panel-title">自定义显示内容</view>
<view class="zan-panel">
<!-- 配合 popup 使用 picker-view -->
<view class="zan-cell zan-field">
<view class="zan-cell__hd zan-field__title">人员信息</view>
<view
class="zan-field__input zan-cell__bd"
bindtap="handleDateFieldClick"
>
出生日期: {{ pickerViewConfig.year[pickerViewConfig.value[0]] }}
性别: {{ pickerViewConfig.sex[pickerViewConfig.value[1]] }}
</view>
</view>
<!-- 对应的 popup 层 -->
<view
class="zan-popup zan-popup--bottom {{ pickerViewConfig.show ? 'zan-popup--show' : ''}}"
>
<view class="zan-popup__mask" bindtap="hideDatePopup"></view>
<view class="zan-popup__container popup-field-example--bottom">
<picker-view
value="{{ pickerViewConfig.value }}"
indicator-style="height: 50px"
class="picker-view-example"
bindchange="handlePopupDateChange"
>
<picker-view-column>
<view
class="picker-view-column-example"
wx:for="{{ pickerViewConfig.year }}"
>{{item}}年</view>
</picker-view-column>
<picker-view-column>
<view
class="picker-view-column-example"
wx:for="{{ pickerViewConfig.sex }}"
>{{item}}</view>
</picker-view-column>
</picker-view>
</view>
</view>
<!-- 简单 picker 示例 -->
<view class="zan-cell zan-field">
<view class="zan-cell__hd zan-field__title">选择区域</view>
@ -139,4 +139,4 @@
</view>
</view>
</view>
</view>
</doc-page>

View File

@ -1,5 +1,5 @@
<doc-page title="ICON">
<view wx:for="{{ icons }}" wx:for-item="icon" class="icon-wrap">
<view wx:for="{{ icons }}" wx:for-item="icon" wx:key="icon" class="icon-wrap">
<view class="example-icon">
<zan-icon type="{{ icon }}"></zan-icon>
</view>

View File

@ -1,6 +1,4 @@
var Zan = require('../../dist/index');
Page(Object.assign({}, Zan.Stepper, {
Page(Object.assign({}, {
data: {
stepper1: {
stepper: 10,
@ -8,20 +6,21 @@ Page(Object.assign({}, Zan.Stepper, {
max: 20
},
stepper2: {
stepper: 1,
stepper: 10,
min: 1,
max: 1
max: 20
},
stepper3: {
stepper: 10,
min: 1,
max: 20
max: 20,
step: 2
}
},
handleZanStepperChange(e) {
var componentId = e.componentId;
var stepper = e.stepper;
const componentId = e.target.dataset.componentId;
const stepper = e.detail;
this.setData({
[`${componentId}.stepper`]: stepper

View File

@ -1,3 +1,6 @@
{
"navigationBarTitleText": "Stepper 计数器"
"navigationBarTitleText": "Stepper 计数器",
"usingComponents": {
"zan-stepper": "../../dist/stepper/index"
}
}

View File

@ -1,20 +1,40 @@
<import src="/dist/stepper/index.wxml" />
<view class="container">
<view class="doc-title zan-hairline--bottom">Stepper</view>
<doc-page title="Stepper">
<view class="zan-panel-title">基础用法</view>
<view style="padding: 40px 15px">
<template is="zan-stepper" data="{{ ...stepper1, componentId: 'stepper1' }}" />
</view>
<!-- 当最大值等于最小值时,组件不可用 -->
<view style="padding: 40px 15px ">
<template is="zan-stepper" data="{{ ...stepper2, componentId: 'stepper2' }}" />
<zan-stepper
stepper="{{ stepper1.stepper }}"
min="{{ stepper1.min }}"
max="{{ stepper1.max }}"
data-component-id="stepper1"
bind:change="handleZanStepperChange"
>
</zan-stepper>
</view>
<!-- small size -->
<view style="padding: 40px 15px ">
<template is="zan-stepper" data="{{ ...stepper3, componentId: 'stepper3', size: 'small' }}" />
<view class="zan-panel-title">不同尺寸</view>
<view style="padding: 40px 15px">
<zan-stepper
stepper="{{ stepper2.stepper }}"
min="{{ stepper2.min }}"
max="{{ stepper2.max }}"
size="small"
data-component-id="stepper2"
bind:change="handleZanStepperChange"
>
</zan-stepper>
</view>
</view>
<view class="zan-panel-title">高级用法</view>
<view style="padding: 40px 15px">
<zan-stepper
stepper="{{ stepper3.stepper }}"
min="{{ stepper3.min }}"
max="{{ stepper3.max }}"
step="{{ stepper3.step }}"
data-component-id="stepper3"
bind:change="handleZanStepperChange"
>
</zan-stepper>
</view>
</doc-page>

View File

@ -1,55 +1,87 @@
## Field 输入框
### 使用指南
在 app.wxss 中引入组件库所有样式
```css
@import "path/to/zanui-weapp/dist/index.wxss";
```
在需要使用的页面里引入组件库模板和脚本
```html
<import src="path/to/zanui-weapp/dist/field/index.wxml" />
<!-- 直接使用 zan-field 模板,并且直接传入设置值 -->
<template is="zan-field" data="{{ value }}"></template>
```
```js
const { Field, extend } = require('path/to/zanui-weapp/dist/index');
// 在 Page 中混入 Field 里面声明的方法
Page(extend({}, Field, {
// ...
}));
在 index.json 中引入组件
```json
{
"usingComponents": {
"zan-field": "path/to/zanui-weapp/dist/field/index"
}
}
```
### 代码演示
#### 基础用法
field 支持多种展示方式,在 `data` 中传入对应的设置即可。
```html
<template is="zan-field" data="{{ title: '收货人', type: 'input', placeholder: '名字', value }}"></template>
<zan-field
title="{{ field.title }}"
placeholder="{{ field.placeholder }}"
focus="{{ field.focus }}"
value="{{ field.value }}"
>
</zan-field>
```
当 field 触发输入事件时,可以在页面中注册 handleZanFieldChange 方法来监听
```js
Page(extend({}, Field, {
// 输入框内容更改时触发
handleZanFieldChange({ componentId, detail }) {
/*
* componentId 即为在模板中传入的 componentId
* 用于在一个页面上使用多个 tab 时,进行区分
* detail 即输入框中的内容
*/
/*
* 处理函数可以直接 return 一个字符串,将替换输入框的内容。
*/
},
// 输入框聚焦时触发
handleZanFieldFocus({ componentId, detail }) {},
// 输入框失焦时触发
handleZanFieldBlur({ componentId, detail }) {},
Page(extend({}, {
data: {
field: {
focus: true,
title: '收货人',
placeholder: '名字',
value: 'test'
}
}
}));
```
`Field` 支持传入参数如下
#### 监听事件
field会触发一些事件当你需要监听这些事件时可以绑定对应的事件。
```html
<zan-field
title="{{ field.title }}"
placeholder="{{ field.placeholder }}"
focus="{{ field.focus }}"
value="{{ field.value }}"
bind:change="handleFieldChange"
bind:focus="handleFieldFocus"
bind:blur="handleFieldBlur"
>
</zan-field>
```
```js
Page(extend({}, {
data: {
field: {
focus: true,
title: '收货人',
placeholder: '名字',
value: 'test'
}
},
methods: {
handleFieldChange(event) {
console.log(event);
},
handleFieldFocus(event) {
console.log(event);
},
handleFieldBlur(event) {
console.log(event);
}
}
}));
```
### API
| 参数 | 说明 | 类型 | 默认值 | 必须 |
|-----------|-----------|-----------|-------------|-------------|
@ -65,3 +97,11 @@ Page(extend({}, Field, {
| right | 输入框内容是否居右显示 | Boolean | false | |
| error | 是否显示为输入框错误情况下的样式 | Boolean | false | |
| componentId | 用于区分输入框之间的唯一名称 | String | - | |
### Event
| 事件名称 | 说明 | 回调参数 |
|-----------|-----------|-----------|
| change | 当绑定值变化时触发的事件 | event对象 |
| focus | 输入框focus | event对象 |
| blur | 输入框blur | event对象 |

View File

@ -1,38 +1,44 @@
const { extractComponentId } = require('../common/helper');
module.exports = {
_handleZanFieldChange(event) {
const componentId = extractComponentId(event);
event.componentId = componentId;
console.info('[zan:field:change]', event);
if (this.handleZanFieldChange) {
return this.handleZanFieldChange(event);
}
console.warn('页面缺少 handleZanFieldChange 回调函数');
Component({
properties: {
title: String,
name: String,
type: {
type: String,
value: 'input'
},
name: String,
value: String,
disabled: Boolean,
inputType: {
type: String,
value: 'text'
},
placeholder: String,
focus: Boolean,
mode: {
type: String,
value: 'normal'
},
right: Boolean,
error: Boolean
},
_handleZanFieldFocus(event) {
const componentId = extractComponentId(event);
event.componentId = componentId;
console.info('[zan:field:focus]', event);
if (this.handleZanFieldFocus) {
return this.handleZanFieldFocus(event);
}
},
_handleZanFieldBlur(event) {
const componentId = extractComponentId(event);
event.componentId = componentId;
console.info('[zan:field:blur]', event);
if (this.handleZanFieldBlur) {
return this.handleZanFieldBlur(event);
methods: {
handleZanFieldChange(event) {
console.info('[zan:field:change]', event);
this.triggerEvent('change', event);
},
handleZanFieldFocus(event) {
console.info('[zan:field:focus]', event);
this.triggerEvent('focus', event);
},
handleZanFieldBlur(event) {
console.info('[zan:field:blur]', event);
this.triggerEvent('blur', event);
}
}
};
})

View File

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

View File

@ -6,7 +6,7 @@
}
.zan-field--wrapped {
margin: 0 15px;
margin: 10px 15px;
background-color: #fff;
&::after {
@ -21,16 +21,12 @@
display: block;
}
.zan-field--wrapped + .zan-field--wrapped {
margin-top: 10px;
}
.zan-field--error {
color: #f40;
}
/* 圆角输入框出现错误时,将边框也置红 */
.zan-field--wrapped.zan-field--error::after {
.zan-field--wrapped.zan-field--error::after {
border-color: #f40;
}

View File

@ -1,35 +1,35 @@
<template name="zan-field">
<view class="zan-cell zan-field {{ error ? 'zan-field--error' : '' }} {{ mode === 'wrapped' ? 'zan-field--wrapped' : '' }}">
<view
wx:if="{{ title }}"
class="zan-cell__hd zan-field__title">{{ title }}</view>
<textarea
wx:if="{{ type === 'textarea' }}"
auto-height
name="{{ name || componentId || '' }}"
disabled="{{ disabled }}"
focus="{{ focus }}"
value="{{ value }}"
placeholder="{{ placeholder }}"
class="zan-field__input zan-cell__bd {{ right ? 'zan-field__input--right' : '' }}"
placeholder-class="zan-field__placeholder"
bindinput="_handleZanFieldChange"
bindfocus="_handleZanFieldFocus"
bindblur="_handleZanFieldBlur"
data-component-id="{{ componentId || '' }}"></textarea>
<input
wx:else
type="{{ inputType || 'text' }}"
name="{{ name || componentId || '' }}"
disabled="{{ disabled }}"
focus="{{ focus }}"
value="{{ value }}"
placeholder="{{ placeholder }}"
class="zan-field__input zan-cell__bd {{ right ? 'zan-field__input--right' : '' }}"
placeholder-class="zan-field__placeholder"
bindinput="_handleZanFieldChange"
bindfocus="_handleZanFieldFocus"
bindblur="_handleZanFieldBlur"
data-component-id="{{ componentId || '' }}"/>
<view class="zan-cell zan-field {{ error ? 'zan-field--error' : '' }} {{ mode === 'wrapped' ? 'zan-field--wrapped' : '' }}">
<view
wx:if="{{ title }}"
class="zan-cell__hd zan-field__title">
{{ title }}
</view>
</template>
<textarea
wx:if="{{ type === 'textarea' }}"
auto-height
name="{{ name || '' }}"
disabled="{{ disabled }}"
focus="{{ focus }}"
value="{{ value }}"
placeholder="{{ placeholder }}"
class="zan-field__input zan-cell__bd {{ right ? 'zan-field__input--right' : '' }}"
placeholder-class="zan-field__placeholder"
bindinput="handleZanFieldChange"
bindfocus="handleZanFieldFocus"
bindblur="handleZanFieldBlur">
</textarea>
<input
wx:else
type="{{ inputType || 'text' }}"
name="{{ name || '' }}"
disabled="{{ disabled }}"
focus="{{ focus }}"
value="{{ value }}"
placeholder="{{ placeholder }}"
class="zan-field__input zan-cell__bd {{ right ? 'zan-field__input--right' : '' }}"
placeholder-class="zan-field__placeholder"
bindinput="handleZanFieldChange"
bindfocus="handleZanFieldFocus"
bindblur="handleZanFieldBlur"
/>
</view>

View File

@ -1,45 +1,32 @@
## Stepper 计数器
### 使用指南
在 app.wxss 中引入组件库所有样式
```css
@import "path/to/zanui-weapp/dist/index.wxss";
```
在需要使用的页面里引入组件库模板和脚本
```html
<import src="path/to/zanui-weapp/dist/stepper/index.wxml" />
<template is="zan-stepper" data="{{ ...stepper, componentId: 'stepper' }}"></template>
```
```js
const { extend, Stepper } = require('path/to/zanui-weapp/dist/index');
// 在 Page 中混入 Stepper 里面声明的方法
Page(extend({}, Stepper, {
// ...
}));
在 index.json 中引入组件
```json
{
"usingComponents": {
"zan-stepper": "path/to/zanui-weapp/dist/stepper/index"
}
}
```
### 代码演示
#### 基础功能
#### 基础用法
`Stepper` 组件通过传入的 stepper 对象控制,内部数据格式如下:
```js
const stepper = {
// 当前 stepper 数字
stepper: 1,
// 最小可到的数字
min: 1,
// 最大可到的数字
max: 1
};
```
Page(extend({}, {
data: {
stepper: {
// 当前 stepper 数字
stepper: 1,
// 最小可到的数字
min: 1,
// 最大可到的数字
max: 1
}
},
当一个 `Stepper`min 超过 max就会导致组件被置灰
当 stepper 被点击时,可以在页面中注册 handleZanStepperChange 方法来监听
```js
Page(extend({}, Stepper, {
handleZanStepperChange({ componentId, stepper }) {
// componentId 即为在模板中传入的 componentId
// 用于在一个页面上使用多个 stepper 时,进行区分
@ -50,3 +37,37 @@ Page(extend({}, Stepper, {
}
}));
```
当一个 `Stepper`min 超过 max就会导致组件被置灰。
当 stepper 被点击时,需要监听`change`事件,处理计数器值的改变。
```js
<zan-stepper
stepper="{{ stepper.stepper }}"
min="{{ stepper.min }}"
max="{{ stepper.max }}"
component-id="stepper"
bind:change="handleZanStepperChange"
>
</zan-stepper>
```
### API
| 参数 | 说明 | 类型 | 默认值 | 必须 |
|-----------|-----------|-----------|-------------|-------------|
| size | 计数器尺寸 | String | - | |
| stepper | 计数器的值 | Number | `1` | 必须 |
| min | 计数器最小值 | Number | `1` | |
| max | 计数器最大值 | Number | 无穷大 | |
| step | 步数 | Number | `1` | |
| componentId | 用于区分输入框之间的唯一名称 | String | - | |
### Event
| 事件名称 | 说明 | 回调参数 |
|-----------|-----------|-----------|
| change | 当绑定值变化时触发的事件 | `{ index, stepper }` |
| minus | 点击减少按钮时触发 | - |
| plus | 点击增加按钮时触发 | - |

View File

@ -1,61 +1,71 @@
function handle(e, num) {
var dataset = e.currentTarget.dataset;
var componentId = dataset.componentId;
var disabled = dataset.disabled;
var stepper = +dataset.stepper;
if (disabled) return null;
callback.call(this, componentId, stepper + num);
}
function callback(componentId, stepper) {
stepper = +stepper;
var e = { componentId, stepper };
console.info('[zan:stepper:change]', e);
if (this.handleZanStepperChange) {
this.handleZanStepperChange(e);
} else {
console.warn('页面缺少 handleZanStepperChange 回调函数');
}
}
var Stepper = {
_handleZanStepperMinus(e) {
handle.call(this, e, -1);
Component({
properties: {
size: String,
stepper: {
type: Number,
value: 1
},
min: {
type: Number,
value: 1
},
max: {
type: Number,
value: Infinity
},
step: {
type: Number,
value: 1
}
},
_handleZanStepperPlus(e) {
handle.call(this, e, +1);
},
methods: {
handleZanStepperChange(e, type) {
const dataset = e.currentTarget.dataset;
const disabled = dataset.disabled;
const { step } = this.data;
let stepper = this.data.stepper;
_handleZanStepperBlur(e) {
var dataset = e.currentTarget.dataset;
var componentId = dataset.componentId;
var max = +dataset.max;
var min = +dataset.min;
var value = e.detail.value;
if (disabled) return null;
if (!value) {
setTimeout(() => {
callback.call(this, componentId, min);
}, 16);
callback.call(this, componentId, value);
return '' + value;
if (type === 'minus') {
stepper -= step;
} else if (type === 'plus') {
stepper += step;
}
this.triggerEvent('change', stepper);
this.triggerEvent(type);
},
handleZanStepperMinus(e) {
this.handleZanStepperChange(e, 'minus');
},
handleZanStepperPlus(e) {
this.handleZanStepperChange( e, 'plus');
},
handleZanStepperBlur(e) {
const dataset = e.currentTarget.dataset;
let value = e.detail.value;
const { min, max } = this.data;
if (!value) {
setTimeout(() => {
this.triggerEvent('change', min);
}, 16);
return;
}
value = +value;
if (value > max) {
value = max;
} else if (value < min) {
value = min;
}
this.triggerEvent('change', value);
}
value = +value;
if (value > max) {
value = max;
} else if (value < min) {
value = min;
}
callback.call(this, componentId, value);
return '' + value;
}
};
module.exports = Stepper;
});

View File

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

View File

@ -1,28 +1,23 @@
<template name="zan-stepper">
<view class="zan-stepper {{ size === 'small' ? 'zan-stepper--small' : '' }}">
<view
class="zan-stepper__minus {{ stepper <= min ? 'zan-stepper--disabled' : '' }}"
data-component-id="{{ componentId }}"
data-stepper="{{ stepper }}"
data-disabled="{{ stepper <= min }}"
bindtap="_handleZanStepperMinus"
>-</view>
<input
class="zan-stepper__text {{ min >= max ? 'zan-stepper--disabled' : '' }}"
type="number"
data-component-id="{{ componentId }}"
data-min="{{ min }}"
data-max="{{ max }}"
value="{{ stepper }}"
disabled="{{ min >= max }}"
bindblur="_handleZanStepperBlur"
></input>
<view
class="zan-stepper__plus {{ stepper >= max ? 'zan-stepper--disabled' : '' }}"
data-component-id="{{ componentId }}"
data-stepper="{{ stepper }}"
data-disabled="{{ stepper >= max }}"
bindtap="_handleZanStepperPlus"
>+</view>
<view class="zan-stepper {{ size === 'small' ? 'zan-stepper--small' : '' }}">
<view
class="zan-stepper__minus {{ stepper <= min ? 'zan-stepper--disabled' : '' }}"
data-disabled="{{ stepper <= min }}"
bindtap="handleZanStepperMinus"
>
-
</view>
</template>
<input
class="zan-stepper__text {{ min >= max ? 'zan-stepper--disabled' : '' }}"
type="number"
value="{{ stepper }}"
disabled="{{ min >= max }}"
bindblur="handleZanStepperBlur"
/>
<view
class="zan-stepper__plus {{ stepper >= max ? 'zan-stepper--disabled' : '' }}"
data-disabled="{{ stepper >= max }}"
bindtap="handleZanStepperPlus"
>
+
</view>
</view>