diff --git a/example/app.json b/example/app.json
index c4bdc15e..5705f003 100644
--- a/example/app.json
+++ b/example/app.json
@@ -1,6 +1,7 @@
{
"pages": [
"pages/dashboard/index",
+ "pages/actionsheet/index",
"pages/btn/index",
"pages/badge/index",
"pages/capsule/index",
diff --git a/example/pages/actionsheet/index.js b/example/pages/actionsheet/index.js
new file mode 100644
index 00000000..b28c57df
--- /dev/null
+++ b/example/pages/actionsheet/index.js
@@ -0,0 +1,51 @@
+const { Actionsheet, extend } = require('../../dist/index');
+
+Page(extend({}, Actionsheet, {
+ data: {
+ baseActionsheet: {
+ show: false,
+ cancelText: '关闭 Action',
+ closeOnClickOverlay: true,
+ componentId: 'baseActionsheet',
+ actions: [{
+ name: '选项1',
+ subname: '选项描述语1',
+ className: 'action-class',
+ loading: false
+ }, {
+ name: '选项2',
+ subname: '选项描述语2',
+ className: 'action-class',
+ loading: false
+ }]
+ }
+ },
+
+ toggleActionsheet() {
+ this.setData({
+ 'baseActionsheet.show': true
+ });
+ },
+
+ handleZanActionsheetCancel({ componentId }) {
+ this.setData({
+ [`${componentId}.show`]: false
+ });
+ },
+
+ handleZanActionsheetClick({ componentId, index }) {
+ console.log(`item index ${index} clicked`);
+
+ this.setData({
+ [`${componentId}.actions[${index}].loading`]: true
+ });
+
+ setTimeout(() => {
+ this.setData({
+ [`${componentId}.show`]: false,
+ [`${componentId}.actions[${index}].loading`]: false
+ });
+ }, 1500);
+ }
+
+}));
diff --git a/example/pages/actionsheet/index.json b/example/pages/actionsheet/index.json
new file mode 100644
index 00000000..175d8120
--- /dev/null
+++ b/example/pages/actionsheet/index.json
@@ -0,0 +1,3 @@
+{
+ "navigationBarTitleText": "Actionsheet 行动按钮"
+}
diff --git a/example/pages/actionsheet/index.wxml b/example/pages/actionsheet/index.wxml
new file mode 100644
index 00000000..52c5659d
--- /dev/null
+++ b/example/pages/actionsheet/index.wxml
@@ -0,0 +1,15 @@
+
+
+
+
+ ACTIONSHEET
+
+
+
+
+
+
+
+
diff --git a/example/pages/dashboard/config.js b/example/pages/dashboard/config.js
index 73e1f07d..42029869 100644
--- a/example/pages/dashboard/config.js
+++ b/example/pages/dashboard/config.js
@@ -72,6 +72,9 @@ export default {
title: '操作反馈',
content: [
{
+ name: 'Actionsheet 行动按钮',
+ path: '/pages/actionsheet/index'
+ }, {
name: 'Dialog 弹出框',
path: '/pages/dialog/index'
}, {
diff --git a/packages/actionsheet/README.md b/packages/actionsheet/README.md
new file mode 100644
index 00000000..881f1453
--- /dev/null
+++ b/packages/actionsheet/README.md
@@ -0,0 +1,78 @@
+## Actionsheet 行动按钮
+
+### 使用指南
+在 app.wxss 中引入组件库所有样式
+```css
+@import "path/to/zanui-weapp/dist/index.wxss";
+```
+
+在需要使用的页面里引入组件库模板和脚本
+```html
+
+
+
+```
+```js
+const { Actionsheet, extend } = require('path/to/zanui-weapp/dist/index');
+
+// 在 Page 中混入 Actionsheet 里面声明的方法
+Page(extend({}, Actionsheet, {
+ data: {
+ actionsheet: {
+ show: false,
+ actions: []
+ }
+ }
+ // ...
+}));
+```
+
+### 代码演示
+#### 基础功能
+在 js 中设置传入的 show 为 true,即可展示出 actionsheet。actionsheet 会根据传入的 actions 展示按钮。
+```js
+this.setData({
+ 'actionsheet.show': true
+})
+```
+
+当行动按钮被点击或者弹层被关掉时,都可以在可以在页面中注册 `handleZanActionsheetClick` 和 `handleZanActionsheetCancel` 方法来监听。
+```js
+Page({
+ // 当行动按钮被关闭时,触发该函数
+ // componentId 即为在模板中传入的 componentId
+ // 用于在一个页面上使用多个 actionsheet 时,进行区分
+ handleZanActionsheetCancel({ componentId }) {
+ },
+
+ // 当行动按钮中有一个被点击时触发
+ // index 代表被点击按钮在传入参数 actions 中的位置
+ handleZanActionsheetClick({ componentId, index }) {
+ }
+});
+```
+
+#### `Actionsheet` 支持的具体参数如下
+| 参数 | 说明 | 类型 | 默认值 | 必须 |
+|-----------|-----------|-----------|-------------|-------------|
+| show | 用来表示是否展示行动按钮 | Boolean | false | |
+| cancelText | 行动按钮底部取消按钮的文案,不传则不显示取消按钮 | String | | |
+| closeOnClickOverlay | 是否在点击背景时,关闭行动按钮 | Boolean | false | |
+| componentId | 用于区分行动按钮之间的唯一名称 | String | | |
+| actions | 行动按钮的按钮显示配置 | Array | [] | |
+
+actions 的具体数据结构
+```js
+// actions 为数组结构传入
+[{
+ // 按钮文案
+ name: '选项1',
+ // 按钮描述文案,不传就不显示
+ subname: '选项描述语1',
+ // 按钮特殊类,可以通过传入这个,为按钮增加特殊样式
+ className: 'action-class',
+ // 按钮是否显示为 loading
+ loading: false
+}]
+```
+
diff --git a/packages/actionsheet/index.js b/packages/actionsheet/index.js
new file mode 100644
index 00000000..02a64544
--- /dev/null
+++ b/packages/actionsheet/index.js
@@ -0,0 +1,41 @@
+const { extractComponentId } = require('../common/helper');
+
+module.exports = {
+ _handleZanActionsheetMaskClick({ currentTarget = {} }) {
+ const dataset = currentTarget.dataset || {};
+ const { componentId, closeOnClickOverlay } = dataset;
+
+ // 判断是否在点击背景时需要关闭弹层
+ if (!closeOnClickOverlay) {
+ return;
+ }
+
+ resolveCancelClick.call(this, { componentId });
+ },
+
+ _handleZanActionsheetCancelBtnClick(e) {
+ const componentId = extractComponentId(e);
+
+ resolveCancelClick.call(this, { componentId });
+ },
+
+ _handleZanActionsheetBtnClick({ currentTarget = {} }) {
+ const dataset = currentTarget.dataset || {};
+ const { componentId, index } = dataset;
+
+ if (this.handleZanActionsheetClick) {
+ this.handleZanActionsheetClick({ componentId, index });
+ } else {
+ console.warn('页面缺少 handleZanActionsheetClick 回调函数');
+ }
+ }
+};
+
+function resolveCancelClick({ componentId }) {
+ console.info('[zan:actionsheet:cancel]');
+ if (this.handleZanActionsheetCancel) {
+ this.handleZanActionsheetCancel({ componentId });
+ } else {
+ console.warn('页面缺少 handleZanActionsheetCancel 回调函数');
+ }
+}
diff --git a/packages/actionsheet/index.pcss b/packages/actionsheet/index.pcss
new file mode 100644
index 00000000..349c2642
--- /dev/null
+++ b/packages/actionsheet/index.pcss
@@ -0,0 +1,71 @@
+@import "../common/_var";
+@import "../common/_mixins";
+
+.zan-actionsheet {
+ background-color: #f8f8f8;
+}
+
+.zan-actionsheet__mask {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ z-index: 10;
+ background: rgba(0, 0, 0, 0.7);
+ display: none;
+}
+
+.zan-actionsheet__container {
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: $background-color;
+ transform: translate3d(0, 50%, 0);
+ transform-origin: center;
+ transition: all 0.2s ease;
+ z-index: 11;
+ opacity: 0;
+}
+
+.zan-actionsheet__btn.zan-btn {
+ height: 50px;
+ line-height: 50px;
+ margin-bottom: 0;
+
+ &::after {
+ border-width: 0;
+ border-bottom-width: 1px;
+ }
+}
+
+.zan-actionsheet__btn.zan-btn:last-child {
+ &::after {
+ border-bottom-width: 0;
+ }
+}
+
+.zan-actionsheet__subname {
+ margin-left: 2px;
+ font-size: 12px;
+ color: $gray-darker;
+}
+
+.zan-actionsheet__footer {
+ margin-top: 10px;
+}
+
+/* btn-loading 状态 */
+.zan-actionsheet__btn.zan-btn--loading .zan-actionsheet__subname {
+ color: transparent;
+}
+
+/* zan-actionsheet 展示出来的样式 */
+.zan-actionsheet--show .zan-actionsheet__container {
+ opacity: 1;
+ transform: translate3d(0, 0, 0);
+}
+.zan-actionsheet--show .zan-actionsheet__mask {
+ display: block;
+}
diff --git a/packages/actionsheet/index.wxml b/packages/actionsheet/index.wxml
new file mode 100644
index 00000000..9c77dddf
--- /dev/null
+++ b/packages/actionsheet/index.wxml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+ {{ item.name }}
+ {{ item.subname }}
+
+
+
+
+
+
+
diff --git a/packages/index.js b/packages/index.js
index ebfb8bbc..24195ba4 100644
--- a/packages/index.js
+++ b/packages/index.js
@@ -1,3 +1,4 @@
+exports.Actionsheet = require('./actionsheet/index');
exports.CheckLabel = require('./select/index');
exports.Dialog = require('./dialog/index');
exports.Field = require('./field/index');
diff --git a/packages/index.pcss b/packages/index.pcss
index 6a4e0079..95916492 100644
--- a/packages/index.pcss
+++ b/packages/index.pcss
@@ -1,3 +1,4 @@
+@import "actionsheet/index.pcss";
@import "badge/index.pcss";
@import "btn/index.pcss";
@import "capsule/index.pcss";