From ec41ce736dd8093fe9afeaea6ff007602a3cb2ef Mon Sep 17 00:00:00 2001 From: limqhz Date: Thu, 24 Nov 2022 17:07:38 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E6=98=8E=E7=BB=86=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.json | 10 +- components/button/README.md | 88 ++++ components/button/button.d.ts | 31 ++ components/button/button.js | 89 ++++ components/button/button.json | 7 + components/button/button.wxml | 58 +++ components/button/button.wxss | 248 +++++++++++ components/button/index.d.ts | 3 + components/button/index.js | 3 + components/button/props.d.ts | 3 + components/button/props.js | 101 +++++ components/button/type.d.ts | 108 +++++ components/button/type.js | 1 + components/cell/README.md | 57 +++ components/cell/cell.d.ts | 14 + components/cell/cell.js | 51 +++ components/cell/cell.json | 6 + components/cell/cell.wxml | 40 ++ components/cell/cell.wxss | 122 ++++++ components/cell/props.d.ts | 3 + components/cell/props.js | 51 +++ components/cell/type.d.ts | 72 ++++ components/cell/type.js | 1 + components/date-time-picker/README.md | 67 +++ .../date-time-picker/date-time-picker.d.ts | 107 +++++ .../date-time-picker/date-time-picker.js | 405 ++++++++++++++++++ .../date-time-picker/date-time-picker.json | 7 + .../date-time-picker/date-time-picker.wxml | 18 + .../date-time-picker/date-time-picker.wxss | 0 components/date-time-picker/dayjs/index.js | 1 + components/date-time-picker/locale/en.d.ts | 12 + components/date-time-picker/locale/en.js | 11 + components/date-time-picker/locale/zh.d.ts | 12 + components/date-time-picker/locale/zh.js | 11 + components/date-time-picker/props.d.ts | 3 + components/date-time-picker/props.js | 51 +++ components/date-time-picker/type.d.ts | 57 +++ components/date-time-picker/type.js | 1 + components/fab/README.md | 44 ++ components/fab/fab.d.ts | 20 + components/fab/fab.js | 47 ++ components/fab/fab.json | 6 + components/fab/fab.wxml | 8 + components/fab/fab.wxss | 52 +++ components/fab/props.d.ts | 3 + components/fab/props.js | 18 + components/fab/type.d.ts | 18 + components/fab/type.js | 1 + components/input/README.md | 129 ++++++ components/input/input.d.ts | 26 ++ components/input/input.js | 93 ++++ components/input/input.json | 6 + components/input/input.wxml | 66 +++ components/input/input.wxss | 180 ++++++++ components/input/props.d.ts | 3 + components/input/props.js | 152 +++++++ components/input/type.d.ts | 166 +++++++ components/input/type.js | 1 + components/loading/README.md | 70 +++ components/loading/index.d.ts | 3 + components/loading/index.js | 3 + components/loading/loading.d.ts | 77 ++++ components/loading/loading.js | 61 +++ components/loading/loading.json | 4 + components/loading/loading.wxml | 47 ++ components/loading/loading.wxss | 235 ++++++++++ components/loading/props.d.ts | 3 + components/loading/props.js | 51 +++ components/loading/type.d.ts | 54 +++ components/loading/type.js | 1 + components/picker/README.md | 57 +++ components/picker/picker-item-props.d.ts | 3 + components/picker/picker-item-props.js | 10 + components/picker/picker-item.d.ts | 24 ++ components/picker/picker-item.js | 110 +++++ components/picker/picker-item.json | 4 + components/picker/picker-item.wxml | 16 + components/picker/picker-item.wxss | 47 ++ components/picker/picker.d.ts | 30 ++ components/picker/picker.js | 108 +++++ components/picker/picker.json | 6 + components/picker/picker.wxml | 20 + components/picker/picker.wxss | 119 +++++ components/picker/props.d.ts | 3 + components/picker/props.js | 41 ++ components/picker/type.d.ts | 59 +++ components/picker/type.js | 1 + components/textarea/README.md | 78 ++++ components/textarea/props.d.ts | 3 + components/textarea/props.js | 51 +++ components/textarea/textarea.d.ts | 95 ++++ components/textarea/textarea.js | 83 ++++ components/textarea/textarea.json | 4 + components/textarea/textarea.wxml | 30 ++ components/textarea/textarea.wxss | 81 ++++ components/textarea/type.d.ts | 67 +++ components/textarea/type.js | 1 + pages/foot-tab/foot-tab.js | 2 +- pages/{today => task}/index.js | 86 ++-- pages/{today => task}/index.json | 3 +- pages/{today => task}/index.wxml | 13 +- pages/{today => task}/index.wxss | 7 +- pages/taskDetail/index.js | 52 +++ pages/taskDetail/index.json | 5 + pages/taskDetail/index.wxml | 25 ++ pages/taskDetail/index.wxss | 18 + 106 files changed, 4892 insertions(+), 48 deletions(-) create mode 100644 components/button/README.md create mode 100644 components/button/button.d.ts create mode 100644 components/button/button.js create mode 100644 components/button/button.json create mode 100644 components/button/button.wxml create mode 100644 components/button/button.wxss create mode 100644 components/button/index.d.ts create mode 100644 components/button/index.js create mode 100644 components/button/props.d.ts create mode 100644 components/button/props.js create mode 100644 components/button/type.d.ts create mode 100644 components/button/type.js create mode 100644 components/cell/README.md create mode 100644 components/cell/cell.d.ts create mode 100644 components/cell/cell.js create mode 100644 components/cell/cell.json create mode 100644 components/cell/cell.wxml create mode 100644 components/cell/cell.wxss create mode 100644 components/cell/props.d.ts create mode 100644 components/cell/props.js create mode 100644 components/cell/type.d.ts create mode 100644 components/cell/type.js create mode 100644 components/date-time-picker/README.md create mode 100644 components/date-time-picker/date-time-picker.d.ts create mode 100644 components/date-time-picker/date-time-picker.js create mode 100644 components/date-time-picker/date-time-picker.json create mode 100644 components/date-time-picker/date-time-picker.wxml create mode 100644 components/date-time-picker/date-time-picker.wxss create mode 100644 components/date-time-picker/dayjs/index.js create mode 100644 components/date-time-picker/locale/en.d.ts create mode 100644 components/date-time-picker/locale/en.js create mode 100644 components/date-time-picker/locale/zh.d.ts create mode 100644 components/date-time-picker/locale/zh.js create mode 100644 components/date-time-picker/props.d.ts create mode 100644 components/date-time-picker/props.js create mode 100644 components/date-time-picker/type.d.ts create mode 100644 components/date-time-picker/type.js create mode 100644 components/fab/README.md create mode 100644 components/fab/fab.d.ts create mode 100644 components/fab/fab.js create mode 100644 components/fab/fab.json create mode 100644 components/fab/fab.wxml create mode 100644 components/fab/fab.wxss create mode 100644 components/fab/props.d.ts create mode 100644 components/fab/props.js create mode 100644 components/fab/type.d.ts create mode 100644 components/fab/type.js create mode 100644 components/input/README.md create mode 100644 components/input/input.d.ts create mode 100644 components/input/input.js create mode 100644 components/input/input.json create mode 100644 components/input/input.wxml create mode 100644 components/input/input.wxss create mode 100644 components/input/props.d.ts create mode 100644 components/input/props.js create mode 100644 components/input/type.d.ts create mode 100644 components/input/type.js create mode 100644 components/loading/README.md create mode 100644 components/loading/index.d.ts create mode 100644 components/loading/index.js create mode 100644 components/loading/loading.d.ts create mode 100644 components/loading/loading.js create mode 100644 components/loading/loading.json create mode 100644 components/loading/loading.wxml create mode 100644 components/loading/loading.wxss create mode 100644 components/loading/props.d.ts create mode 100644 components/loading/props.js create mode 100644 components/loading/type.d.ts create mode 100644 components/loading/type.js create mode 100644 components/picker/README.md create mode 100644 components/picker/picker-item-props.d.ts create mode 100644 components/picker/picker-item-props.js create mode 100644 components/picker/picker-item.d.ts create mode 100644 components/picker/picker-item.js create mode 100644 components/picker/picker-item.json create mode 100644 components/picker/picker-item.wxml create mode 100644 components/picker/picker-item.wxss create mode 100644 components/picker/picker.d.ts create mode 100644 components/picker/picker.js create mode 100644 components/picker/picker.json create mode 100644 components/picker/picker.wxml create mode 100644 components/picker/picker.wxss create mode 100644 components/picker/props.d.ts create mode 100644 components/picker/props.js create mode 100644 components/picker/type.d.ts create mode 100644 components/picker/type.js create mode 100644 components/textarea/README.md create mode 100644 components/textarea/props.d.ts create mode 100644 components/textarea/props.js create mode 100644 components/textarea/textarea.d.ts create mode 100644 components/textarea/textarea.js create mode 100644 components/textarea/textarea.json create mode 100644 components/textarea/textarea.wxml create mode 100644 components/textarea/textarea.wxss create mode 100644 components/textarea/type.d.ts create mode 100644 components/textarea/type.js rename pages/{today => task}/index.js (74%) rename pages/{today => task}/index.json (82%) rename pages/{today => task}/index.wxml (76%) rename pages/{today => task}/index.wxss (91%) create mode 100644 pages/taskDetail/index.js create mode 100644 pages/taskDetail/index.json create mode 100644 pages/taskDetail/index.wxml create mode 100644 pages/taskDetail/index.wxss diff --git a/app.json b/app.json index fecc057..22c15fb 100644 --- a/app.json +++ b/app.json @@ -3,12 +3,16 @@ "pages/index/index", "pages/logs/logs", "pages/myself/index", - "pages/today/index", - "pages/message/index" + "pages/task/index", + "pages/message/index", + "pages/taskDetail/index" ], "usingComponents": { "t-icon": "/components/icon/icon", - "t-checkbox": "/components/checkbox/checkbox" + "t-checkbox": "/components/checkbox/checkbox", + "t-input": "/components/input/input", + "t-textarea": "/components/textarea/textarea", + "t-cell": "/components/cell/cell" }, "window": { "backgroundTextStyle": "light", diff --git a/components/button/README.md b/components/button/README.md new file mode 100644 index 0000000..d1bca6a --- /dev/null +++ b/components/button/README.md @@ -0,0 +1,88 @@ +--- +title: Button 按钮 +description: 用于开启一个闭环的操作任务,如“删除”对象、“购买”商品等。 +spline: base +isComponent: true +--- + + +## 引入 + +全局引入,在 miniprogram 根目录下的`app.json`中配置,局部引入,在需要引入的页面或组件的`index.json`中配置。 + +```json +"usingComponents": { + "t-button": "tdesign-miniprogram/button/button", + "t-button-group": "tdesign-miniprogram/button-group/button-group" +} +``` + +## 代码演示 + +### 基础按钮 + + +基础类型分为主按钮、次按钮、文字按钮 + +#### 次按钮 +使用场景:在用户进行的操作为流程中的辅助操作,或者进行不那么重要的交互行为时,选择用次按钮;次要按钮通常和主要按钮一起出现 + +#### 主按钮 +使用场景:大部分场景都可以使用,例如反馈页、表单页、对话框,一个页面建议最多只出现一个主按钮; + +#### 文字按钮 +使用场景:它的操作通常和其旁边内容相关,通常出现在标题旁、字段旁、列表最下方 + +{{ base }} + +### 带图标按钮 +{{ icon-btn }} + +### 不同尺寸 + +{{ size }} + +## API +### Button Props + +名称 | 类型 | 默认值 | 说明 | 必传 +-- | -- | -- | -- | -- +block | Boolean | false | 是否为块级元素 | N +content | String / Slot | - | 按钮内容 | N +custom-dataset | Any | - | 自定义 dataset,可通过 event.detail.currentTarget.dataset.custom 获取。当open-type 为 share 时,可在 onShareAppMessage 事件的 event.target.dataset.custom 中看到传入的值。TS 类型:`any` | N +disabled | Boolean | false | 是否禁用按钮 | N +external-classes | Array | - | 组件类名。`['t-class', 't-class-icon', 't-class-loading']` | N +ghost | Boolean | false | 是否为幽灵按钮(镂空按钮) | N +icon | String | - | 图标名称 | N +icon-props | Object | {} | 图标属性,透传至 icon | N +loading | Boolean | false | 是否显示为加载状态 | N +loading-props | Object | - | 加载loading属性,透传至loading。TS 类型:`LoadingProps` | N +shape | String | rectangle | 按钮形状,有 4 种:长方形、正方形、圆角长方形、圆形。可选项:rectangle/square/round/circle | N +size | String | medium | 组件尺寸。可选项:small/medium/large。TS 类型:`SizeEnum` | N +theme | String | default | 组件风格,依次为品牌色、危险色。可选项:default/primary/danger | N +type | String | - | 同小程序的 formType。可选项:submit/reset | N +variant | String | base | 按钮形式,基础、线框、文字。可选项:base/outline/text | N +open-type | String | - | 微信开放能力。
具体释义:
`contact` 打开客服会话,如果用户在会话中点击消息卡片后返回小程序,可以从 bindcontact 回调中获得具体信息,具体说明 (*小程序插件中不能使用*);
`share` 触发用户转发,使用前建议先阅读使用指引
`getPhoneNumber` 获取用户手机号,可以从 bindgetphonenumber 回调中获取到用户信息,具体说明 (*小程序插件中不能使用*);
`getUserInfo` 获取用户信息,可以从 bindgetuserinfo 回调中获取到用户信息 (*小程序插件中不能使用*);
`launchApp` 打开APP,可以通过 app-parameter 属性设定向 APP 传的参数具体说明
`openSetting` 打开授权设置页;
`feedback` 打开“意见反馈”页面,用户可提交反馈内容并上传日志,开发者可以登录小程序管理后台后进入左侧菜单“客服反馈”页面获取到反馈内容;
`chooseAvatar` 获取用户头像,可以从 bindchooseavatar 回调中获取到头像信息。
[小程序官方文档](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 英文。。
具体释义:
`en` 英文;
`zh_CN` 简体中文;
`zh_TW` 繁体中文。
[小程序官方文档](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 数据与wx.getUserInfo返回的一致,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` | 点击时触发 diff --git a/components/button/button.d.ts b/components/button/button.d.ts new file mode 100644 index 0000000..4b2d7c7 --- /dev/null +++ b/components/button/button.d.ts @@ -0,0 +1,31 @@ +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; + }; + 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; + }; +} diff --git a/components/button/button.js b/components/button/button.js new file mode 100644 index 0000000..0efc4e4 --- /dev/null +++ b/components/button/button.js @@ -0,0 +1,89 @@ +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'; +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(); + }, + }; + this.lifetimes = { + attached() { + this.setClass(); + }, + }; + this.methods = { + setClass() { + const classList = [ + name, + `${prefix}-class`, + `${name}--${this.data.theme}`, + `${name}--size-${this.data.size.slice(0, 1)}`, + ]; + classList.push(`${name}--${this.data.shape}`); + if (this.data.block) { + classList.push(`${prefix}-is-block`); + } + if (this.data.disabled) { + classList.push(`${prefix}-is-disabled`); + } + classList.push(`${name}--${this.data.variant}`); + 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; diff --git a/components/button/button.json b/components/button/button.json new file mode 100644 index 0000000..708bd1b --- /dev/null +++ b/components/button/button.json @@ -0,0 +1,7 @@ +{ + "component": true, + "usingComponents": { + "t-icon": "../icon/icon", + "t-loading": "../loading/loading" + } +} diff --git a/components/button/button.wxml b/components/button/button.wxml new file mode 100644 index 0000000..d967852 --- /dev/null +++ b/components/button/button.wxml @@ -0,0 +1,58 @@ + diff --git a/components/button/button.wxss b/components/button/button.wxss new file mode 100644 index 0000000..8e3012c --- /dev/null +++ b/components/button/button.wxss @@ -0,0 +1,248 @@ +.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 { + display: inline-flex; + align-items: center; + justify-content: center; + position: relative; + white-space: nowrap; + text-align: center; + background-image: none; + border: 1px solid transparent; + cursor: pointer; + transition: all 0.3s; + user-select: none; + touch-action: manipulation; + font-size: 28rpx; + height: 80rpx; + border-radius: 8rpx; + color: rgba(0, 0, 0, 0.9); + border-color: #dcdcdc; + background-color: #fff; + outline: none; + font-family: PingFang SC, Microsoft YaHei, Arial Regular; + /* stylelint-disable-next-line */ + -webkit-appearance: none; +} +.t-button::after { + background-color: #000; + content: ' '; + opacity: 0; + top: 0; + right: 0; + bottom: 0; + left: 0; + position: absolute; +} +.t-button:not(.t-is-disabled):active::after { + opacity: 0.1; +} +.t-button--default { + color: rgba(0, 0, 0, 0.9); + background-color: #ffffff; + border: 1px solid #dcdcdc; +} +.t-button--default.t-is-disabled { + color: rgba(0, 0, 0, 0.26); +} +.t-button--primary { + color: #fff; + background-color: #0052d9; + border: 1px solid #0052d9; +} +.t-button--primary.t-is-disabled { + background-color: #bbd3fb; + border-color: #bbd3fb; +} +.t-button--danger { + color: #fff; + background-color: #e34d59; + border: 1px solid #e34d59; +} +.t-button--danger.t-is-disabled { + background-color: #f8b9be; + border-color: #f8b9be; +} +.t-button--text { + color: #0052d9; + background: none; + border: 0; +} +.t-button--text.t-button--size-default { + width: auto; + height: auto; + line-height: normal; + padding: 0; +} +.t-button--text.t-is-disabled { + color: #bbd3fb; +} +.t-button--ghost { + background-color: transparent; + border: 1px solid #fff; + color: #fff; +} +.t-button--ghost.t-is-disabled { + color: rgba(255, 255, 255, 0.35); + border-color: rgba(255, 255, 255, 0.35); +} +.t-button--outline { + background-color: transparent; +} +.t-button--outline.t-button--primary { + color: #0052d9; +} +.t-button--outline.t-button--primary.t-is-disabled { + background-color: transparent; + color: #bbd3fb; +} +.t-button--outline.t-button--danger { + color: #e34d59; +} +.t-button--outline.t-button--danger.t-is-disabled { + background-color: transparent; + color: #f8b9be; +} +.t-button--dashed { + background-color: transparent; + border-style: dashed; +} +.t-button--dashed.t-button--primary { + color: #0052d9; +} +.t-button--dashed.t-button--primary.t-is-disabled { + background-color: transparent; + color: #bbd3fb; +} +.t-button--dashed.t-button--danger { + color: #e34d59; +} +.t-button--dashed.t-button--danger.t-is-disabled { + background-color: transparent; + color: #f8b9be; +} +.t-button--base { + height: 80rpx; + line-height: 80rpx; + padding-left: 31rpx; + padding-right: 31rpx; + font-size: 28rpx; +} +.t-button--size-l { + height: 88rpx; + line-height: 88rpx; +} +.t-button--size-l .t-button__icon { + font-size: 48rpx; +} +.t-button--size-l .t-button__loading + .t-button__content:not(:empty), +.t-button--size-l .t-button__icon + .t-button__content:not(:empty) { + margin-left: 16rpx; +} +.t-button--size-m .t-button__icon { + font-size: 44rpx; +} +.t-button--size-m .t-button__loading + .t-button__content:not(:empty), +.t-button--size-m .t-button__icon + .t-button__content:not(:empty) { + margin-left: 8rpx; +} +.t-button--size-s { + height: 72rpx; + line-height: 72rpx; +} +.t-button--size-s .t-button__icon { + font-size: 40rpx; +} +.t-button--size-s .t-button__loading + .t-button__content:not(:empty), +.t-button--size-s .t-button__icon + .t-button__content:not(:empty) { + margin-left: 8rpx; +} +.t-button__icon { + border-radius: 8rpx; +} +.t-button--round.t-button--size-l { + border-radius: 44rpx; +} +.t-button--round.t-button--size-m { + border-radius: 40rpx; +} +.t-button--round.t-button--size-s { + border-radius: 36rpx; +} +.t-button--square { + padding: 0; +} +.t-button--square.t-button--size-l { + width: 88rpx; +} +.t-button--square.t-button--size-m { + width: 80rpx; +} +.t-button--square.t-button--size-s { + width: 72rpx; +} +.t-button--circle { + padding: 0; +} +.t-button--circle.t-button--size-l { + border-radius: 50%; + width: 88rpx; +} +.t-button--circle.t-button--size-m { + border-radius: 50%; + width: 80rpx; +} +.t-button--circle.t-button--size-s { + border-radius: 50%; + width: 72rpx; +} +.t-button.t-is-block { + display: flex; + width: 100%; +} +.t-button.t-is-disabled { + cursor: not-allowed; +} +.t-button.button-hover:after { + border-radius: 8rpx; +} +.t-button .position-center { + display: flex; + align-items: center; + justify-content: center; +} +.t-button .indicator-blue { + color: white; +} +.t-button-group .t-button { + border: 0; + border-radius: 0; + box-shadow: 0; + width: 100%; + height: 100%; +} diff --git a/components/button/index.d.ts b/components/button/index.d.ts new file mode 100644 index 0000000..beb0ad5 --- /dev/null +++ b/components/button/index.d.ts @@ -0,0 +1,3 @@ +export * from './props'; +export * from './type'; +export * from './button'; diff --git a/components/button/index.js b/components/button/index.js new file mode 100644 index 0000000..beb0ad5 --- /dev/null +++ b/components/button/index.js @@ -0,0 +1,3 @@ +export * from './props'; +export * from './type'; +export * from './button'; diff --git a/components/button/props.d.ts b/components/button/props.d.ts new file mode 100644 index 0000000..00dc5fb --- /dev/null +++ b/components/button/props.d.ts @@ -0,0 +1,3 @@ +import { TdButtonProps } from './type'; +declare const props: TdButtonProps; +export default props; diff --git a/components/button/props.js b/components/button/props.js new file mode 100644 index 0000000..110cca6 --- /dev/null +++ b/components/button/props.js @@ -0,0 +1,101 @@ +const props = { + block: { + type: Boolean, + value: false, + }, + content: { + type: String, + }, + customDataset: { + type: null, + }, + disabled: { + type: Boolean, + value: false, + }, + externalClasses: { + type: Array, + }, + ghost: { + type: Boolean, + value: false, + }, + icon: { + type: String, + value: '', + }, + iconProps: { + type: Object, + value: {}, + }, + 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; diff --git a/components/button/type.d.ts b/components/button/type.d.ts new file mode 100644 index 0000000..bb716b6 --- /dev/null +++ b/components/button/type.d.ts @@ -0,0 +1,108 @@ +import { SizeEnum } from '../common/common'; +import { LoadingProps } from '../loading/index'; +export interface TdButtonProps { + block?: { + type: BooleanConstructor; + value?: boolean; + }; + content?: { + type: StringConstructor; + value?: string; + }; + customDataset?: { + type: ObjectConstructor; + value?: any; + }; + disabled?: { + type: BooleanConstructor; + value?: boolean; + }; + externalClasses?: { + type: ArrayConstructor; + value?: ['t-class', 't-class-icon', 't-class-loading']; + }; + ghost?: { + type: BooleanConstructor; + value?: boolean; + }; + icon?: { + type: StringConstructor; + value?: string; + }; + iconProps?: { + type: ObjectConstructor; + value?: 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'; + }; + 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; + }; +} diff --git a/components/button/type.js b/components/button/type.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/components/button/type.js @@ -0,0 +1 @@ +export {}; diff --git a/components/cell/README.md b/components/cell/README.md new file mode 100644 index 0000000..4bdc541 --- /dev/null +++ b/components/cell/README.md @@ -0,0 +1,57 @@ +--- +title: Cell 单元格 +description: 用于各个类别行的信息展示。 +spline: data +isComponent: true +--- + + +## 引入 + +全局引入,在 miniprogram 根目录下的`app.json`中配置,局部引入,在需要引入的页面或组件的`index.json`中配置。 + +```json +"usingComponents": { + "t-cell": "tdesign-miniprogram/cell/cell" +} +``` + +## 代码演示 + +### 单行单元格 + + + +{{ base }} + +### 多行单元格 + + + +{{ multiple }} + +## API +### Cell Props + +名称 | 类型 | 默认值 | 说明 | 必传 +-- | -- | -- | -- | -- +align | String | middle | 内容的对齐方式,默认居中对齐。可选项:top/middle/bottom | N +arrow | Boolean | false | 是否显示右侧箭头 | N +bordered | Boolean | true | 是否显示下边框 | 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 | - | 右侧内容 diff --git a/components/cell/cell.d.ts b/components/cell/cell.d.ts new file mode 100644 index 0000000..92eb1c9 --- /dev/null +++ b/components/cell/cell.d.ts @@ -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; +} diff --git a/components/cell/cell.js b/components/cell/cell.js new file mode 100644 index 0000000..7950416 --- /dev/null +++ b/components/cell/cell.js @@ -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; diff --git a/components/cell/cell.json b/components/cell/cell.json new file mode 100644 index 0000000..049940c --- /dev/null +++ b/components/cell/cell.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "t-icon": "../icon/icon" + } +} diff --git a/components/cell/cell.wxml b/components/cell/cell.wxml new file mode 100644 index 0000000..c3ba655 --- /dev/null +++ b/components/cell/cell.wxml @@ -0,0 +1,40 @@ + + + + + + + + + + {{ title}} + + +  * + + + + + {{description}} + + + + + + {{note}} + + + + + + + + + + + diff --git a/components/cell/cell.wxss b/components/cell/cell.wxss new file mode 100644 index 0000000..57394d6 --- /dev/null +++ b/components/cell/cell.wxss @@ -0,0 +1,122 @@ +.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%; + padding: 24rpx 32rpx; + font-size: 32rpx; + line-height: 48rpx; + color: rgba(0, 0, 0, 0.9); + background-color: #ffffff; +} +.t-cell::after { + position: absolute; + box-sizing: border-box; + content: ' '; + pointer-events: none; + right: 0; + left: 0; + bottom: 0; + border-bottom: 1px solid #e7e7e7; + transform: scaleY(0.5); + left: 32rpx; +} +.t-cell--borderless::after { + display: none; +} +.t-cell__description { + font-size: 28rpx; + line-height: 44rpx; + color: rgba(0, 0, 0, 0.4); +} +.t-cell__description-text { + margin-top: 8rpx; +} +.t-cell__note { + display: flex; + align-items: center; + justify-content: flex-end; + overflow: hidden; + color: rgba(0, 0, 0, 0.4); +} +.t-cell__title, +.t-cell__note { + flex: 1 1 auto; +} +.t-cell__title:empty, +.t-cell__note:empty { + display: none; +} +.t-cell__title-text { + font-size: 35rpx; + display: flex; +} +.t-cell__left, +.t-cell__right { + display: flex; + align-items: center; + font-size: 48rpx; + line-height: 48rpx; +} +.t-cell__left :not(:empty) { + margin-right: 16rpx; +} +.t-cell__left-icon { + font-size: 48rpx; +} +.t-cell__left-image { + height: 112rpx; + width: 112rpx; +} +.t-cell__right { + margin-left: 8rpx; + color: #bbb; +} +.t-cell__right-icon { + color: #bbb; + font-size: 48rpx; + line-height: 48rpx; +} +.t-cell--hover.t-cell--hover-class { + background-color: #f2f3f5; +} +.t-cell--required { + font-size: 32rpx; + color: #e34d59; +} +.t-cell--middle { + align-items: center; +} +.t-cell--top { + align-items: flex-start; +} +.t-cell--bottom { + align-items: flex-end; +} diff --git a/components/cell/props.d.ts b/components/cell/props.d.ts new file mode 100644 index 0000000..ad657e5 --- /dev/null +++ b/components/cell/props.d.ts @@ -0,0 +1,3 @@ +import { TdCellProps } from './type'; +declare const props: TdCellProps; +export default props; diff --git a/components/cell/props.js b/components/cell/props.js new file mode 100644 index 0000000..8e741e8 --- /dev/null +++ b/components/cell/props.js @@ -0,0 +1,51 @@ +const props = { + align: { + type: String, + value: 'middle', + }, + arrow: { + type: Boolean, + value: false, + }, + bordered: { + type: Boolean, + value: true, + }, + 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; diff --git a/components/cell/type.d.ts b/components/cell/type.d.ts new file mode 100644 index 0000000..00d874b --- /dev/null +++ b/components/cell/type.d.ts @@ -0,0 +1,72 @@ +export interface TdCellProps { + align?: { + type: StringConstructor; + value?: 'top' | 'middle' | 'bottom'; + required?: boolean; + }; + arrow?: { + type: BooleanConstructor; + value?: boolean; + required?: boolean; + }; + bordered?: { + type: BooleanConstructor; + value?: boolean; + required?: boolean; + }; + description?: { + type: StringConstructor; + value?: string; + required?: boolean; + }; + 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']; + required?: boolean; + }; + hover?: { + type: BooleanConstructor; + value?: boolean; + required?: boolean; + }; + image?: { + type: StringConstructor; + value?: string; + required?: boolean; + }; + jumpType?: { + type: StringConstructor; + value?: 'switchTab' | 'reLaunch' | 'redirectTo' | 'navigateTo'; + required?: boolean; + }; + leftIcon?: { + type: StringConstructor; + value?: string; + required?: boolean; + }; + note?: { + type: StringConstructor; + value?: string; + required?: boolean; + }; + required?: { + type: BooleanConstructor; + value?: boolean; + required?: boolean; + }; + rightIcon?: { + type: StringConstructor; + value?: string; + required?: boolean; + }; + title?: { + type: StringConstructor; + value?: string; + required?: boolean; + }; + url?: { + type: StringConstructor; + value?: string; + required?: boolean; + }; +} diff --git a/components/cell/type.js b/components/cell/type.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/components/cell/type.js @@ -0,0 +1 @@ +export {}; diff --git a/components/date-time-picker/README.md b/components/date-time-picker/README.md new file mode 100644 index 0000000..6cad303 --- /dev/null +++ b/components/date-time-picker/README.md @@ -0,0 +1,67 @@ +--- +title: DateTimePicker 时间选择器 +description: 用于选择一个时间点或者一个时间段。 +spline: form +isComponent: true +--- + + +## 引入 + +全局引入,在 miniprogram 根目录下的`app.json`中配置,局部引入,在需要引入的页面或组件的`index.json`中配置。 + +```json +"usingComponents": { + "t-date-time-picker": "tdesign-miniprogram/date-time-picker/date-time-picker" +} +``` + +## 代码演示 + +### 基础时间选择器 + + + +#### 选择日期(年月日) + +{{ year-month-date }} + +#### 选择日期(年月) + +{{ year-month }} + +#### 选择时间(时分) + +{{ time-min }} + +#### 选择日期时间(年月日时分) + +{{ date-all }} + +## API +### DateTimePicker Props + +名称 | 类型 | 默认值 | 说明 | 必传 +-- | -- | -- | -- | -- +cancel-btn | String | 取消 | 取消按钮文字 | N +confirm-btn | String | - | 确定按钮文字 | N +end | String / Number | - | 选择器的结束时间 | N +external-classes | Array | - | 组件类名,分别用于设置组件外层元素、确认按钮、取消按钮、标题等元素类名。`['t-class', 't-class-confirm', 't-class-cancel', 't-class-title']` | N +footer | Slot | true | 底部内容 | N +format | String | '' | 用于格式化日期,[详细文档](https://day.js.org/docs/en/display/format) | N +header | Boolean / Slot | true | 头部内容。值为 true 显示空白头部,值为 false 不显示任何内容,值类型为 TNode 表示自定义头部内容 | N +mode | String / Array | 'date' | year = 年;month = 年月;date = 年月日;hour = 年月日时; minute = 年月日时分;当类型为数组时,第一个值控制年月日,第二个值控制时分秒。TS 类型:`DateTimePickerMode` `type DateTimePickerMode = TimeModeValues | Array ` `type TimeModeValues = 'year' | 'month' | 'date' | 'hour' | 'minute' | 'second'`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/date-time-picker/type.ts) | N +show-week | Boolean | false | 【开发中】是否在日期旁边显示周几(如周一,周二,周日等) | N +start | String / Number | - | 选择器的开始时间 | N +title | String | - | 标题 | N +value | String / Number | - | 选中值。TS 类型:`DateValue` `type DateValue = string | number`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/date-time-picker/type.ts) | N +default-value | String / Number | undefined | 选中值。非受控属性。TS 类型:`DateValue` `type DateValue = string | number`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/date-time-picker/type.ts) | N +visible | Boolean | false | 是否显示 | N + +### DateTimePicker Events + +名称 | 参数 | 描述 +-- | -- | -- +cancel | \- | 取消按钮点击时触发 +change | `(value: DateValue)` | 确认按钮点击时触发 +pick | `(value: DateValue)` | 选中值发生变化时触发 diff --git a/components/date-time-picker/date-time-picker.d.ts b/components/date-time-picker/date-time-picker.d.ts new file mode 100644 index 0000000..aadd2e7 --- /dev/null +++ b/components/date-time-picker/date-time-picker.d.ts @@ -0,0 +1,107 @@ +import dayjs from 'dayjs'; +import type { Dayjs } from 'dayjs'; +import { SuperComponent } from '../common/src/index'; +declare enum ModeItem { + YEAR = "year", + MONTH = "month", + DATE = "date", + HOUR = "hour", + MINUTE = "minute" +} +interface ColumnItemValue { + value: string | number; + label: string | number; +} +export default class DateTimePicker extends SuperComponent { + properties: import("./type").TdDateTimePickerProps; + externalClasses: string[]; + options: { + multipleSlots: boolean; + }; + observers: { + 'start, end, value': () => void; + mode(m: any): void; + }; + date: any; + data: { + prefix: string; + classPrefix: string; + columns: any[]; + columnsValue: any[]; + fullModes: any[]; + locale: { + year: string; + month: string; + day: string; + hour: string; + minute: string; + am: string; + pm: string; + confirm: string; + cancel: string; + }; + }; + controlledProps: { + key: string; + event: string; + }[]; + methods: { + updateColumns(): void; + getParseDate(): Dayjs; + getMinDate(): Dayjs; + getMaxDate(): Dayjs; + getMinYear(): number; + getMaxYear(): number; + getMinMonth(): number; + getMaxMonth(): number; + getMinDay(): number; + getMaxDay(): number; + getMinHour(): number; + getMaxHour(): number; + getMinMinute(): number; + getMaxMinute(): number; + getDate(): Dayjs; + clipDate(date: Dayjs): Dayjs; + setYear(date: Dayjs, year: number): Dayjs; + setMonth(date: Dayjs, month: number): Dayjs; + getColumnOptions(): any[]; + getCommonDateParams(): { + date: dayjs.Dayjs; + selYear: number; + selMonth: number; + selDate: number; + selHour: number; + minDateYear: any; + maxDateYear: any; + minDateMonth: any; + maxDateMonth: any; + minDateDay: any; + maxDateDay: any; + minDateHour: any; + maxDateHour: any; + minDateMinute: any; + maxDateMinute: any; + }; + getOptionByType(type: any, dateParams: any): any; + getYearOptions(dateParams: any): ColumnItemValue[]; + getMonthOptions(dateParams: any): ColumnItemValue[]; + getDayOptions(dateParams: any): ColumnItemValue[]; + getHourOptions(dateParams: any): ColumnItemValue[]; + getMinuteOptions(dateParams: any): ColumnItemValue[]; + getValueCols(this: DateTimePicker): { + columns: any; + columnsValue: any; + }; + getColumnsValue(): string[]; + getNewDate(value: number, type: ModeItem): Dayjs; + onColumnChange(e: WechatMiniprogram.CustomEvent): void; + onConfirm(): void; + onCancel(): void; + onVisibleChange(e: any): void; + resetColumns(): void; + }; + getFullModeArray(mode: any): any; + getFullModeByModeString(modeString: any, matchModes: any): any; + isTimeMode(): boolean; +} +export {}; diff --git a/components/date-time-picker/date-time-picker.js b/components/date-time-picker/date-time-picker.js new file mode 100644 index 0000000..903121e --- /dev/null +++ b/components/date-time-picker/date-time-picker.js @@ -0,0 +1,405 @@ +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 dayjs from './dayjs/index'; +import config from '../common/config'; +import { SuperComponent, wxComponent } from '../common/src/index'; +import defaultLocale from './locale/zh'; +import props from './props'; +const { prefix } = config; +const name = `${prefix}-date-time-picker`; +var ModeItem; +(function (ModeItem) { + ModeItem["YEAR"] = "year"; + ModeItem["MONTH"] = "month"; + ModeItem["DATE"] = "date"; + ModeItem["HOUR"] = "hour"; + ModeItem["MINUTE"] = "minute"; +})(ModeItem || (ModeItem = {})); +const DATE_MODES = ['year', 'month', 'date']; +const TIME_MODES = ['hour', 'minute']; +const FULL_MODES = [...DATE_MODES, ...TIME_MODES]; +const DEFAULT_MIN_DATE = dayjs('2000-01-01 00:00:00'); +const DEFAULT_MAX_DATE = dayjs('2030-12-31 23:59:59'); +let DateTimePicker = class DateTimePicker extends SuperComponent { + constructor() { + super(...arguments); + this.properties = props; + this.externalClasses = [`${prefix}-class`, `${prefix}-class-confirm`, `${prefix}-class-cancel`, `${prefix}-class-title`]; + this.options = { + multipleSlots: true, + }; + this.observers = { + 'start, end, value': function () { + this.updateColumns(); + }, + mode(m) { + const fullModes = this.getFullModeArray(m); + this.setData({ + fullModes, + }); + this.updateColumns(); + }, + }; + this.date = null; + this.data = { + prefix, + classPrefix: name, + columns: [], + columnsValue: [], + fullModes: [], + locale: defaultLocale, + }; + this.controlledProps = [ + { + key: 'value', + event: 'change', + }, + ]; + this.methods = { + updateColumns() { + this.date = this.getParseDate(); + const { columns, columnsValue } = this.getValueCols(); + this.setData({ + columns, + columnsValue, + }); + }, + getParseDate() { + const { value, defaultValue } = this.properties; + const minDate = this.getMinDate(); + const isTimeMode = this.isTimeMode(); + let currentValue = value || defaultValue; + if (isTimeMode) { + const dateStr = dayjs(minDate).format('YYYY-MM-DD'); + currentValue = dayjs(`${dateStr} ${currentValue}`); + } + const parseDate = dayjs(currentValue || minDate); + const isDateValid = parseDate.isValid(); + return isDateValid ? parseDate : minDate; + }, + getMinDate() { + const { start } = this.properties; + return start ? dayjs(start) : DEFAULT_MIN_DATE; + }, + getMaxDate() { + const { end } = this.properties; + return end ? dayjs(end) : DEFAULT_MAX_DATE; + }, + getMinYear() { + return this.getMinDate().year(); + }, + getMaxYear() { + return this.getMaxDate().year(); + }, + getMinMonth() { + return this.getMinDate().month(); + }, + getMaxMonth() { + return this.getMaxDate().month(); + }, + getMinDay() { + return this.getMinDate().date(); + }, + getMaxDay() { + return this.getMaxDate().date(); + }, + getMinHour() { + return this.getMinDate().hour(); + }, + getMaxHour() { + return this.getMaxDate().hour(); + }, + getMinMinute() { + return this.getMinDate().minute(); + }, + getMaxMinute() { + return this.getMaxDate().minute(); + }, + getDate() { + return this.clipDate((this === null || this === void 0 ? void 0 : this.date) || DEFAULT_MIN_DATE); + }, + clipDate(date) { + const minDate = this.getMinDate(); + const maxDate = this.getMaxDate(); + return dayjs(Math.min(Math.max(minDate.valueOf(), date.valueOf()), maxDate.valueOf())); + }, + setYear(date, year) { + const beforeMonthDays = date.date(); + const afterMonthDays = date.year(year).daysInMonth(); + const tempDate = date.date(Math.min(beforeMonthDays.valueOf(), afterMonthDays.valueOf())); + return tempDate.year(year); + }, + setMonth(date, month) { + const beforeMonthDays = date.date(); + const afterMonthDays = date.month(month).daysInMonth(); + const tempDate = date.date(Math.min(beforeMonthDays.valueOf(), afterMonthDays.valueOf())); + return tempDate.month(month); + }, + getColumnOptions() { + const { fullModes } = this.data; + const dateParams = this.getCommonDateParams(); + const columnOptions = []; + fullModes === null || fullModes === void 0 ? void 0 : fullModes.forEach((mode) => { + const columnOption = this.getOptionByType(mode, dateParams); + columnOptions.push(columnOption); + }); + return columnOptions; + }, + getCommonDateParams() { + const date = this.getDate(); + const selYear = date.year(); + const selMonth = date.month(); + const selDate = date.date(); + const selHour = date.hour(); + const minDateYear = this.getMinYear(); + const maxDateYear = this.getMaxYear(); + const minDateMonth = this.getMinMonth(); + const maxDateMonth = this.getMaxMonth(); + const minDateDay = this.getMinDay(); + const maxDateDay = this.getMaxDay(); + const minDateHour = this.getMinHour(); + const maxDateHour = this.getMaxHour(); + const minDateMinute = this.getMinMinute(); + const maxDateMinute = this.getMaxMinute(); + return { + date, + selYear, + selMonth, + selDate, + selHour, + minDateYear, + maxDateYear, + minDateMonth, + maxDateMonth, + minDateDay, + maxDateDay, + minDateHour, + maxDateHour, + minDateMinute, + maxDateMinute, + }; + }, + getOptionByType(type, dateParams) { + switch (type) { + case ModeItem.YEAR: + return this.getYearOptions(dateParams); + case ModeItem.MONTH: + return this.getMonthOptions(dateParams); + case ModeItem.DATE: + return this.getDayOptions(dateParams); + case ModeItem.HOUR: + return this.getHourOptions(dateParams); + case ModeItem.MINUTE: + return this.getMinuteOptions(dateParams); + default: + break; + } + }, + getYearOptions(dateParams) { + const { locale } = this.data; + const { minDateYear, maxDateYear } = dateParams; + const years = []; + for (let i = minDateYear; i <= maxDateYear; i += 1) { + years.push({ + value: `${i}`, + label: `${i + locale.year}`, + }); + } + return years; + }, + getMonthOptions(dateParams) { + const { locale } = this.data; + const { minDateYear, maxDateYear, selYear, minDateMonth, maxDateMonth } = dateParams; + const months = []; + let minMonth = 0; + let maxMonth = 11; + if (minDateYear === selYear) { + minMonth = minDateMonth; + } + if (maxDateYear === selYear) { + maxMonth = maxDateMonth; + } + for (let i = minMonth; i <= maxMonth; i += 1) { + months.push({ + value: `${i}`, + label: `${i + 1 + locale.month}`, + }); + } + return months; + }, + getDayOptions(dateParams) { + const { locale } = this.data; + const { minDateYear, maxDateYear, minDateMonth, maxDateMonth, minDateDay, maxDateDay, selYear, selMonth, date } = dateParams; + const days = []; + let minDay = 1; + let maxDay = date.daysInMonth(); + if (minDateYear === selYear && minDateMonth === selMonth) { + minDay = minDateDay; + } + if (maxDateYear === selYear && maxDateMonth === selMonth) { + maxDay = maxDateDay; + } + for (let i = minDay; i <= maxDay; i += 1) { + days.push({ + value: `${i}`, + label: `${i + locale.day}`, + }); + } + return days; + }, + getHourOptions(dateParams) { + const { locale } = this.data; + const { minDateYear, maxDateYear, minDateMonth, maxDateMonth, minDateDay, minDateHour, maxDateDay, maxDateHour, selYear, selMonth, selDate, } = dateParams; + const hours = []; + let minHour = 0; + let maxHour = 23; + if (minDateYear === selYear && minDateMonth === selMonth && minDateDay === selDate) { + minHour = minDateHour; + } + if (maxDateYear === selYear && maxDateMonth === selMonth && maxDateDay === selDate) { + maxHour = maxDateHour; + } + for (let i = minHour; i <= maxHour; i += 1) { + hours.push({ + value: `${i}`, + label: `${i + locale.hour}`, + }); + } + return hours; + }, + getMinuteOptions(dateParams) { + const { locale } = this.data; + const { minDateYear, maxDateYear, minDateMonth, maxDateMonth, minDateDay, maxDateDay, minDateHour, maxDateHour, minDateMinute, maxDateMinute, selYear, selMonth, selDate, selHour, } = dateParams; + const minutes = []; + let minMinute = 0; + let maxMinute = 59; + if (minDateYear === selYear && minDateMonth === selMonth && minDateDay === selDate && minDateHour === selHour) { + minMinute = minDateMinute; + } + if (maxDateYear === selYear && maxDateMonth === selMonth && maxDateDay === selDate && maxDateHour === selHour) { + maxMinute = maxDateMinute; + } + for (let i = minMinute; i <= maxMinute; i += 1) { + minutes.push({ + value: `${i}`, + label: `${i + locale.minute}`, + }); + } + return minutes; + }, + getValueCols() { + return { + columns: this.getColumnOptions(), + columnsValue: this.getColumnsValue(), + }; + }, + getColumnsValue() { + const { fullModes } = this.data; + const date = this.getDate(); + const columnsValue = []; + fullModes === null || fullModes === void 0 ? void 0 : fullModes.forEach((mode) => { + columnsValue.push(`${date[mode]()}`); + }); + return columnsValue; + }, + getNewDate(value, type) { + let newValue = this.getDate(); + switch (type) { + case ModeItem.YEAR: + newValue = this.setYear(newValue, value); + break; + case ModeItem.MONTH: + newValue = this.setMonth(newValue, value); + break; + case ModeItem.DATE: + newValue = newValue.date(value); + break; + case ModeItem.HOUR: + newValue = newValue.hour(value); + break; + case ModeItem.MINUTE: + newValue = newValue.minute(value); + break; + default: + break; + } + return this.clipDate(newValue); + }, + onColumnChange(e) { + const { value, column } = e === null || e === void 0 ? void 0 : e.detail; + const { fullModes, format } = this.data; + const columnValue = value === null || value === void 0 ? void 0 : value[column]; + const columnType = fullModes === null || fullModes === void 0 ? void 0 : fullModes[column]; + const newValue = this.getNewDate(parseInt(columnValue, 10), columnType); + this.date = newValue; + const { columns, columnsValue } = this.getValueCols(); + this.setData({ + columns, + columnsValue, + }); + const date = this.getDate(); + const pickValue = format ? date.format(format) : date.valueOf(); + this.triggerEvent('pick', { value: pickValue }); + }, + onConfirm() { + const { format } = this.properties; + const date = this.getDate(); + const value = format ? date.format(format) : date.valueOf(); + this._trigger('change', { value }); + this.resetColumns(); + }, + onCancel() { + this.resetColumns(); + this.triggerEvent('cancel'); + }, + onVisibleChange(e) { + if (!e.detail.visible) { + this.resetColumns(); + } + }, + resetColumns() { + const parseDate = this.getParseDate(); + this.date = parseDate; + const { columns, columnsValue } = this.getValueCols(); + this.setData({ + columns, + columnsValue, + }); + }, + }; + } + getFullModeArray(mode) { + if (typeof mode === 'string' || mode instanceof String) { + return this.getFullModeByModeString(mode, FULL_MODES); + } + if (Array.isArray(mode)) { + if ((mode === null || mode === void 0 ? void 0 : mode.length) === 1) { + return this.getFullModeByModeString(mode[0], FULL_MODES); + } + if ((mode === null || mode === void 0 ? void 0 : mode.length) === 2) { + const dateModes = this.getFullModeByModeString(mode[0], DATE_MODES); + const timeModes = this.getFullModeByModeString(mode[1], TIME_MODES); + return [...dateModes, ...timeModes]; + } + } + } + getFullModeByModeString(modeString, matchModes) { + if (!modeString) { + return []; + } + const endIndex = matchModes === null || matchModes === void 0 ? void 0 : matchModes.findIndex((mode) => modeString === mode); + return matchModes === null || matchModes === void 0 ? void 0 : matchModes.slice(0, endIndex + 1); + } + isTimeMode() { + const { fullModes } = this.data; + return fullModes[0] === ModeItem.HOUR; + } +}; +DateTimePicker = __decorate([ + wxComponent() +], DateTimePicker); +export default DateTimePicker; diff --git a/components/date-time-picker/date-time-picker.json b/components/date-time-picker/date-time-picker.json new file mode 100644 index 0000000..036831c --- /dev/null +++ b/components/date-time-picker/date-time-picker.json @@ -0,0 +1,7 @@ +{ + "component": true, + "usingComponents": { + "t-picker": "../picker/picker", + "t-picker-item": "../picker/picker-item" + } +} diff --git a/components/date-time-picker/date-time-picker.wxml b/components/date-time-picker/date-time-picker.wxml new file mode 100644 index 0000000..2b1ea87 --- /dev/null +++ b/components/date-time-picker/date-time-picker.wxml @@ -0,0 +1,18 @@ + + + + + + diff --git a/components/date-time-picker/date-time-picker.wxss b/components/date-time-picker/date-time-picker.wxss new file mode 100644 index 0000000..e69de29 diff --git a/components/date-time-picker/dayjs/index.js b/components/date-time-picker/dayjs/index.js new file mode 100644 index 0000000..4acc24c --- /dev/null +++ b/components/date-time-picker/dayjs/index.js @@ -0,0 +1 @@ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).dayjs=e()}(this,(function(){"use strict";var t=1e3,e=6e4,n=36e5,r="millisecond",i="second",s="minute",u="hour",a="day",o="week",f="month",h="quarter",c="year",d="date",$="Invalid Date",l=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,y=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,M={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_")},m=function(t,e,n){var r=String(t);return!r||r.length>=e?t:""+Array(e+1-r.length).join(n)+t},g={s:m,z:function(t){var e=-t.utcOffset(),n=Math.abs(e),r=Math.floor(n/60),i=n%60;return(e<=0?"+":"-")+m(r,2,"0")+":"+m(i,2,"0")},m:function t(e,n){if(e.date()1)return t(u[0])}else{var a=e.name;D[a]=e,i=a}return!r&&i&&(v=i),i||!r&&v},w=function(t,e){if(p(t))return t.clone();var n="object"==typeof e?e:{};return n.date=t,n.args=arguments,new _(n)},O=g;O.l=S,O.i=p,O.w=function(t,e){return w(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var _=function(){function M(t){this.$L=S(t.locale,null,!0),this.parse(t)}var m=M.prototype;return m.parse=function(t){this.$d=function(t){var e=t.date,n=t.utc;if(null===e)return new Date(NaN);if(O.u(e))return new Date;if(e instanceof Date)return new Date(e);if("string"==typeof e&&!/Z$/i.test(e)){var r=e.match(l);if(r){var i=r[2]-1||0,s=(r[7]||"0").substring(0,3);return n?new Date(Date.UTC(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,s)):new Date(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,s)}}return new Date(e)}(t),this.$x=t.x||{},this.init()},m.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},m.$utils=function(){return O},m.isValid=function(){return!(this.$d.toString()===$)},m.isSame=function(t,e){var n=w(t);return this.startOf(e)<=n&&n<=this.endOf(e)},m.isAfter=function(t,e){return w(t); +export declare type TimeModeValues = 'year' | 'month' | 'date' | 'hour' | 'minute' | 'second'; +export declare type DateValue = string | number; diff --git a/components/date-time-picker/type.js b/components/date-time-picker/type.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/components/date-time-picker/type.js @@ -0,0 +1 @@ +export {}; diff --git a/components/fab/README.md b/components/fab/README.md new file mode 100644 index 0000000..0ba9127 --- /dev/null +++ b/components/fab/README.md @@ -0,0 +1,44 @@ +--- +title: Fab +description: 当功能使用图标即可表意清楚时,可使用纯图标悬浮按钮,例如:添加、发布。 +spline: form +isComponent: true +--- + + +## 引入 + +全局引入,在 miniprogram 根目录下的`app.json`中配置,局部引入,在需要引入的页面或组件的`index.json`中配置。 + + +```json +"usingComponents": { + "t-fab": "tdesign-miniprogram/fab/fab" +} +``` + +## 代码演示 + +### 基础使用 + +{{ base }} + +### 进阶使用 + +{{ advance }} + +## API +### Fab Props + +名称 | 类型 | 默认值 | 说明 | 必传 +-- | -- | -- | -- | -- +button-props | Object | - | 透传至 Button 组件 | N +icon | String | - | 图标 | N +style | String | right: 16px; bottom: 32px; | 悬浮按钮的样式,常用于调整位置 | N +text | String | - | 文本内容 | N + +### Fab Events + +名称 | 参数 | 描述 +-- | -- | -- +click | `({e: Event})` | 悬浮按钮点击事件 diff --git a/components/fab/fab.d.ts b/components/fab/fab.d.ts new file mode 100644 index 0000000..00e06b5 --- /dev/null +++ b/components/fab/fab.d.ts @@ -0,0 +1,20 @@ +import { SuperComponent } from '../common/src/index'; +export default class Fab extends SuperComponent { + properties: import("./type").TdFabProps; + externalClasses: string[]; + data: { + prefix: string; + classPrefix: string; + baseButtonProps: { + size: string; + shape: string; + theme: string; + }; + }; + observers: { + text(val: any): void; + }; + methods: { + onTplButtonTap(e: any): void; + }; +} diff --git a/components/fab/fab.js b/components/fab/fab.js new file mode 100644 index 0000000..e30f4f3 --- /dev/null +++ b/components/fab/fab.js @@ -0,0 +1,47 @@ +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}-fab`; +let Fab = class Fab extends SuperComponent { + constructor() { + super(...arguments); + this.properties = props; + this.externalClasses = [`${prefix}-class`, `${prefix}-class-button`]; + this.data = { + prefix, + classPrefix: name, + baseButtonProps: { + size: 'large', + shape: 'circle', + theme: 'primary', + }, + }; + this.observers = { + text(val) { + if (val) { + this.setData({ + baseButtonProps: { + shape: 'round', + }, + }); + } + }, + }; + this.methods = { + onTplButtonTap(e) { + this.triggerEvent('click', e); + }, + }; + } +}; +Fab = __decorate([ + wxComponent() +], Fab); +export default Fab; diff --git a/components/fab/fab.json b/components/fab/fab.json new file mode 100644 index 0000000..e73f3ad --- /dev/null +++ b/components/fab/fab.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "t-button": "../button/button" + } +} diff --git a/components/fab/fab.wxml b/components/fab/fab.wxml new file mode 100644 index 0000000..41fcc64 --- /dev/null +++ b/components/fab/fab.wxml @@ -0,0 +1,8 @@ + + + +