升级依赖

This commit is contained in:
xh
2025-04-16 00:06:55 +08:00
parent f88d27b7f7
commit 3d138dea15
259 changed files with 10784 additions and 3842 deletions
+5
View File
@@ -0,0 +1,5 @@
{
"cSpell.words": [
"goreleaser"
]
}
+1
View File
@@ -15,6 +15,7 @@ pnpm-lock.yaml
*.njsproj
*.sln
stats.html
.hbuilderx
.vscode/*
!/.vscode/settings.json
-52
View File
@@ -1,52 +0,0 @@
{
//项目名字或项目绝对路径
"project": "x_admin_app",
//打包平台 默认值android 值有"android","ios" 如果要打多个逗号隔开打包平台
"platform": "android",
//是否使用自定义基座 默认值false true自定义基座 false自定义证书
"iscustom": false,
//打包方式是否为安心打包默认值false,true安心打包,false传统打包
"safemode": true,
//android打包参数
"android": {
//安卓包名
"packagename": "uni.UNIFB29F21",
//安卓打包类型 默认值0 0 使用自有证书 1 使用公共证书 2 使用老版证书
"androidpacktype": "3",
//安卓使用自有证书自有打包证书参数
//安卓打包证书别名,自有证书打包填写的参数
"certalias": "",
//安卓打包证书文件路径,自有证书打包填写的参数
"certfile": "",
//安卓打包证书密码,自有证书打包填写的参数
"certpassword": "",
//安卓平台要打的渠道包 取值有"google","yyb","360","huawei","xiaomi","oppo","vivo",如果要打多个逗号隔开
"channels": ""
},
//ios打包参数
"ios": {
//ios appid
"bundle": "uni.UNIFB29F21",
//ios打包支持的设备类型 默认值iPhone 值有"iPhone","iPad" 如果要打多个逗号隔开打包平台
"supporteddevice": "iPhone,iPad",
//iOS打包是否打越狱包,只有值为true时打越狱包,false打正式包
"isprisonbreak": false,
//iOS使用自定义证书打包的profile文件路径
"profile": "",
//iOS使用自定义证书打包的p12文件路径
"certfile": "",
//iOS使用自定义证书打包的证书密码
"certpassword": ""
},
//是否混淆 true混淆 false关闭
"isconfusion": false,
//开屏广告 true打开 false关闭
"splashads": false,
//悬浮红包广告true打开 false关闭
"rpads": false,
//push广告 true打开 false关闭
"pushads": false,
//加入换量联盟 true加入 false不加入
"exchange": false
}
+116
View File
@@ -0,0 +1,116 @@
const {
defineConfig
} = require("@adtkcn/hb-cli");
/**
*
* @param {object} param0
* @param {string} param0.mode 打包模式,通过命令行参数--mode传入
* @returns
*/
module.exports = ({
mode
}) => {
console.log("当前mode环境:", mode);
return defineConfig({
// 打包配置项,全部为uniapp官方配置(必须)
packConfig() {
return {
//项目名字或项目绝对路径
"project": "x_admin_app",
//打包平台 默认值android 值有"android","ios" 如果要打多个逗号隔开打包平台
"platform": "android",
//是否使用自定义基座 默认值false true自定义基座 false自定义证书
"iscustom": false,
//打包方式是否为安心打包默认值false,true安心打包,false传统打包
"safemode": true,
//android打包参数
"android": {
//安卓包名
"packagename": "uni.UNIFB29F21",
//安卓打包类型 默认值0 0 使用自有证书 1 使用公共证书 2 使用老版证书
"androidpacktype": "3",
//安卓使用自有证书自有打包证书参数
//安卓打包证书别名,自有证书打包填写的参数
"certalias": "",
//安卓打包证书文件路径,自有证书打包填写的参数
"certfile": "",
//安卓打包证书密码,自有证书打包填写的参数
"certpassword": "",
//安卓平台要打的渠道包 取值有"google","yyb","360","huawei","xiaomi","oppo","vivo",如果要打多个逗号隔开
"channels": ""
},
//ios打包参数
"ios": {
//ios appid
"bundle": "uni.UNIFB29F21",
//ios打包支持的设备类型 默认值iPhone 值有"iPhone","iPad" 如果要打多个逗号隔开打包平台
"supporteddevice": "iPhone,iPad",
//iOS打包是否打越狱包,只有值为true时打越狱包,false打正式包
"isprisonbreak": false,
//iOS使用自定义证书打包的profile文件路径
"profile": "",
//iOS使用自定义证书打包的p12文件路径
"certfile": "",
//iOS使用自定义证书打包的证书密码
"certpassword": ""
},
//是否混淆 true混淆 false关闭
"isconfusion": false,
//开屏广告 true打开 false关闭
"splashads": false,
//悬浮红包广告true打开 false关闭
"rpads": false,
//push广告 true打开 false关闭
"pushads": false,
//加入换量联盟 true加入 false不加入
"exchange": false
}
},
// 自定义manifest.json配置项: 合并到manifest.json中(可选)
mergeManifestConfig() {
return {
};
},
/**
* 创建APP内环境变量,生成HBuilderEnv.js文件(可选)
* @returns {any} 环境变量
*/
appConfig:{
output:"./HBuilderEnv.js", // 默认./HBuilderEnv.js
create(){
},
},
/**
* 定义manifest.versionName的生成规则(可选,默认:auto-increment)
*/
version: {
mode: "date", // 可选值:"custom"、"date"、"auto-increment",
/**
* 自定义版本号(可选)
* @param {string[]} VersionNameArr 版本号数组,如:[1, 0, 0]
* @returns {string} 版本号数组,如:1.0.0
*/
customVersion: (VersionNameArr) => {
console.log(VersionNameArr);
var lastIndex = VersionNameArr.length - 1;
VersionNameArr[lastIndex] = String(
parseInt(VersionNameArr[lastIndex]) + 1
);
return VersionNameArr.join(".");
},
},
/**
* 打包后回调(可选)
* @param {string} filePath 文件路径,appResource打包后是目录
* @param {"android"|"ios"| "appResource"| "wgt"} fileType 文件类型
*/
async onPackEnd(filePath, fileType) {
//上传回调
console.log("上传回调开始",filePath, fileType);
},
});
};
+3 -3
View File
@@ -1,9 +1,9 @@
{
"name": "x_admin_app",
"name": "x-admin",
"appid": "__UNI__FB29F21",
"description": "",
"versionName": "2024.08.170956",
"versionCode": 104,
"versionName": "2025.04.142245",
"versionCode": 130,
"transformPx": false,
"app-plus": {
"compatible": {
+4
View File
@@ -1,4 +1,8 @@
{
"scripts": {
"build": "hb-cli",
"build:prod": "hb-cli --mode prod"
},
"dependencies": {
"bignumber.js": "^9.1.2",
"crypto-js": "^4.2.0",
@@ -1,3 +1,5 @@
## 1.0.152024-06-14
1. 修复上次更改引出的BUG
## 1.0.142024-05-31
1. 修复设置maxDate后存在选择不准确的BUG
## 1.0.132024-03-22
@@ -78,7 +78,7 @@
},
watch: {
propsChange() {
uni.$uv.sleep(100).then(res=>{
this.$uv.sleep(100).then(res=>{
this.init()
})
}
@@ -1,7 +1,7 @@
{
"id": "uv-datetime-picker",
"displayName": "uv-datetime-picker 时间选择器 全面兼容vue3+2、app、h5、小程序等多端",
"version": "1.0.14",
"version": "1.0.15",
"description": "时间选择器组件用于时间日期,主要用于年月日时分的选择,具体选择的精确度由参数控制。",
"keywords": [
"datetime-picker",
@@ -1,14 +1,623 @@
## 1.2.242024-06-04
### [1.2.24](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.2.23...v1.2.24) (2024-06-03)
## 1.8.02025-03-23
## [1.8.0](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.7.1...v1.8.0) (2025-03-23)
### ✨ Features | 新功能
* ✨ Img 组件添加预览图片属性 ([#945](https://github.com/Moonofweisheng/wot-design-uni/issues/945)) ([34a4878](https://github.com/Moonofweisheng/wot-design-uni/commit/34a48783f37a56fb6ed7a77dd29ee5a406bf989a))
* ✨ 废弃 DateTimePicker 开启插槽开关use-label-slot和use-default-slot ([8d9e5c6](https://github.com/Moonofweisheng/wot-design-uni/commit/8d9e5c66589f1b6eed5faa093f2c28cf2640f5b5))
* ✨ 新增 InputNumber 组件支持长按加减功能 ([#910](https://github.com/Moonofweisheng/wot-design-uni/issues/910)) ([9437087](https://github.com/Moonofweisheng/wot-design-uni/commit/94370876e4ce91faec6e10db5e413dfa27d0f4c2))
* ✨ 重构 Signature 签字板历史记录模式并添加压感模式和横屏示例 ([#967](https://github.com/Moonofweisheng/wot-design-uni/issues/967)) ([aad3e83](https://github.com/Moonofweisheng/wot-design-uni/commit/aad3e8332b4cb6a1f9c0a3c81e9fb7d5068f09b3))
* ✨ Signature 添加历史记录和历史记录步长(包含文档添加、i18n、代码示例) ([#889](https://github.com/Moonofweisheng/wot-design-uni/issues/889)) ([10ec731](https://github.com/Moonofweisheng/wot-design-uni/commit/10ec731b8986f7bf5903a923fe7f1f7d78623ecf))
* extend wd-fab component with 4 new positions and update docs ([6f12aa4](https://github.com/Moonofweisheng/wot-design-uni/commit/6f12aa4b04477a2b1f8535e272699333ceb0b9f6))
### Bug Fixes | Bug 修复
* 修复Input支付宝小程序number/digit类型使用maxlength=-1时v-model失效的问题 ([7aa21b0](https://github.com/Moonofweisheng/wot-design-uni/commit/7aa21b0baadeccf4f0eb179f74332013acec6a10))
* 修复 DateTimePicker 区域选择时边界值处理错误的问题 ([230e09f](https://github.com/Moonofweisheng/wot-design-uni/commit/230e09ff2ac25550b0efc2628827b70162041aad))
* 修复 drop-menu-item 有选项值为空字符串时导致新值错误并触发组件内部警告的问题 ([f63de5b](https://github.com/Moonofweisheng/wot-design-uni/commit/f63de5bd1d3453e844c058a9f185c0a5e56bcf67))
* 修复在template中使用readonly无法通过vue-ts校验的问题 ([ee5b25f](https://github.com/Moonofweisheng/wot-design-uni/commit/ee5b25fbc36a24cab02576757226f26fb9e27777))
* 修复input、textarea组件placeholder样式在微信小程序无效的问题 ([#944](https://github.com/Moonofweisheng/wot-design-uni/issues/944)) ([1ac115f](https://github.com/Moonofweisheng/wot-design-uni/commit/1ac115fdac310760e630e8745b438f96c6b88386)), closes [#943](https://github.com/Moonofweisheng/wot-design-uni/issues/943)
* 修复textarea统计多码元字符长度错误的问题 ([#940](https://github.com/Moonofweisheng/wot-design-uni/issues/940)) ([f9d8523](https://github.com/Moonofweisheng/wot-design-uni/commit/f9d85232c4142f0c957fa3c829dd3321c7ad56e5)), closes [#933](https://github.com/Moonofweisheng/wot-design-uni/issues/933)
* **picker:** clear selected value and options when columns is emptied ([496cb73](https://github.com/Moonofweisheng/wot-design-uni/commit/496cb732b1ab0e69517d629e147b673692631f98)), closes [#935](https://github.com/Moonofweisheng/wot-design-uni/issues/935)
### Documentation | 文档
* 接入 petercatai 聊天助手 ([34f0299](https://github.com/Moonofweisheng/wot-design-uni/commit/34f02997dd79f88de89da79791d5a6c056367e8a))
* 添加优秀案例页面 ([ef7c98b](https://github.com/Moonofweisheng/wot-design-uni/commit/ef7c98bffb843129d872c8ebc6a1bbaf7d8437bf))
* 新增优秀案例——随享小栈 ([2040230](https://github.com/Moonofweisheng/wot-design-uni/commit/2040230064989bf4816932870920f52ae0797bf2))
* 修复 Navbar 文档部分标题显示 Tabbar 的问题 ([b4b4d59](https://github.com/Moonofweisheng/wot-design-uni/commit/b4b4d594fc29fe1f947b6ea7e8b5b90cc3f58013))
* 修复部分文档拼写错误 ([#911](https://github.com/Moonofweisheng/wot-design-uni/issues/911)) ([15613b3](https://github.com/Moonofweisheng/wot-design-uni/commit/15613b393aaf750a85e03512c41ffed473471228))
* fix drop-menu demo code type error ([#905](https://github.com/Moonofweisheng/wot-design-uni/issues/905)) ([0c32c29](https://github.com/Moonofweisheng/wot-design-uni/commit/0c32c29969a8fcb748409a17a06cf277202a18a7))
# 更新日志
## [1.8.0](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.7.1...v1.8.0) (2025-03-23)
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复 DateTimePicker 区域选择时边界值处理错误的问题 ([230e09f](https://github.com/Moonofweisheng/wot-design-uni/commit/230e09ff2ac25550b0efc2628827b70162041aad))
* 🐛 修复 drop-menu-item 有选项值为空字符串时导致新值错误并触发组件内部警告的问题 ([f63de5b](https://github.com/Moonofweisheng/wot-design-uni/commit/f63de5bd1d3453e844c058a9f185c0a5e56bcf67))
* 🐛 修复在template中使用readonly无法通过vue-ts校验的问题 ([ee5b25f](https://github.com/Moonofweisheng/wot-design-uni/commit/ee5b25fbc36a24cab02576757226f26fb9e27777))
* 🐛 修复input、textarea组件placeholder样式在微信小程序无效的问题 ([#944](https://github.com/Moonofweisheng/wot-design-uni/issues/944)) ([1ac115f](https://github.com/Moonofweisheng/wot-design-uni/commit/1ac115fdac310760e630e8745b438f96c6b88386)), closes [#943](https://github.com/Moonofweisheng/wot-design-uni/issues/943)
* 🐛 修复textarea统计多码元字符长度错误的问题 ([#940](https://github.com/Moonofweisheng/wot-design-uni/issues/940)) ([f9d8523](https://github.com/Moonofweisheng/wot-design-uni/commit/f9d85232c4142f0c957fa3c829dd3321c7ad56e5)), closes [#933](https://github.com/Moonofweisheng/wot-design-uni/issues/933)
* **picker:** clear selected value and options when columns is emptied ([496cb73](https://github.com/Moonofweisheng/wot-design-uni/commit/496cb732b1ab0e69517d629e147b673692631f98)), closes [#935](https://github.com/Moonofweisheng/wot-design-uni/issues/935)
### ✨ Features | 新功能
* ✨ Img 组件添加预览图片属性 ([#945](https://github.com/Moonofweisheng/wot-design-uni/issues/945)) ([34a4878](https://github.com/Moonofweisheng/wot-design-uni/commit/34a48783f37a56fb6ed7a77dd29ee5a406bf989a))
* ✨ 废弃 DateTimePicker 开启插槽开关use-label-slot和use-default-slot ([8d9e5c6](https://github.com/Moonofweisheng/wot-design-uni/commit/8d9e5c66589f1b6eed5faa093f2c28cf2640f5b5))
* ✨ 新增 InputNumber 组件支持长按加减功能 ([#910](https://github.com/Moonofweisheng/wot-design-uni/issues/910)) ([9437087](https://github.com/Moonofweisheng/wot-design-uni/commit/94370876e4ce91faec6e10db5e413dfa27d0f4c2))
* ✨ 重构 Signature 签字板历史记录模式并添加压感模式和横屏示例 ([#967](https://github.com/Moonofweisheng/wot-design-uni/issues/967)) ([aad3e83](https://github.com/Moonofweisheng/wot-design-uni/commit/aad3e8332b4cb6a1f9c0a3c81e9fb7d5068f09b3))
* ✨ Signature 添加历史记录和历史记录步长(包含文档添加、i18n、代码示例) ([#889](https://github.com/Moonofweisheng/wot-design-uni/issues/889)) ([10ec731](https://github.com/Moonofweisheng/wot-design-uni/commit/10ec731b8986f7bf5903a923fe7f1f7d78623ecf))
* extend wd-fab component with 4 new positions and update docs ([6f12aa4](https://github.com/Moonofweisheng/wot-design-uni/commit/6f12aa4b04477a2b1f8535e272699333ceb0b9f6))
### ✏️ Documentation | 文档
* ✏️ 接入 petercatai 聊天助手 ([34f0299](https://github.com/Moonofweisheng/wot-design-uni/commit/34f02997dd79f88de89da79791d5a6c056367e8a))
* ✏️ 添加优秀案例页面 ([ef7c98b](https://github.com/Moonofweisheng/wot-design-uni/commit/ef7c98bffb843129d872c8ebc6a1bbaf7d8437bf))
* ✏️ 新增优秀案例——随享小栈 ([2040230](https://github.com/Moonofweisheng/wot-design-uni/commit/2040230064989bf4816932870920f52ae0797bf2))
* ✏️ 修复 Navbar 文档部分标题显示 Tabbar 的问题 ([b4b4d59](https://github.com/Moonofweisheng/wot-design-uni/commit/b4b4d594fc29fe1f947b6ea7e8b5b90cc3f58013))
* ✏️ 修复部分文档拼写错误 ([#911](https://github.com/Moonofweisheng/wot-design-uni/issues/911)) ([15613b3](https://github.com/Moonofweisheng/wot-design-uni/commit/15613b393aaf750a85e03512c41ffed473471228))
* fix drop-menu demo code type error ([#905](https://github.com/Moonofweisheng/wot-design-uni/issues/905)) ([0c32c29](https://github.com/Moonofweisheng/wot-design-uni/commit/0c32c29969a8fcb748409a17a06cf277202a18a7))
### [1.7.1](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.7.0...v1.7.1) (2025-02-19)
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复 InputNumber 微信小程序设置了precision后无法输入小数点的问题 ([#902](https://github.com/Moonofweisheng/wot-design-uni/issues/902)) ([e3a03b1](https://github.com/Moonofweisheng/wot-design-uni/commit/e3a03b1dbb6640b76a3034daeebd88d42252508c)), closes [#878](https://github.com/Moonofweisheng/wot-design-uni/issues/878)
* 🐛 修复 Upload 文档自定义唤起上传样式的示例错误的问题 ([3dfa69c](https://github.com/Moonofweisheng/wot-design-uni/commit/3dfa69c282514bd786d3822963f3f1dd18089eb9))
* 🐛 修复分页组件为0时不更新页数问题 ([#903](https://github.com/Moonofweisheng/wot-design-uni/issues/903)) ([604faeb](https://github.com/Moonofweisheng/wot-design-uni/commit/604faebf4bb19eca96ba84ee48424be12ee72ba3)), closes [#897](https://github.com/Moonofweisheng/wot-design-uni/issues/897)
* 🐛 修复web-types可选值/默认值类型识别错误 ([#899](https://github.com/Moonofweisheng/wot-design-uni/issues/899)) ([8b4d2ed](https://github.com/Moonofweisheng/wot-design-uni/commit/8b4d2ed14b6340003c63d10e31c02f058bed3ef0))
### ✏️ Documentation | 文档
* ✏️ 优化demo项目的展示方便支付宝平台提审 ([c48a67b](https://github.com/Moonofweisheng/wot-design-uni/commit/c48a67b027b9b3f66f0b051ee34bde163feda6cf))
## [1.7.0](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.6.1...v1.7.0) (2025-02-16)
### ✨ Features | 新功能
* ✨ 添加 web-type.json 支持 webstorm 代码提示 ([#871](https://github.com/Moonofweisheng/wot-design-uni/issues/871)) ([4575099](https://github.com/Moonofweisheng/wot-design-uni/commit/4575099b9ba580fee2c03e8f8660bbfd9aa70aa3)), closes [#819](https://github.com/Moonofweisheng/wot-design-uni/issues/819)
* ✨ 重构 Curtain 优化控制展示隐藏的实现逻辑 ([#895](https://github.com/Moonofweisheng/wot-design-uni/issues/895)) ([0e31950](https://github.com/Moonofweisheng/wot-design-uni/commit/0e3195059e0843045533b7ff89b9a3613c5449a8))
* ✨ ActionSheet 支持 close-on-click-action 控制点击选项后是否关闭菜单功能 ([#891](https://github.com/Moonofweisheng/wot-design-uni/issues/891)) ([a1b035a](https://github.com/Moonofweisheng/wot-design-uni/commit/a1b035a6fe3a9ae3a023032b6c33403853424559)), closes [#698](https://github.com/Moonofweisheng/wot-design-uni/issues/698)
* ✨ NavbarCapsule 导航胶囊组件支持外部传入样式 ([fb980e7](https://github.com/Moonofweisheng/wot-design-uni/commit/fb980e7d9bd90c76570d2069a9d41a6c1187ef30))
* ✨ Rate 评分新增支持半选和触摸滑动选中 ([#896](https://github.com/Moonofweisheng/wot-design-uni/issues/896)) ([9d34f2e](https://github.com/Moonofweisheng/wot-design-uni/commit/9d34f2e5d90cca1820d69100bca7c546ce16fb0e)), closes [#669](https://github.com/Moonofweisheng/wot-design-uni/issues/669)
* ✨ Toast 支持设置布局方向 ([ed60852](https://github.com/Moonofweisheng/wot-design-uni/commit/ed60852432999d295e4af2efe9f1ee86e235e1ee)), closes [#780](https://github.com/Moonofweisheng/wot-design-uni/issues/780)
* ✨ Toast 支持通过props设置组件属性并新增局中显示的配置 ([#888](https://github.com/Moonofweisheng/wot-design-uni/issues/888)) ([ebbe7e4](https://github.com/Moonofweisheng/wot-design-uni/commit/ebbe7e407904df428564dcf53e5141c14d9e7daa))
### ✏️ Documentation | 文档
* ✏️ 标注 Form 组件支持不校验隐藏子组件的版本 ([e5a24c4](https://github.com/Moonofweisheng/wot-design-uni/commit/e5a24c4873baa9db62ad1ab6f3adb078dac89dc2))
* ✏️ 新增关于页面展示主要团队成员信息 ([031107d](https://github.com/Moonofweisheng/wot-design-uni/commit/031107d5888c2887ea40d47810239cd398f042ef))
* ✏️ 修复 SwipeAction 文档示例拼写错误的问题 ([1dc48cf](https://github.com/Moonofweisheng/wot-design-uni/commit/1dc48cfce9773a0ec60dd2b6cb8fd6c60bb63281))
* ✏️ 修复文档拼写的错误 ([8f8cb10](https://github.com/Moonofweisheng/wot-design-uni/commit/8f8cb1077aa318e9fb067dfeebdd04dfbdb12412))
* ✏️ fix create-uni command error ([#874](https://github.com/Moonofweisheng/wot-design-uni/issues/874)) ([a0da88c](https://github.com/Moonofweisheng/wot-design-uni/commit/a0da88c5db21b7127de9342aabcf6961b611e22d))
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复 InputNumber 设置了precision后无法输入小数点的问题 ([#886](https://github.com/Moonofweisheng/wot-design-uni/issues/886)) ([dd1a005](https://github.com/Moonofweisheng/wot-design-uni/commit/dd1a00596472023c9b6e545dbf2a9a8238e67baf)), closes [#878](https://github.com/Moonofweisheng/wot-design-uni/issues/878)
* 🐛 修复 Swiper 在微信小程序平台轮播视频时在iOS平台全屏展示异常的问题 ([#898](https://github.com/Moonofweisheng/wot-design-uni/issues/898)) ([34a15ac](https://github.com/Moonofweisheng/wot-design-uni/commit/34a15ac0786d003825491cc9fa2a8961b307c0d2)), closes [#885](https://github.com/Moonofweisheng/wot-design-uni/issues/885)
* 🐛 修复 Tabs 组件导航地图标题不生效的问题 ([#869](https://github.com/Moonofweisheng/wot-design-uni/issues/869)) ([ccf976a](https://github.com/Moonofweisheng/wot-design-uni/commit/ccf976ad631b4ad0272d4897a6245cdd8f13fa4b))
* 🐛 修复 Upload 组件自定义上传方法不支持asyncfunction的问题 ([#890](https://github.com/Moonofweisheng/wot-design-uni/issues/890)) ([25649db](https://github.com/Moonofweisheng/wot-design-uni/commit/25649dbca55059cb425ba7d7b4e0af7884366dce)), closes [#859](https://github.com/Moonofweisheng/wot-design-uni/issues/859)
### [1.6.1](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.6.0...v1.6.1) (2025-01-20)
### ✏️ Documentation | 文档
* ✏️ 更新文档小程序二维码 ([a5f862b](https://github.com/Moonofweisheng/wot-design-uni/commit/a5f862bdbea6a84df7ad2e3bef4456baae040ae8))
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复 Search placeholder 样式丢失的问题 ([#857](https://github.com/Moonofweisheng/wot-design-uni/issues/857)) ([40565d1](https://github.com/Moonofweisheng/wot-design-uni/commit/40565d19688f6776cdb4ea4b9fc3f6cbaeb4dc66)), closes [#856](https://github.com/Moonofweisheng/wot-design-uni/issues/856)
## [1.6.0](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.5.1...v1.6.0) (2025-01-18)
### ✏️ Documentation | 文档
* ✏️ 常见问题添加Vue 3.3+使用defineOptions设置styleIsolation规则的介绍 ([f3bee13](https://github.com/Moonofweisheng/wot-design-uni/commit/f3bee13b46ccbb8856b9051a99ed2b5356dc0d8e)), closes [#784](https://github.com/Moonofweisheng/wot-design-uni/issues/784)
* ✏️ 更新组件库互助群二维码 ([9b50d6c](https://github.com/Moonofweisheng/wot-design-uni/commit/9b50d6c6922e34c964621cff926565cb9fb723ab))
* ✏️ 添加互助交流QQ群3群二维码 ([1d0b11b](https://github.com/Moonofweisheng/wot-design-uni/commit/1d0b11b25621b7b585fe1e047093d07861c88a30))
* ✏️ 微信小程序演示demo提供激励视频广告页面 ([#783](https://github.com/Moonofweisheng/wot-design-uni/issues/783)) ([7ed7dd3](https://github.com/Moonofweisheng/wot-design-uni/commit/7ed7dd3495c84f91ed5e77870da7e5845fc28a94))
* ✏️ 修复 Tooltip 文档显示异常的问题 ([c89eb92](https://github.com/Moonofweisheng/wot-design-uni/commit/c89eb927a21e0f4e10d317346c31ab45d322720d))
* ✏️ 演示demo小程序支持分享 ([583acc2](https://github.com/Moonofweisheng/wot-design-uni/commit/583acc2fa942422469abcab5f805a54c72614d69))
* ✏️ 优化演示demo支持在顶部显示对应页面微信小程序的二维码 ([b1f42af](https://github.com/Moonofweisheng/wot-design-uni/commit/b1f42af640a32d8c9119331a19fe0495a908b16c))
* ✏️修改自定义样式描述 [#772](https://github.com/Moonofweisheng/wot-design-uni/issues/772) ([1ac352d](https://github.com/Moonofweisheng/wot-design-uni/commit/1ac352da9539e60ac79bd1ec10768e08e4d49ff3))
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复 Calendar 为周选择时跨年周的单元格值显示错误的问题 ([#854](https://github.com/Moonofweisheng/wot-design-uni/issues/854)) ([c0d48b2](https://github.com/Moonofweisheng/wot-design-uni/commit/c0d48b25c11af87629e7feedc6cd0cc3a70b37e4))
* 🐛 修复 Divider 分割线组件 CustomClass 未生效的问题 ([#790](https://github.com/Moonofweisheng/wot-design-uni/issues/790)) ([44df081](https://github.com/Moonofweisheng/wot-design-uni/commit/44df081dbd80771a9df122be4e3953034194308f)), closes [#789](https://github.com/Moonofweisheng/wot-design-uni/issues/789)
* 🐛 修复 Form 表单 validator 校验不通过且未指定错误信息时无法显示校验信息的问题 ([#791](https://github.com/Moonofweisheng/wot-design-uni/issues/791)) ([bdb5653](https://github.com/Moonofweisheng/wot-design-uni/commit/bdb56537db7fbec59224ebf5aecd3e7a6354424c))
* 🐛 修复Button初始化margin的问题 ([#831](https://github.com/Moonofweisheng/wot-design-uni/issues/831)) ([3836309](https://github.com/Moonofweisheng/wot-design-uni/commit/38363097a5fbf4c0c7116abd536f90936d2fa86d))
* 🐛 修复Card footer或者header没写的时候,不会自动隐藏占位 ([8d528cb](https://github.com/Moonofweisheng/wot-design-uni/commit/8d528cb9c06c48456016e0a4cce1cf0699b7311b))
* 🐛 修复Form组件rules属性,没有按照顺序执行问题 ([#808](https://github.com/Moonofweisheng/wot-design-uni/issues/808)) ([834cd8e](https://github.com/Moonofweisheng/wot-design-uni/commit/834cd8e3f08919800189c1d2710267d4aa99a8d5)), closes [#799](https://github.com/Moonofweisheng/wot-design-uni/issues/799) [#799](https://github.com/Moonofweisheng/wot-design-uni/issues/799) [#799](https://github.com/Moonofweisheng/wot-design-uni/issues/799)
* 🐛 修复Input初始化修改失败的问题 ([#814](https://github.com/Moonofweisheng/wot-design-uni/issues/814)) ([04e9a50](https://github.com/Moonofweisheng/wot-design-uni/commit/04e9a50ede30337c35e9f28b7f7985f3e717a91f))
* 🐛 修复Picker文档初始选项code错误的问题 ([67f675d](https://github.com/Moonofweisheng/wot-design-uni/commit/67f675d1cc4764e25d357b91c17ad276612340a1))
* 🐛 修复popover tooltip组件visibleArrow=false时弹出框距离元素间距过远的问题 ([#792](https://github.com/Moonofweisheng/wot-design-uni/issues/792)) ([3b6d10d](https://github.com/Moonofweisheng/wot-design-uni/commit/3b6d10dbb93188adb3aea3fc9f7d1b763b4d5ec9)), closes [#788](https://github.com/Moonofweisheng/wot-design-uni/issues/788)
### ✨ Features | 新功能
* ✨ 新增Signature签名组件 ([0ad8fcc](https://github.com/Moonofweisheng/wot-design-uni/commit/0ad8fcce28f5692572aeae79f0cc7315aa6e5b54)), closes [#505](https://github.com/Moonofweisheng/wot-design-uni/issues/505)
* ✨ 修复 InputNumber 在设置为 allow-null 时被赋值为空时未触发更新的问题并支持异步更新 ([#812](https://github.com/Moonofweisheng/wot-design-uni/issues/812)) ([0fc90dd](https://github.com/Moonofweisheng/wot-design-uni/commit/0fc90ddcc9b5d478fe3e5bf84e2e780c48a8a341))
* ✨ 修复Img组件在错误状态下可以预览的问题 ([dbd2c85](https://github.com/Moonofweisheng/wot-design-uni/commit/dbd2c85b83b0992e791c0b828a12f182d4923b81))
* ✨ Calendar 确认事件 confirm 增加 `type` 参数 ([e0fca91](https://github.com/Moonofweisheng/wot-design-uni/commit/e0fca9161e8282871b2126ecc82999bc9530eb6b))
* ✨ Form 表单 validate 方法支持传入数组 ([#829](https://github.com/Moonofweisheng/wot-design-uni/issues/829)) ([8e6096a](https://github.com/Moonofweisheng/wot-design-uni/commit/8e6096ab7459b9164ef1ec9b366becf9acc7ab83)), closes [#797](https://github.com/Moonofweisheng/wot-design-uni/issues/797)
* ✨ Search新增customInputClassplaceholderClass等属性 ([#845](https://github.com/Moonofweisheng/wot-design-uni/issues/845)) ([03623f4](https://github.com/Moonofweisheng/wot-design-uni/commit/03623f4989b6bfbf53588058c632eb2f2e830bfd)), closes [#299](https://github.com/Moonofweisheng/wot-design-uni/issues/299)
* ✨ Swiper 轮播视频支持控制静音播放和循环播放 ([#855](https://github.com/Moonofweisheng/wot-design-uni/issues/855)) ([7a0d5ce](https://github.com/Moonofweisheng/wot-design-uni/commit/7a0d5ce9720020e3f0fb148f7b65db129ceb82af)), closes [#846](https://github.com/Moonofweisheng/wot-design-uni/issues/846)
* ✨ Swiper 轮播项type字段的处理逻辑限制在可选值范围内 ([#785](https://github.com/Moonofweisheng/wot-design-uni/issues/785)) ([1fd0a27](https://github.com/Moonofweisheng/wot-design-uni/commit/1fd0a27788db2b467bc53e83a6a4953e5d134c53))
### [1.5.1](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.5.0...v1.5.1) (2024-12-10)
### 🐛 Bug Fixes | Bug 修复
* 🐛 调整 Upload 的覆盖上传参数 reupload 默认值为 false ([d9ce000](https://github.com/Moonofweisheng/wot-design-uni/commit/d9ce00010a15ae8e168e082a2c4f3a50cf61fa13))
## [1.5.0](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.4.0...v1.5.0) (2024-12-09)
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复 Button 按钮设置为 block 无效的问题 ([#762](https://github.com/Moonofweisheng/wot-design-uni/issues/762)) ([ea8bc66](https://github.com/Moonofweisheng/wot-design-uni/commit/ea8bc6671012a811f49027062e6e7f8f1359a175))
* 🐛 修复 Cell 设置 label 过长时影响页面结构的问题 ([70058f2](https://github.com/Moonofweisheng/wot-design-uni/commit/70058f2270788fb9d7edd56eff35bd2cbebcd99e))
* 🐛 修复 Collapse v-model绑定数据变化时未更新折叠面板状态的问题 ([#744](https://github.com/Moonofweisheng/wot-design-uni/issues/744)) ([09f7f9c](https://github.com/Moonofweisheng/wot-design-uni/commit/09f7f9caf5e381ef44fb9a31965f8d2d70d4e271)), closes [#741](https://github.com/Moonofweisheng/wot-design-uni/issues/741)
* 🐛 修复 GridItem 徽标属性类型标注错误的问题 ([c018560](https://github.com/Moonofweisheng/wot-design-uni/commit/c018560b7d3087b89b759b3c83aff91c74354021)), closes [#766](https://github.com/Moonofweisheng/wot-design-uni/issues/766)
* 🐛 修复 Progress 无法设置进度为 0 的问题 ([#748](https://github.com/Moonofweisheng/wot-design-uni/issues/748)) ([c136f54](https://github.com/Moonofweisheng/wot-design-uni/commit/c136f54cda6164ab3653d47342d7c88c5f515efc)), closes [#747](https://github.com/Moonofweisheng/wot-design-uni/issues/747)
* 🐛 修复 Swiper 在支付宝小程序平台点击事件无效的问题 ([f63bf10](https://github.com/Moonofweisheng/wot-design-uni/commit/f63bf101338d7f9d2f72c5941d3405950544a1d7))
* 🐛 修复 Tab 未渲染项高度会影响整体高度的问题 ([5e06378](https://github.com/Moonofweisheng/wot-design-uni/commit/5e063781a3b58f94f107816473600ce95f3761e9))
* 🐛 修复 vue-tsc 校验不通过的问题 ([#753](https://github.com/Moonofweisheng/wot-design-uni/issues/753)) ([a90f4ad](https://github.com/Moonofweisheng/wot-design-uni/commit/a90f4ad2f2b68bb79f30a2e6973a4e149b7ba66e)), closes [#752](https://github.com/Moonofweisheng/wot-design-uni/issues/752)
* 🐛 修复微信小程序在iOS设备上处于后台一段时间后抖动的问题 ([6091566](https://github.com/Moonofweisheng/wot-design-uni/commit/6091566380c7c129fca284eb4e5a2ba6e447a7ab)), closes [#694](https://github.com/Moonofweisheng/wot-design-uni/issues/694)
### ✏️ Documentation | 文档
* ✏️ 调整文档结构增加文档内容可用宽度,支持收起演示demo ([#765](https://github.com/Moonofweisheng/wot-design-uni/issues/765)) ([402f73f](https://github.com/Moonofweisheng/wot-design-uni/commit/402f73f6ee8aa7d022b640333e6bfef4311fdc6f))
* ✏️ 添加 MessageBox 自定义按钮样式的文档 ([46b1c39](https://github.com/Moonofweisheng/wot-design-uni/commit/46b1c394a024c293fb07c7788691e2ac572a2fa1))
* ✏️ 添加关于Sass的介绍 ([995a65f](https://github.com/Moonofweisheng/wot-design-uni/commit/995a65f8451801062ae83f0f71470d0c428dba7f))
* ✏️ 优化 Cell 关于 clickable 和 is-link 的介绍 ([6f58e72](https://github.com/Moonofweisheng/wot-design-uni/commit/6f58e72b1d5436326052a79da19e21d071ab9b3c))
* ✏️ 增加 ConfigProvider 组件设定全局共享示例 ([#758](https://github.com/Moonofweisheng/wot-design-uni/issues/758)) ([356cb4a](https://github.com/Moonofweisheng/wot-design-uni/commit/356cb4ad11791366138002233754b2d2e79d5d18))
* ✏️ Table 表格组件提供结合分页器使用的demo ([#738](https://github.com/Moonofweisheng/wot-design-uni/issues/738)) ([fb7580d](https://github.com/Moonofweisheng/wot-design-uni/commit/fb7580df7eee7d81d3826c399e565975cef81625))
### ✨ Features | 新功能
* ✨ 优化 Divider 分割线功能支持虚线、垂直等功能 ([#737](https://github.com/Moonofweisheng/wot-design-uni/issues/737)) ([1b9d7e6](https://github.com/Moonofweisheng/wot-design-uni/commit/1b9d7e625256b365a381b30e902bb54692d636cf))
* ✨ Calendar 优化选中样式和滚动位置处理并支持屏蔽内置cell ([#768](https://github.com/Moonofweisheng/wot-design-uni/issues/768)) ([97c4004](https://github.com/Moonofweisheng/wot-design-uni/commit/97c40047e8ed46af31d4c1647056d90c2edf4842))
* ✨ Curtain 幕帘新增 close 插槽和自定义关闭插槽样式类 ([#746](https://github.com/Moonofweisheng/wot-design-uni/issues/746)) ([7bc3592](https://github.com/Moonofweisheng/wot-design-uni/commit/7bc359205deb99899baf01c733af9690b12703fa)), closes [#648](https://github.com/Moonofweisheng/wot-design-uni/issues/648)
* ✨ DropMenuItem 增加自定 Popup 样式参数 ([28ad03b](https://github.com/Moonofweisheng/wot-design-uni/commit/28ad03b7afdd38a86f168d15a7c0f3564d122101))
* ✨ Input、Textarea在APP-VUE和H5端支持inputmode ([#771](https://github.com/Moonofweisheng/wot-design-uni/issues/771)) ([9ceb2e8](https://github.com/Moonofweisheng/wot-design-uni/commit/9ceb2e807e33edd3937db5f57a4306f1ce719cff)), closes [#743](https://github.com/Moonofweisheng/wot-design-uni/issues/743)
* ✨ MessageBox 新增确认、取消按钮的 ButtonProps 属性 ([#761](https://github.com/Moonofweisheng/wot-design-uni/issues/761)) ([80682ba](https://github.com/Moonofweisheng/wot-design-uni/commit/80682ba933427fac7bfefc6c692cd058a14163c5)), closes [#740](https://github.com/Moonofweisheng/wot-design-uni/issues/740)
* ✨ Radio添加icon-placement属性用于控制图标方向 ([#763](https://github.com/Moonofweisheng/wot-design-uni/issues/763)) ([b06a7a7](https://github.com/Moonofweisheng/wot-design-uni/commit/b06a7a751b3115c8e3909af4cbe595684ed9d00f)), closes [#371](https://github.com/Moonofweisheng/wot-design-uni/issues/371)
* ✨ Segmented 提供 updateActiveStyle 方法设置激活样式 ([529e57f](https://github.com/Moonofweisheng/wot-design-uni/commit/529e57fc83b00482f101e84cf0437627e140a59f))
* ✨ Table 支持设置不固定表头 ([#769](https://github.com/Moonofweisheng/wot-design-uni/issues/769)) ([b0a2461](https://github.com/Moonofweisheng/wot-design-uni/commit/b0a2461a1a6f9691502a1f4a1a06ec4103fabd4b))
* ✨ Upload 支持文件重传 ([3cd5137](https://github.com/Moonofweisheng/wot-design-uni/commit/3cd5137129ae13f90744a5d0038686cef5602d8c))
## [1.4.0](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.3.14...v1.4.0) (2024-11-24)
### ✨ Features | 新功能
* ✨ Curtain 幕帘组件支持设置 z-index ([a1e20af](https://github.com/Moonofweisheng/wot-design-uni/commit/a1e20afef34704e518a96d4b4cb248cab3b7a8b6))
* ✨ Siderbar 侧边栏添加before-change属性支持异步更新 ([#721](https://github.com/Moonofweisheng/wot-design-uni/issues/721)) ([1f5801d](https://github.com/Moonofweisheng/wot-design-uni/commit/1f5801d3f4c2cfc1b3990d74077e18ea88e8d7f8)), closes [#711](https://github.com/Moonofweisheng/wot-design-uni/issues/711)
* ✨ Swiper 支持指定轮播项的文件类型 ([#720](https://github.com/Moonofweisheng/wot-design-uni/issues/720)) ([1e039cb](https://github.com/Moonofweisheng/wot-design-uni/commit/1e039cb7073d57bd19f59d4ffbb95c74b5cdc42f)), closes [#712](https://github.com/Moonofweisheng/wot-design-uni/issues/712)
* ✨ Tab 添加 lazy 属性支持配置是否开启懒加载 ([bb5b193](https://github.com/Moonofweisheng/wot-design-uni/commit/bb5b19325fc2a0f4d13d353ee9bc8cfbf8605daa)), closes [#641](https://github.com/Moonofweisheng/wot-design-uni/issues/641)
* ✨ Tabs 新增 `autoLineWidth` 设置底部条宽度自动同步文本内容' ([#679](https://github.com/Moonofweisheng/wot-design-uni/issues/679)) ([cb7cbf3](https://github.com/Moonofweisheng/wot-design-uni/commit/cb7cbf33250e3711d631271b1bbcb5f6829e75fa))
* ✨ Tabs 新增map-title属性支持修改导航地图标题 ([0b7605f](https://github.com/Moonofweisheng/wot-design-uni/commit/0b7605f3ef2ca11cedc2cc61a3eb93e0757e6b86)), closes [#670](https://github.com/Moonofweisheng/wot-design-uni/issues/670)
* ✨ Tabs 支持设置徽标 ([#724](https://github.com/Moonofweisheng/wot-design-uni/issues/724)) ([cd20581](https://github.com/Moonofweisheng/wot-design-uni/commit/cd20581ca6f75a67995a0cf562f524d82e357bbc)), closes [#689](https://github.com/Moonofweisheng/wot-design-uni/issues/689) [#672](https://github.com/Moonofweisheng/wot-design-uni/issues/672)
* ✨ tabs支持左对齐 ([#718](https://github.com/Moonofweisheng/wot-design-uni/issues/718)) ([314c2e8](https://github.com/Moonofweisheng/wot-design-uni/commit/314c2e8c9d08e806dd0ec78fd4b2aa5e536af8f8)), closes [#380](https://github.com/Moonofweisheng/wot-design-uni/issues/380)
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复 Collapse 使用 toggleAall 方法时不会触发 before-expand 钩子的问题 ([#727](https://github.com/Moonofweisheng/wot-design-uni/issues/727)) ([02aa5ce](https://github.com/Moonofweisheng/wot-design-uni/commit/02aa5ceb78713f210d97ecc29f18618084b93096))
* 🐛 修复 CollapseItem 在微信小程序平台使用 title 插槽时宽度无法撑满的问题 ([4f1d945](https://github.com/Moonofweisheng/wot-design-uni/commit/4f1d9452ecd5054a636fb51871369ee1f183e1f1))
* 🐛 修复 DateTimePicker 设置为 time 类型时绑定值无法设置为空数组的问题 ([443ac92](https://github.com/Moonofweisheng/wot-design-uni/commit/443ac929820327339062a608ef94db43bdaafb27)), closes [#706](https://github.com/Moonofweisheng/wot-design-uni/issues/706)
* 🐛 修复 FloadingPanel 设置 height 不生效的问题 ([#725](https://github.com/Moonofweisheng/wot-design-uni/issues/725)) ([3cc1805](https://github.com/Moonofweisheng/wot-design-uni/commit/3cc18058aee83ed0abbf804595e38d7934490f4a)), closes [#703](https://github.com/Moonofweisheng/wot-design-uni/issues/703)
* 🐛 修复 Slider 滑块处于极值时会遮挡max和min的问题 ([aa8834d](https://github.com/Moonofweisheng/wot-design-uni/commit/aa8834df630286882425778263ea9ff68811c928)), closes [#714](https://github.com/Moonofweisheng/wot-design-uni/issues/714)
* 🐛 修复 wd-select-picker 组件单选搜索高亮 class 错误 ([7d461a5](https://github.com/Moonofweisheng/wot-design-uni/commit/7d461a54d09b14273fd18ff37310ecf754cf5138))
* 🐛 修复Collapse折叠面板组件内容溢出问题 ([#710](https://github.com/Moonofweisheng/wot-design-uni/issues/710)) ([4bf8d1e](https://github.com/Moonofweisheng/wot-design-uni/commit/4bf8d1e300c28f405402582dd32fde4245d9ed47))
### ✏️ Documentation | 文档
* ✏️ 调整文档中gitee镜像仓库的地址 ([a40dd9f](https://github.com/Moonofweisheng/wot-design-uni/commit/a40dd9f63e52cf178be2fd9a93904cdf26e23f14))
* ✏️ 调整join-group页面加群的问题 ([9a70d89](https://github.com/Moonofweisheng/wot-design-uni/commit/9a70d89be1e369dc2ea2a4babd3b3fdb326fcecc))
* ✏️ 添加 Cell 单元格 border 属性的文档 ([fad777d](https://github.com/Moonofweisheng/wot-design-uni/commit/fad777dfa8cf8dcf26288a9f975927dc3de2e80d)), closes [#653](https://github.com/Moonofweisheng/wot-design-uni/issues/653)
* ✏️ 添加关于 Button 自定义样式设置阴影的文档 ([c38321f](https://github.com/Moonofweisheng/wot-design-uni/commit/c38321f69c8f4fcb572cb40c8eef38cf4fa20eae)), closes [#731](https://github.com/Moonofweisheng/wot-design-uni/issues/731)
* ✏️ 文档新增演示页面源码和组件源码链接 ([330e8c7](https://github.com/Moonofweisheng/wot-design-uni/commit/330e8c7bbfc792f4a29cdaa08dec8b35c75b2a30))
* ✏️ 优化 NoticeBar 垂直滚动示例 ([ff1d377](https://github.com/Moonofweisheng/wot-design-uni/commit/ff1d37723b38169fc1a1f75676a8464343b42bec))
* ✏️ 增加 Input 字数限制的示例 ([5aa1c00](https://github.com/Moonofweisheng/wot-design-uni/commit/5aa1c00acd72f17cea108ffccecc427711e2cbdb))
* ✏️ 增加关于Tabs属性autoLineWidth的介绍和最低版本要求 ([08e7d77](https://github.com/Moonofweisheng/wot-design-uni/commit/08e7d774c6b6886fe3f79431b4728176e267144f))
### [1.3.14](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.3.13...v1.3.14) (2024-11-09)
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复 Curtain 幕帘组件在某些情况下关闭按钮不显示的问题 ([8c0e978](https://github.com/Moonofweisheng/wot-design-uni/commit/8c0e97831445183662ce0af79210117eb77e63e9)), closes [#690](https://github.com/Moonofweisheng/wot-design-uni/issues/690)
* 🐛 修复Picker和SelectPicker清空按钮颜色与Input不统一的问题 ([#700](https://github.com/Moonofweisheng/wot-design-uni/issues/700)) ([8fdbfa3](https://github.com/Moonofweisheng/wot-design-uni/commit/8fdbfa319a5c0c5895a3162b56cd3225c54a24d2))
* 🐛 修复upload组件header默认值错误的问题 ([4cfd1e5](https://github.com/Moonofweisheng/wot-design-uni/commit/4cfd1e568d55eed9efe9cc1dadcc30dd571d3b36)), closes [#691](https://github.com/Moonofweisheng/wot-design-uni/issues/691)
### ✏️ Documentation | 文档
* ✏️ 文档添加生活小工具 ([6f44a63](https://github.com/Moonofweisheng/wot-design-uni/commit/6f44a631ac067a7321ff0cb6ea8ebaabbc64bd9b))
* ✏️ 文档中添加wot-demo的介绍 ([66fff60](https://github.com/Moonofweisheng/wot-design-uni/commit/66fff6009b261a62be96d4c279d83833c70a8a0f))
* ✏️ 增加create-uni创建快速上手项目的介绍 ([92aa1ef](https://github.com/Moonofweisheng/wot-design-uni/commit/92aa1efe68f4a9bd52942122b2f063384eb885fc))
### ✨ Features | 新功能
* ✨ 使用Transition重构Popup为center类型的Popup添加zoom-in动画 ([#699](https://github.com/Moonofweisheng/wot-design-uni/issues/699)) ([0dd34d0](https://github.com/Moonofweisheng/wot-design-uni/commit/0dd34d06492f9d071ce6c11aa82789fbcc5cd442)), closes [#687](https://github.com/Moonofweisheng/wot-design-uni/issues/687)
* ✨ 移除Switch默认的size支持在不指定size的情况下使用css变量设置组件尺寸 ([5e55da4](https://github.com/Moonofweisheng/wot-design-uni/commit/5e55da4839677c63534148d4664dbde1c9f950b2)), closes [#516](https://github.com/Moonofweisheng/wot-design-uni/issues/516)
* ✨ 优化Toast、Message和Notify组件的函数式调用方案 ([#696](https://github.com/Moonofweisheng/wot-design-uni/issues/696)) ([9f318bd](https://github.com/Moonofweisheng/wot-design-uni/commit/9f318bdeb37bea643276d3e7f8be51bfc1b19d27))
* ✨ 支持Button在支付宝小程序平台opentype设为getAuthorize用于获取手机号和用户信息 ([deeb45d](https://github.com/Moonofweisheng/wot-design-uni/commit/deeb45d8cb47284c1a557b50c3fcd95f80f93c22))
* ✨ Form 校验规则validator支持传入Error作为校验提示 ([db32ef9](https://github.com/Moonofweisheng/wot-design-uni/commit/db32ef962140333a13e2a04ba4642e7423bc4bef)), closes [#667](https://github.com/Moonofweisheng/wot-design-uni/issues/667)
* ✨ Loadmore提供loadingProps属性用于自定义loading样式 ([178e056](https://github.com/Moonofweisheng/wot-design-uni/commit/178e056035511de4123d2bd9ce575948154874b4))
* ✨ Table 行高支持Number和String类型 ([#682](https://github.com/Moonofweisheng/wot-design-uni/issues/682)) ([21f0b17](https://github.com/Moonofweisheng/wot-design-uni/commit/21f0b178b6e3221a69609dd1603960fc866cb534))
### [1.3.13](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.3.12...v1.3.13) (2024-10-25)
### ✏️ Documentation | 文档
* ✏️ 快速上手增加vue和uni-app的快速上手链接 ([20148a7](https://github.com/Moonofweisheng/wot-design-uni/commit/20148a7800d12376adedadb32bf29239f02baef3))
* ✏️ 添加关于深度选择的介绍 ([63428f2](https://github.com/Moonofweisheng/wot-design-uni/commit/63428f244ae84574027ea89e19598c3600716f7b))
* ✏️ 文档新增展示优秀案例 ([47c1764](https://github.com/Moonofweisheng/wot-design-uni/commit/47c176490dabda1937abea8342d02cc6cbbcfc02))
* ✏️ 优化文档快速上手章节 ([4e9a9da](https://github.com/Moonofweisheng/wot-design-uni/commit/4e9a9da914a372f1b0f31cfcc7fbc2f96650ef58))
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复Notice在Tabbar页面时跳转至其他页面导致播放异常的问题并提供reset方法 ([#680](https://github.com/Moonofweisheng/wot-design-uni/issues/680)) ([7584ac2](https://github.com/Moonofweisheng/wot-design-uni/commit/7584ac2a1249b6bee79669ae57c80da08a17d912)), closes [#358](https://github.com/Moonofweisheng/wot-design-uni/issues/358) [#650](https://github.com/Moonofweisheng/wot-design-uni/issues/650)
### ✨ Features | 新功能
* ✨ 为Picker和SelectPicker补充clear事件 ([8fffaa6](https://github.com/Moonofweisheng/wot-design-uni/commit/8fffaa646aad195b33c56719ffb28b2529f3f627))
* ✨ 移除 Navbar 点击热区的激活态样式 ([60b07e5](https://github.com/Moonofweisheng/wot-design-uni/commit/60b07e514b836c55305536e2ba29ec5239b62de3)), closes [#511](https://github.com/Moonofweisheng/wot-design-uni/issues/511)
* ✨ cell组件border属性以props为最高优先级 ([#656](https://github.com/Moonofweisheng/wot-design-uni/issues/656)) ([31353ce](https://github.com/Moonofweisheng/wot-design-uni/commit/31353ceafa3bcae01202c40918e579d141957c0a))
* ✨ picker和selectPicker添加clearable属性 ([b0d60a0](https://github.com/Moonofweisheng/wot-design-uni/commit/b0d60a0b750e8ed2cbae0b55309145c6963e498a))
* ✨ Swiper 轮播组件支持展示视频和设置轮播项标题 ([#663](https://github.com/Moonofweisheng/wot-design-uni/issues/663)) ([a50c0be](https://github.com/Moonofweisheng/wot-design-uni/commit/a50c0be38465342e5b688b8e10b377d69ba998a6))
### [1.3.12](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.3.11...v1.3.12) (2024-10-08)
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复Upload文件小程序找不到文件,显示的问题 ([c13e605](https://github.com/Moonofweisheng/wot-design-uni/commit/c13e6058a2c665c174806aebd353294113c4007e))
* 🐛 Radio修复在cell里面高度的问题 ([f9deacf](https://github.com/Moonofweisheng/wot-design-uni/commit/f9deacf40eed17a37558ca96319880822ca897d5))
### ✏️ Documentation | 文档
* ✏️ 优化捐赠榜单中捐赠人链接的展示效果 ([898f079](https://github.com/Moonofweisheng/wot-design-uni/commit/898f07985e602ad18a84c06b5bd6183dd61142cd))
* ✏️ Upload添加preview-cover最低版本 ([52f9bf6](https://github.com/Moonofweisheng/wot-design-uni/commit/52f9bf654b26a09c20b7118efb331f7e6228ea79))
### ✨ Features | 新功能
* ✨ 新增 FloatingPanel 浮动面板组件 ([#616](https://github.com/Moonofweisheng/wot-design-uni/issues/616)) ([e2966fd](https://github.com/Moonofweisheng/wot-design-uni/commit/e2966fdd01d6c91ab9499fbc95e4f7160a83deb5)), closes [#509](https://github.com/Moonofweisheng/wot-design-uni/issues/509)
* ✨ 新增支持法语、日语等9 种语言 ([#637](https://github.com/Moonofweisheng/wot-design-uni/issues/637)) ([691a7b5](https://github.com/Moonofweisheng/wot-design-uni/commit/691a7b57727af45f3c2f99437740be72e8be0f86))
* ✨ StatusTip缺省提示组件提供图片内容插槽([#538](https://github.com/Moonofweisheng/wot-design-uni/issues/538)) ([#615](https://github.com/Moonofweisheng/wot-design-uni/issues/615)) ([c6b2cf8](https://github.com/Moonofweisheng/wot-design-uni/commit/c6b2cf84db1cb5536516606999c1fa3d6bd1dbe3))
* ✨ ToolTip 组件 offset 属性支持数组和对象写法 ([#625](https://github.com/Moonofweisheng/wot-design-uni/issues/625)) ([5092c5a](https://github.com/Moonofweisheng/wot-design-uni/commit/5092c5a6548fe7222e0d6e2614020f15ce95c5df)), closes [#560](https://github.com/Moonofweisheng/wot-design-uni/issues/560)
* ✨ Upload新增preview-cover插槽 ([ef6433d](https://github.com/Moonofweisheng/wot-design-uni/commit/ef6433d81c576db8b55715a14a574a6d392478df))
* ✨Calendar日历添加open事件 ([#627](https://github.com/Moonofweisheng/wot-design-uni/issues/627)) ([43a5da6](https://github.com/Moonofweisheng/wot-design-uni/commit/43a5da631d4402319d4e3f0739f2ab7e960e497f)), closes [#624](https://github.com/Moonofweisheng/wot-design-uni/issues/624)
### [1.3.11](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.3.10...v1.3.11) (2024-09-23)
### ✏️ Documentation | 文档
* ✏️ 移除文档中CountTo不支持的type ([cae2e56](https://github.com/Moonofweisheng/wot-design-uni/commit/cae2e56aba98427b1b6c7a2c3f6a2f9ed8acf96f))
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复[#598](https://github.com/Moonofweisheng/wot-design-uni/issues/598)产生的使用未定义变量的问题 ([ce64daf](https://github.com/Moonofweisheng/wot-design-uni/commit/ce64daf77d119df509873226c9209cae406e0330))
* 🐛 修复与@uni-helper/uni-typed搭配使用时tsc报类型错误的问题并更新依赖 ([f9ca2e4](https://github.com/Moonofweisheng/wot-design-uni/commit/f9ca2e4d4ed2ef88a073f7f80ce64df811144b3a)), closes [#586](https://github.com/Moonofweisheng/wot-design-uni/issues/586)
* 🐛 修复Button设置为hairline时圆角显示异常的问题 ([10ebf5c](https://github.com/Moonofweisheng/wot-design-uni/commit/10ebf5c3959099389f1f1349e32ad755740ce0d5)), closes [#486](https://github.com/Moonofweisheng/wot-design-uni/issues/486)
* 🐛 修复Input、Textarea未设置labelWidth时通过CSS变量设置label宽度无效的问题 ([#591](https://github.com/Moonofweisheng/wot-design-uni/issues/591)) ([2f12ac6](https://github.com/Moonofweisheng/wot-design-uni/commit/2f12ac6d2b598c7fa545009a82acd1c07bf21779)), closes [#573](https://github.com/Moonofweisheng/wot-design-uni/issues/573)
* 🐛 修复loadmore组件属性errorText存在默认值导致国际化失效的问题 ([#594](https://github.com/Moonofweisheng/wot-design-uni/issues/594)) ([0bcc3c4](https://github.com/Moonofweisheng/wot-design-uni/commit/0bcc3c498ed9206bea45522f58889ec3f3a5f673))
* 🐛 修复Radio点击失效的问题 ([5cce125](https://github.com/Moonofweisheng/wot-design-uni/commit/5cce125c737989e1e447394223129e2e585b91f4)), closes [#596](https://github.com/Moonofweisheng/wot-design-uni/issues/596)
* 🐛确保inputNumber输入值在设定的最小值和最大值之间 ([#610](https://github.com/Moonofweisheng/wot-design-uni/issues/610)) ([344b1ac](https://github.com/Moonofweisheng/wot-design-uni/commit/344b1ac9168701bc408f82268f68ef8453527ef9)), closes [#602](https://github.com/Moonofweisheng/wot-design-uni/issues/602)
### ✨ Features | 新功能
* ✨ 迁移StatusTip组件的图片资源 ([f54ff30](https://github.com/Moonofweisheng/wot-design-uni/commit/f54ff306e7dafcfaead671120d100c4d9482daf9))
* ✨ count-to组件添加type属性 ([#556](https://github.com/Moonofweisheng/wot-design-uni/issues/556)) ([60c92f2](https://github.com/Moonofweisheng/wot-design-uni/commit/60c92f2f38b563968f88f94267b8d805c28109d1))
* ✨ Fab 悬浮按钮组件支持自定义触发器和控制能否展开 ([#612](https://github.com/Moonofweisheng/wot-design-uni/issues/612)) ([8e68ef3](https://github.com/Moonofweisheng/wot-design-uni/commit/8e68ef3bf807b5ec3c935daa6ce68f58962a188d)), closes [#512](https://github.com/Moonofweisheng/wot-design-uni/issues/512)
* ✨ Img组件新增属性 show-menu-by-longpress 支持微信小程序长按弹出菜单栏 ([#613](https://github.com/Moonofweisheng/wot-design-uni/issues/613)) ([a7fc229](https://github.com/Moonofweisheng/wot-design-uni/commit/a7fc22964823af1ee1e513a268fb783bbea77ee4)), closes [#611](https://github.com/Moonofweisheng/wot-design-uni/issues/611)
* ✨ Input、Textarea增加ignoreCompositionEvent属性 ([#592](https://github.com/Moonofweisheng/wot-design-uni/issues/592)) ([efcd4bb](https://github.com/Moonofweisheng/wot-design-uni/commit/efcd4bbb38b5bf53a26f0a8834f0cbd9fa26f5e5)), closes [#574](https://github.com/Moonofweisheng/wot-design-uni/issues/574)
* ✨ InputNumber 步进器新增支持adjustPosition属性 ([f8a5240](https://github.com/Moonofweisheng/wot-design-uni/commit/f8a524010a2945941fbefa745756f2e6efbeb88b)), closes [#599](https://github.com/Moonofweisheng/wot-design-uni/issues/599)
### [1.3.10](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.3.9...v1.3.10) (2024-09-08)
### ✨ Features | 新功能
* ✨ 新增Keyboard虚拟键盘支持车牌号输入 ([#567](https://github.com/Moonofweisheng/wot-design-uni/issues/567)) ([59df1b7](https://github.com/Moonofweisheng/wot-design-uni/commit/59df1b7ce56e9253ad046a7898651a866b8c99d7)), closes [#351](https://github.com/Moonofweisheng/wot-design-uni/issues/351)
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复 col-picker 点击遮罩关闭执行两次问题 ([#584](https://github.com/Moonofweisheng/wot-design-uni/issues/584)) ([8fc5380](https://github.com/Moonofweisheng/wot-design-uni/commit/8fc5380ad1f9a34998aedf1de2a9b05011bd8267))
* 🐛 修复wd-upload 关闭按钮受项目行高影响的问题 ([#576](https://github.com/Moonofweisheng/wot-design-uni/issues/576)) ([feb64ea](https://github.com/Moonofweisheng/wot-design-uni/commit/feb64ea7be1eada01782bb1fa0d5b848acb4fa64))
### ✏️ Documentation | 文档
* ✏️ 文档中添加KeyBoard的版本要求 ([715c054](https://github.com/Moonofweisheng/wot-design-uni/commit/715c054f4c723de73e2d57b940390cc7bcc89273))
* ✏️ 优化多列选择器组件文档 ([#572](https://github.com/Moonofweisheng/wot-design-uni/issues/572)) ([93e0736](https://github.com/Moonofweisheng/wot-design-uni/commit/93e0736a24aa77d60376b5dd4d073180b88a6411))
### [1.3.9](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.3.8...v1.3.9) (2024-09-01)
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复某些场景下wd-textarea属性maxlength无效的问题 ([#558](https://github.com/Moonofweisheng/wot-design-uni/issues/558)) ([4b1b237](https://github.com/Moonofweisheng/wot-design-uni/commit/4b1b2370db4a34716ceedfde3a49d2ae7e20f919))
* 🐛 修复IndexBar组件更新数据时显示异常的问题 ([f4c751d](https://github.com/Moonofweisheng/wot-design-uni/commit/f4c751dfae3724118c2d842489a5c7d1003996f1)), closes [#545](https://github.com/Moonofweisheng/wot-design-uni/issues/545)
* 🐛 修复Input和Textarea设置为readonly时在部分iOS手机可以点击聚焦的问题 ([ff59403](https://github.com/Moonofweisheng/wot-design-uni/commit/ff594031546a25f4b2831749312171d260a76044)), closes [#533](https://github.com/Moonofweisheng/wot-design-uni/issues/533)
* 🐛 修复Picker多级联动未应用picker选择值时取消后打开展示列数据错误的问题 ([90e86de](https://github.com/Moonofweisheng/wot-design-uni/commit/90e86def95ae458208f8aa50427b845db61d05b4)), closes [#562](https://github.com/Moonofweisheng/wot-design-uni/issues/562)
### ✏️ Documentation | 文档
* ✏️ 调整数字滚动组件文档路径 ([636a2c5](https://github.com/Moonofweisheng/wot-design-uni/commit/636a2c5e8a8906166947312f085e5fabba5c47df))
* ✏️ 更正form demo 方法名不一致 ([#534](https://github.com/Moonofweisheng/wot-design-uni/issues/534)) ([59fb1ea](https://github.com/Moonofweisheng/wot-design-uni/commit/59fb1eaabd7fea5428dc860af5ad734c9eebb496))
* ✏️ 优化MessageBox示例demo ([a827b79](https://github.com/Moonofweisheng/wot-design-uni/commit/a827b79498a48272eb71fd9c0e70a9dae889375b))
* ✏️ 增加安卓演示demo下载二维码 ([8680e77](https://github.com/Moonofweisheng/wot-design-uni/commit/8680e776e229d96b995de402e12ab423930a27ba))
* ✏️ 更正text组件doc的type属性默认值 ([#557](https://github.com/Moonofweisheng/wot-design-uni/issues/557)) ([3e51f76](https://github.com/Moonofweisheng/wot-design-uni/commit/3e51f763cf394cd5214bc5c0c3e6e23c9ee974b7))
### ✨ Features | 新功能
* ✨ config-provider 支持customClass 与 customeStyle ([#535](https://github.com/Moonofweisheng/wot-design-uni/issues/535)) ([febe730](https://github.com/Moonofweisheng/wot-design-uni/commit/febe73079eceeb2cf0eec9fc5712321fa3434bd2))
* ✨ Form设置提示模式为toast时优先显示顺序靠前的表单项的错误提示 ([f25409f](https://github.com/Moonofweisheng/wot-design-uni/commit/f25409f5a83df50ecbbf0a21bb2d5199021b9cc1)), closes [#548](https://github.com/Moonofweisheng/wot-design-uni/issues/548)
* ✨ img 图片组件click事件增加mouseEvent参数 ([#539](https://github.com/Moonofweisheng/wot-design-uni/issues/539)) ([4983f48](https://github.com/Moonofweisheng/wot-design-uni/commit/4983f4832a194d399aeb919b8d2c02564789d9ab))
* ✨ Text支持传入number类型的text ([e1f9ff6](https://github.com/Moonofweisheng/wot-design-uni/commit/e1f9ff60e35c7b6bbb4b5e7b84b2d570471056f6)), closes [#553](https://github.com/Moonofweisheng/wot-design-uni/issues/553)
### [1.3.8](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.3.7...v1.3.8) (2024-08-18)
### ✏️ Documentation | 文档
* ✏️ 补充Form设置error-type的示例 ([0e6ea3e](https://github.com/Moonofweisheng/wot-design-uni/commit/0e6ea3ead02c7b51fac7c5776c92044abeaa4dc3))
* ✏️ 修复常见问题中useToast入参错误的问题 ([3cd0905](https://github.com/Moonofweisheng/wot-design-uni/commit/3cd0905bab2b0dfc3d05257e01aa16afe61c0002))
* ✏️ 修复textarea组件的maxlength属性类型标注错误 ([#502](https://github.com/Moonofweisheng/wot-design-uni/issues/502)) ([3698e30](https://github.com/Moonofweisheng/wot-design-uni/commit/3698e30301c6c482135671b0a3f150388421ffae))
* ✏️ 优化MessageBox和Toast文档中selector的介绍 ([f092838](https://github.com/Moonofweisheng/wot-design-uni/commit/f092838756144677c97155dfb700b1ae2cf56f47))
* ✏️ Toast 文档增加唯一标识selector的介绍 ([#494](https://github.com/Moonofweisheng/wot-design-uni/issues/494)) ([3f99e1b](https://github.com/Moonofweisheng/wot-design-uni/commit/3f99e1bfc7e78c0359e593a2862d1d885c914858))
### ✨ Features | 新功能
* ✨ 调整Statistic为CountTo组件并使用useCountDown重构 ([a01baaf](https://github.com/Moonofweisheng/wot-design-uni/commit/a01baafe327e4feeba0de9735901dfc32e014f6a))
* ✨ 新增statistic 数值显示 ([#489](https://github.com/Moonofweisheng/wot-design-uni/issues/489)) ([592c37b](https://github.com/Moonofweisheng/wot-design-uni/commit/592c37b15e54049faefd14cb480451895bb34d90))
* ✨ Collapse 折叠面板组件支持嵌套使用 ([#521](https://github.com/Moonofweisheng/wot-design-uni/issues/521)) ([a5ce5dd](https://github.com/Moonofweisheng/wot-design-uni/commit/a5ce5dd8825e520f8e676a9f400efda1eb27546a)), closes [#503](https://github.com/Moonofweisheng/wot-design-uni/issues/503)
* ✨ datetime-picker 增加自定义 Cell 样式属性 ([#491](https://github.com/Moonofweisheng/wot-design-uni/issues/491)) ([2cc7d7f](https://github.com/Moonofweisheng/wot-design-uni/commit/2cc7d7fb106ec0a13104bf8bea964ba375bd7ad5))
* ✨ form表单新增errorType错误提示类型 ([#487](https://github.com/Moonofweisheng/wot-design-uni/issues/487)) ([5915922](https://github.com/Moonofweisheng/wot-design-uni/commit/5915922b0b4970424e2dc97ef7f922a918fedfce))
* ✨Upload 组件支持手动上传并增加自定义上传函数 ([3def17e](https://github.com/Moonofweisheng/wot-design-uni/commit/3def17eb16b1355ee0a9a950788ef6299b0179a3)), closes [#481](https://github.com/Moonofweisheng/wot-design-uni/issues/481)
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复checkbox-group的shape无法作用到子组件的问题 ([cd96d25](https://github.com/Moonofweisheng/wot-design-uni/commit/cd96d258f618d4a93584307b4100eee448a58884)), closes [#519](https://github.com/Moonofweisheng/wot-design-uni/issues/519)
* 🐛 修复DropDown传入正确direction出现错误警告的问题 ([#499](https://github.com/Moonofweisheng/wot-design-uni/issues/499)) ([35507a1](https://github.com/Moonofweisheng/wot-design-uni/commit/35507a1b24dbdee27eefb960ffa637e842b04f9c))
* 🐛 修复picker-view动态设置columns时获取选中值异常的问题 ([#518](https://github.com/Moonofweisheng/wot-design-uni/issues/518)) ([8530440](https://github.com/Moonofweisheng/wot-design-uni/commit/8530440e81cb8244d7e6288a2c7a8fda41bc7a11)), closes [#492](https://github.com/Moonofweisheng/wot-design-uni/issues/492)
* 🐛 修复Textarea组件暗黑模式下清空按钮样式不正确的问题 ([8e83a11](https://github.com/Moonofweisheng/wot-design-uni/commit/8e83a117f2acf8b17b021ec833b43d9b2b940d9a))
### [1.3.7](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.3.6...v1.3.7) (2024-08-06)
### ✏️ Documentation | 文档
* ✏️ 更新爱发电地址和示例demo二维码 ([0ecc4c1](https://github.com/Moonofweisheng/wot-design-uni/commit/0ecc4c194d753a11dfa461d74df1a00d75be0e4e))
* ✏️ 更新README ([0c33dd4](https://github.com/Moonofweisheng/wot-design-uni/commit/0c33dd48ad8528b4b080125272375bae9fedf352))
* ✏️ 允许文档组件列表折叠收起 ([#468](https://github.com/Moonofweisheng/wot-design-uni/issues/468)) ([b0e4d23](https://github.com/Moonofweisheng/wot-design-uni/commit/b0e4d235b27a729024951a7b31950e83bd43d3de))
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复addUnit工具方法为string类型的参数时未添加单位导致swiper高度丢失的问题 ([3d7775c](https://github.com/Moonofweisheng/wot-design-uni/commit/3d7775c5a93668cb7ac6b50563869d13bbd39bfa))
* 🐛 修复Input设置为number类型时绑定值重设为0时显示异常的问题 ([df6a6a0](https://github.com/Moonofweisheng/wot-design-uni/commit/df6a6a0ab1f911296002e39299a93bbee5546715)), closes [#470](https://github.com/Moonofweisheng/wot-design-uni/issues/470)
* 🐛 修复LockScroll后切换页面无法滚动 ([#478](https://github.com/Moonofweisheng/wot-design-uni/issues/478)) ([197d61a](https://github.com/Moonofweisheng/wot-design-uni/commit/197d61a678738bda608588d660263e0d5657f940)), closes [#473](https://github.com/Moonofweisheng/wot-design-uni/issues/473)
* 🐛 修复Textarea的placeholder无法设置空字符串问题 ([#472](https://github.com/Moonofweisheng/wot-design-uni/issues/472)) ([bb3d329](https://github.com/Moonofweisheng/wot-design-uni/commit/bb3d3292af56016ad21d7bf49024a0338d93ec3d)), closes [#471](https://github.com/Moonofweisheng/wot-design-uni/issues/471)
* **type:** 🐛 修复vue>=2.7版本的GlobalComponents类型声明问题 ([#464](https://github.com/Moonofweisheng/wot-design-uni/issues/464)) ([a175f05](https://github.com/Moonofweisheng/wot-design-uni/commit/a175f05e01eff86678dd08bd226bd401192b0c0b))
### ✨ Features | 新功能
* ✨ 修复Text组件设置color属性后lines失效的问题 ([84826f8](https://github.com/Moonofweisheng/wot-design-uni/commit/84826f8057ba29f65b26ee8f292073edb2f441f0)), closes [#477](https://github.com/Moonofweisheng/wot-design-uni/issues/477)
* ✨ Input 组件新增clear-triger属性 ([#476](https://github.com/Moonofweisheng/wot-design-uni/issues/476)) ([364cfbf](https://github.com/Moonofweisheng/wot-design-uni/commit/364cfbf1af7a9109be9af59b543b4ccef9c32916)), closes [#462](https://github.com/Moonofweisheng/wot-design-uni/issues/462)
* ✨ Swiper 轮播组件增加value-key用于自定义目标字段属性名 ([#485](https://github.com/Moonofweisheng/wot-design-uni/issues/485)) ([f207876](https://github.com/Moonofweisheng/wot-design-uni/commit/f20787690368e341850c2fd51cf725b26b192ec9)), closes [#410](https://github.com/Moonofweisheng/wot-design-uni/issues/410)
* ✨ Textarea 组件新增clear-triger属性 ([1c13f2e](https://github.com/Moonofweisheng/wot-design-uni/commit/1c13f2e629fc259e282d7d859097f8905ef1053e)), closes [#462](https://github.com/Moonofweisheng/wot-design-uni/issues/462)
* 组件text新增金额类型,前后插槽,下划线等功能 ([#452](https://github.com/Moonofweisheng/wot-design-uni/issues/452)) ([95735be](https://github.com/Moonofweisheng/wot-design-uni/commit/95735be75e276b8679a5a76c9cbe49ea29a9b18d))
* **drop-menu:** 支持自定义图标以及before-toggle ([#479](https://github.com/Moonofweisheng/wot-design-uni/issues/479)) ([108e1b3](https://github.com/Moonofweisheng/wot-design-uni/commit/108e1b36c69cdb28b59f8742d82bb78540a0e043))
### [1.3.6](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.3.5...v1.3.6) (2024-07-26)
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复Button为disabled状态时仍能触发open-type指定事件的问题 ([a64a570](https://github.com/Moonofweisheng/wot-design-uni/commit/a64a5707d2573c042cd9bb16d6f7fecba9a38291)), closes [#458](https://github.com/Moonofweisheng/wot-design-uni/issues/458)
* 🐛 修复MessageBox设置为prompt时输入框绑定值异常的问题 ([140d960](https://github.com/Moonofweisheng/wot-design-uni/commit/140d96019d91a51f2af2efbd91a279d203a8408b))
### ✏️ Documentation | 文档
* ✏️ 文档地址更新并增加QQ2群二维码 ([ef1ad01](https://github.com/Moonofweisheng/wot-design-uni/commit/ef1ad011f205612d6d2a8f5fc8cbf7d05dfffc7d))
* ✏️ 修复Toast组件文档中关于提示方法描述的错误 ([8ed19a2](https://github.com/Moonofweisheng/wot-design-uni/commit/8ed19a2949064ec93cc281aadae4710d4d24a25f))
* ✏️ 修正DateTimePicker文档中关于minDate和maxDate类型标注错误的问题 ([b322264](https://github.com/Moonofweisheng/wot-design-uni/commit/b322264c9a84d9acb82276ecacf5f12f1fd25f6e))
### [1.3.5](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.3.4...v1.3.5) (2024-07-20)
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复Text组件使用日期工具方法路径错误的问题 ([c4071c3](https://github.com/Moonofweisheng/wot-design-uni/commit/c4071c3759d8328f5dd6a6a374bb91dda5af1029)), closes [#453](https://github.com/Moonofweisheng/wot-design-uni/issues/453)
### ✏️ Documentation | 文档
* ✏️ 文档中全局引入ElTag用于显示组件上线版本 ([1d05654](https://github.com/Moonofweisheng/wot-design-uni/commit/1d056547c89f4b6f39e9f2b503d55790abc02b52))
* ✏️ 修复RadioBox文档中关于表单模式表述错误的问题 ([1da6c34](https://github.com/Moonofweisheng/wot-design-uni/commit/1da6c34565d20c7fdb0970cfc93dada208b1f82e))
* ✏️ 优化Segmented分段器关于绑定激活项的文档 ([5caf3b9](https://github.com/Moonofweisheng/wot-design-uni/commit/5caf3b95073c9bf28f280cbe88431a40f937e994))
### [1.3.4](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.3.3...v1.3.4) (2024-07-19)
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复双向滑块响应式丢失 ([#436](https://github.com/Moonofweisheng/wot-design-uni/issues/436)) ([825ea9b](https://github.com/Moonofweisheng/wot-design-uni/commit/825ea9b5b81981ae2a8cb497b412bf950caf6aaf))
* 🐛 修复Input组件[@input](https://github.com/input)事件参数错误的问题 ([82357f9](https://github.com/Moonofweisheng/wot-design-uni/commit/82357f916def6283003aef64ef522a5bb155c307))
* 🐛 修复Table组件异步填充数据源无效的问题 ([c795c00](https://github.com/Moonofweisheng/wot-design-uni/commit/c795c00560a267de41d8ef3f976fe16c6ad8ba00)), closes [#445](https://github.com/Moonofweisheng/wot-design-uni/issues/445)
* 🐛 修复Upload组件accept为media时图片预览顺序混乱的问题 ([f8c1053](https://github.com/Moonofweisheng/wot-design-uni/commit/f8c1053abd2b0ce3f3bee89fbd0e9adcdf1961d2)), closes [#442](https://github.com/Moonofweisheng/wot-design-uni/issues/442)
* 🐛 Button按钮click事件直接透传event ([017aeda](https://github.com/Moonofweisheng/wot-design-uni/commit/017aeda89d7950024baddc40a4a1e83a36010be3)), closes [#443](https://github.com/Moonofweisheng/wot-design-uni/issues/443)
* 修复 textarea 组件同时使用 auto-height 和 no-border 属性时,no-border 属性不生效 ([#448](https://github.com/Moonofweisheng/wot-design-uni/issues/448)) ([a2f4b32](https://github.com/Moonofweisheng/wot-design-uni/commit/a2f4b322f5b9bd01a36a46b904684d531d5e6730))
### ✨ Features | 新功能
* ✨ Button按钮组件支持使用自定义组件 ([517b583](https://github.com/Moonofweisheng/wot-design-uni/commit/517b583f262e374154111d635644dfb225a473c9)), closes [#310](https://github.com/Moonofweisheng/wot-design-uni/issues/310)
* ✨ Toast 轻提示组件支持使用组件库内置和自定义图标 ([723c51b](https://github.com/Moonofweisheng/wot-design-uni/commit/723c51bac98bb751af44f13737fba12deb298dd4)), closes [#444](https://github.com/Moonofweisheng/wot-design-uni/issues/444)
* ✨ Upload上传组件新增支持successStatus属性 ([99eab74](https://github.com/Moonofweisheng/wot-design-uni/commit/99eab74260e1e3c43f9f4b147edb4a5a3147d086))
* 新增Text 文本组件 ([#403](https://github.com/Moonofweisheng/wot-design-uni/issues/403)) ([14f5f44](https://github.com/Moonofweisheng/wot-design-uni/commit/14f5f4430a7cd599149adf16f7bc704dc42f4d90))
### ✏️ Documentation | 文档
* ✏️ 调整QQ群与提问相关文档 ([cb11e98](https://github.com/Moonofweisheng/wot-design-uni/commit/cb11e9822ff714d3c1e03ad5f2b01b0a07e8fcec))
* ✏️ 移除示例demo中手机号等字样方便过审 ([7488a7f](https://github.com/Moonofweisheng/wot-design-uni/commit/7488a7f708035b5f59c60078190c880cc8d11800))
### [1.3.3](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.3.2...v1.3.3) (2024-07-14)
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复IndexBar索引值显示错误的问题 ([#433](https://github.com/Moonofweisheng/wot-design-uni/issues/433)) ([19dc35b](https://github.com/Moonofweisheng/wot-design-uni/commit/19dc35bf40eecc263ed19e9f54d05c004b1d3425)), closes [#408](https://github.com/Moonofweisheng/wot-design-uni/issues/408)
### ✏️ Documentation | 文档
* ✏️ 调整演示demo中图片到npmmirror上 ([93ff5f9](https://github.com/Moonofweisheng/wot-design-uni/commit/93ff5f938fdb1ced622080bce9168bfe0e7ed771))
* ✏️ 新增关于messageBox弹出多个的常见问题解答 ([a362928](https://github.com/Moonofweisheng/wot-design-uni/commit/a3629283aa3838803df900512afc990f920b3e0b))
* ✏️ 修复SelectPicker文档中存在的拼写错误 ([9e28b57](https://github.com/Moonofweisheng/wot-design-uni/commit/9e28b5771a30fa0bf8aad60e8e494e0bc976d9a1)), closes [#426](https://github.com/Moonofweisheng/wot-design-uni/issues/426)
* ✏️ Upload文档增加微信隐私协议的介绍 ([c7f3a4a](https://github.com/Moonofweisheng/wot-design-uni/commit/c7f3a4adc2907bab30f5e075417f34541cba7a5e))
### [1.3.2](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.3.1...v1.3.2) (2024-07-08)
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复ActionSheet样式调整导致微信编译错误的问题 ([a9189d2](https://github.com/Moonofweisheng/wot-design-uni/commit/a9189d2c263459a33cdbb68bec3dd0dd0213b5c0))
### [1.3.1](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.3.0...v1.3.1) (2024-07-08)
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复暗黑模式下Grid和ActionSheet组件部分样式异常的问题 ([a28938c](https://github.com/Moonofweisheng/wot-design-uni/commit/a28938c91d4b437e6b583793e32f8373cec102ae)), closes [#409](https://github.com/Moonofweisheng/wot-design-uni/issues/409)
## [1.3.0](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.2.28...v1.3.0) (2024-07-07)
### ✨ Features | 新功能
* ✨ Upload上传组件新增支持上传视频和文件 ([#412](https://github.com/Moonofweisheng/wot-design-uni/issues/412)) ([e07dbdd](https://github.com/Moonofweisheng/wot-design-uni/commit/e07dbdd5305c112fe3648ce988a45b2cc36ae143)), closes [#186](https://github.com/Moonofweisheng/wot-design-uni/issues/186) [#336](https://github.com/Moonofweisheng/wot-design-uni/issues/336)
* ✨select-picker组件增加open、close事件 ([#395](https://github.com/Moonofweisheng/wot-design-uni/issues/395)) ([9237a04](https://github.com/Moonofweisheng/wot-design-uni/commit/9237a04bcbde9960864b9a7b09a64fc2b6c27595))
### ✏️ Documentation | 文档
* ✏️ 调整ColPicker多列选择器文档中省市区数据源及演示demo ([d09bd03](https://github.com/Moonofweisheng/wot-design-uni/commit/d09bd037e735b02264074c2a251c59c01b8ff571))
* ✏️ DropDownItem文档增加closed和opened介绍 ([401bd28](https://github.com/Moonofweisheng/wot-design-uni/commit/401bd284ceaafe957a0f4184d0a009bed70e9377))
* ✏️ PasswordInput 修复示例代码错误的问题 ([#391](https://github.com/Moonofweisheng/wot-design-uni/issues/391)) ([519d172](https://github.com/Moonofweisheng/wot-design-uni/commit/519d17235b7c61acf2048104a495690bff0b9804))
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复Calendar等组件暗黑模式部分样式异常的问题 ([281e20f](https://github.com/Moonofweisheng/wot-design-uni/commit/281e20f2a922d98c00321d1316efc96b985c620d)), closes [#388](https://github.com/Moonofweisheng/wot-design-uni/issues/388)
* 🐛 修复IndexBar点击索引序号时未显示预期索引值的问题 ([c33991e](https://github.com/Moonofweisheng/wot-design-uni/commit/c33991ee14b8108bcd084b5d7b59f35cb79b2b35)), closes [#408](https://github.com/Moonofweisheng/wot-design-uni/issues/408)
* 🐛 修复Swiper在微信端长时间处于后台出现抖动的问题 ([#413](https://github.com/Moonofweisheng/wot-design-uni/issues/413)) ([4741439](https://github.com/Moonofweisheng/wot-design-uni/commit/4741439277f1a2668634a4e5e3649236ed95a627)), closes [#411](https://github.com/Moonofweisheng/wot-design-uni/issues/411)
### [1.2.28](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.2.27...v1.2.28) (2024-06-24)
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复omitBy工具方法实现错误导致Tabbar等组件徽标显示异常的问题 ([1491fe4](https://github.com/Moonofweisheng/wot-design-uni/commit/1491fe44616a0db1c165e2bed29637f8c46fbc7e))
### [1.2.27](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.2.26...v1.2.27) (2024-06-21)
### ✨ Features | 新功能
* ✨ add title slot for wd-collapse-item ([#372](https://github.com/Moonofweisheng/wot-design-uni/issues/372)) ([0252bd9](https://github.com/Moonofweisheng/wot-design-uni/commit/0252bd98254f8e108e545651127a744640b39692)), closes [#356](https://github.com/Moonofweisheng/wot-design-uni/issues/356)
### ✏️ Documentation | 文档
* ✏️ 调整文档中关于类型声明文件的配置 ([0c38e98](https://github.com/Moonofweisheng/wot-design-uni/commit/0c38e986f0151b8aa2e17ab1770d1f39b178d354))
* ✏️ Input 密码输入框示例移除disabled属性 ([3026c78](https://github.com/Moonofweisheng/wot-design-uni/commit/3026c78d237217b08e2fa3cdf64260c294a61b2b))
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复ActionSheet禁用和加载状态时仍有点击效果的问题 ([c6baf45](https://github.com/Moonofweisheng/wot-design-uni/commit/c6baf452f0b626dea378148131d624589bb0c47e)), closes [#379](https://github.com/Moonofweisheng/wot-design-uni/issues/379)
* 🐛 修复Sidebar等组件css变量前缀错误的问题 ([0c31e16](https://github.com/Moonofweisheng/wot-design-uni/commit/0c31e16699e0b70b91384da0a5c0537b791e6bcf))
### [1.2.26](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.2.25...v1.2.26) (2024-06-14)
### ✨ Features | 新功能
* ✨ fab组件添加gap属性 ([#366](https://github.com/Moonofweisheng/wot-design-uni/issues/366)) ([7b44765](https://github.com/Moonofweisheng/wot-design-uni/commit/7b44765adc08fd16e055fbd326698a8f6b708426))
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复Fab初始化时存在初始位置闪现的问题 ([74c90be](https://github.com/Moonofweisheng/wot-design-uni/commit/74c90beb402e519fee1057870b0631673945cb73))
* 🐛 修复Transition被打断时出现显示异常的问题 ([#368](https://github.com/Moonofweisheng/wot-design-uni/issues/368)) ([9c21b95](https://github.com/Moonofweisheng/wot-design-uni/commit/9c21b9512076cc95098a36ee7a7283f70386c94b))
### [1.2.25](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.2.24...v1.2.25) (2024-06-09)
### ✨ Features | 新功能
* ✨ Pickerview选择器新增immediate-change属性,目前微信和支付宝小程序支持。 ([3428ae1](https://github.com/Moonofweisheng/wot-design-uni/commit/3428ae17889a36552010e3f7cc4a9bebb7a94461))
* ✨ Slider暴露initSlider方法用于外部初始化slider宽度信息 ([fc3e4ef](https://github.com/Moonofweisheng/wot-design-uni/commit/fc3e4ef3bb108e6bb6a660ffead40f4658c119e7)), closes [#344](https://github.com/Moonofweisheng/wot-design-uni/issues/344)
### ✏️ Documentation | 文档
* ✏️ 常见问题中增加关于交流群的内容 ([9ddaeec](https://github.com/Moonofweisheng/wot-design-uni/commit/9ddaeec32299463406ae2f60406cf39daff575cf))
* ✏️ 更新文档中组件数量 ([10d2ba9](https://github.com/Moonofweisheng/wot-design-uni/commit/10d2ba9035970c5627fc731219ec529e634d2578))
* ✏️ 增加关于微信小程序v-if和slot执行顺序异常问题的介绍 ([6a14879](https://github.com/Moonofweisheng/wot-design-uni/commit/6a1487900b214d071fdbda52034f220b8b046eec))
* ✏️ 修正upload组件文档中change事件的dmeo错误 ([#360](https://github.com/Moonofweisheng/wot-design-uni/issues/360)) ([61004d3](https://github.com/Moonofweisheng/wot-design-uni/commit/61004d30ed3e79b439ef8a3c5d2e78723d7fa017))
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复时间选择器设置minDate之后选择器显示值和实际选择值不一致的问题 ([3c0284f](https://github.com/Moonofweisheng/wot-design-uni/commit/3c0284f1f27b743ea3bdb7eeac5c489939057e13)), closes [#339](https://github.com/Moonofweisheng/wot-design-uni/issues/339)
* 🐛 修复ImgCropper未暴露resetImg和setRoate方法的问题 ([e58f111](https://github.com/Moonofweisheng/wot-design-uni/commit/e58f1111f2ae8e2da23e60c0ed60130373117970)), closes [#354](https://github.com/Moonofweisheng/wot-design-uni/issues/354)
* 🐛 修复Tag在钉钉小程序平台close方法不执行的问题 ([242d2f2](https://github.com/Moonofweisheng/wot-design-uni/commit/242d2f25c6ac829b5d20d63d520b1f8c8ae921a8)), closes [#359](https://github.com/Moonofweisheng/wot-design-uni/issues/359)
### [1.2.24](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.2.23...v1.2.24) (2024-06-03)
@@ -0,0 +1,28 @@
export class AbortablePromise<T> {
promise: Promise<T>
private _reject: ((res?: any) => void) | null = null
constructor(executor: (resolve: (value: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void) {
this.promise = new Promise<T>((resolve, reject) => {
executor(resolve, reject)
this._reject = reject // 保存reject方法的引用,以便在abort时调用
})
}
// 提供abort方法来中止Promise
abort(error?: any) {
if (this._reject) {
this._reject(error) // 调用reject方法来中止Promise
}
}
then<TResult1 = T, TResult2 = never>(
onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null,
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null
): Promise<TResult1 | TResult2> {
return this.promise.then(onfulfilled, onrejected)
}
catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<T | TResult> {
return this.promise.catch(onrejected)
}
}
@@ -8,7 +8,7 @@
* BEM,定义块(b)
*/
@mixin b($block) {
$B: $namespace + "-" + $block !global;
$B: $namespace + "-"+ $block !global;
.#{$B} {
@content;
@@ -24,6 +24,7 @@
@each $item in $element {
$selectors: #{$selectors + "." + $B + $elementSeparator + $item + ","};
}
@at-root {
#{$selector} {
#{$selectors} {
@@ -31,10 +32,13 @@
}
}
}
} @else {
}
@else {
@each $item in $element {
$selectors: #{$selectors + $selector + $elementSeparator + $item + ","};
}
@at-root {
#{$selectors} {
@content;
@@ -44,17 +48,7 @@
}
/* 此方法用于生成穿透样式 */
/**
* BEM,定义块(b)
*/
@mixin bdeep($block) {
$B: $namespace + "-" + $block !global;
.#{$B}{
@content;
}
}
/* 此方法用于生成穿透样式 */
/* 定义元素(e),对于伪类,会自动将 e 嵌套在 伪类 底下 */
@@ -66,20 +60,28 @@
@each $item in $element {
$selectors: #{$selectors + "." + $B + $elementSeparator + $item + ","};
}
@at-root {
#{$selector} {
:deep(#{$selectors}) {
@content;
:deep() {
#{$selectors} {
@content;
}
}
}
}
} @else {
}
@else {
@each $item in $element {
$selectors: #{$selectors + $selector + $elementSeparator + $item + ","};
}
@at-root {
:deep(#{$selectors}) {
@content;
:deep() {
#{$selectors} {
@content;
}
}
}
}
@@ -89,6 +91,7 @@
/* 定义状态(m */
@mixin m($modifier...) {
$selectors: "";
@each $item in $modifier {
$selectors: #{$selectors + & + $modifierSeparator + $item + ","};
}
@@ -99,6 +102,24 @@
}
}
}
/* 定义状态(m */
@mixin mdeep($modifier...) {
$selectors: "";
@each $item in $modifier {
$selectors: #{$selectors + & + $modifierSeparator + $item + ","};
}
@at-root {
:deep() {
#{$selectors} {
@content;
}
}
}
}
/* 对于需要需要嵌套在 m 底下的 e,调用这个混合宏,一般在切换整个组件的状态,如切换颜色的时候 */
@mixin me($element...) {
$selector: &;
@@ -108,6 +129,7 @@
@each $item in $element {
$selectors: #{$selectors + "." + $B + $elementSeparator + $item + ","};
}
@at-root {
#{$selector} {
#{$selectors} {
@@ -115,10 +137,13 @@
}
}
}
} @else {
}
@else {
@each $item in $element {
$selectors: #{$selectors + $selector + $elementSeparator + $item + ","};
}
@at-root {
#{$selectors} {
@content;
@@ -172,22 +197,31 @@
/* 0.5px 边框 指定方向*/
@mixin halfPixelBorder($direction: "bottom", $left: 0, $color: $-color-border-light) {
position: relative;
&::after {
position: absolute;
display: block;
content: "";
@if ($left == 0) {
@if ($left==0) {
width: 100%;
} @else {
}
@else {
width: calc(100% - #{$left});
}
height: 1px;
left: $left;
@if ($direction == "bottom") {
@if ($direction=="bottom") {
bottom: 0;
} @else {
}
@else {
top: 0;
}
transform: scaleY(0.5);
background: $color;
}
@@ -197,6 +231,7 @@
/* 0.5px 边框 环绕 */
@mixin halfPixelBorderSurround($color: $-color-border-light) {
position: relative;
&::after {
position: absolute;
display: block;
@@ -212,6 +247,7 @@
transform-origin: left top;
}
}
@mixin buttonClear {
outline: none;
-webkit-appearance: none;
@@ -238,6 +274,7 @@
transform: translateX(-50%);
bottom: calc(-1 * $size)
}
@include e(arrow-up) {
border-left: $size solid transparent;
border-right: $size solid transparent;
@@ -245,6 +282,7 @@
transform: translateX(-50%);
top: calc(-1 * $size)
}
@include e(arrow-left) {
border-top: $size solid transparent;
border-bottom: $size solid transparent;
@@ -252,6 +290,7 @@
transform: translateY(-50%);
left: calc(-1 * $size)
}
@include e(arrow-right) {
border-top: $size solid transparent;
border-bottom: $size solid transparent;
@@ -292,9 +331,11 @@
box-shadow: $box-shadow;
}
}
@include e(arrow-up) {
transform: translateX(-50%);
top: 0;
&:after {
content: "";
width: $size;
@@ -307,9 +348,11 @@
box-shadow: $box-shadow;
}
}
@include e(arrow-left) {
transform: translateY(-50%);
left: 0;
&:after {
content: "";
width: $size;
@@ -322,6 +365,7 @@
box-shadow: $box-shadow;
}
}
@include e(arrow-right) {
transform: translateY(-50%);
right: 0;
@@ -338,4 +382,4 @@
box-shadow: $box-shadow;
}
}
}
}
@@ -37,8 +37,6 @@ $-font-white-2: var(--wot-font-white-2, rgba(255, 255, 255, 0.55));
$-font-white-3: var(--wot-font-white-3, rgba(255, 255, 255, 0.35));
$-font-white-4: var(--wot-font-white-4, rgba(255, 255, 255, 0.22));
/* 文字颜色(默认浅色背景下 */
$-color-title: var(--wot-color-title, $-color-black) !default; // 模块标题/重要正文 000
$-color-content: var(--wot-color-content, #262626) !default; // 普通正文 262626
@@ -68,7 +66,6 @@ $-color-icon: var(--wot-color-icon, #d9d9d9) !default; // icon颜色
$-color-icon-active: var(--wot-color-icon-active, #eee) !default; // icon颜色hover
$-color-icon-disabled: var(--wot-color-icon-disabled, #a7a7a7) !default; // icon颜色disabled
/*----------------------------------------- Theme color. end -------------------------------------------*/
/*-------------------------------- Theme color application size. start --------------------------------*/
@@ -90,9 +87,12 @@ $-size-side-padding: var(--wot-size-side-padding, 15px) !default; // 屏幕两
/*-------------------------------- Theme color application size. end --------------------------------*/
/* component var */
/* action-sheet */
$-action-sheet-weight: var(--wot-action-sheet-weight, 500) !default; // 面板字重
$-action-sheet-radius: var(--wot-action-sheet-radius, 16px) !default; // 面板圆角大小
$-action-sheet-loading-size: var(--wot-action-sheet-loading-size, 20px) !default; // loading动画尺寸
$-action-sheet-action-height: var(--wot-action-sheet-action-height, 48px) !default; // 单条菜单高度
$-action-sheet-color: var(--wot-action-sheet-color, rgba(0, 0, 0, 0.85)) !default; // 选项名称颜色
$-action-sheet-fs: var(--wot-action-sheet-fs, $-fs-title) !default; // 选项名称字号
@@ -131,61 +131,44 @@ $-badge-border: var(--wot-badge-border, 2px solid $-badge-color) !default; //
/* button */
$-button-disabled-opacity: var(--wot-button-disabled-opacity, 0.6) !default; // button禁用透明度
$-button-small-height: var(--wot-button-small-height, 28px) !default; // 小型按钮高度
$-button-small-padding: var(--wot-button-small-padding, 0 12px) !default; // 小型按钮padding
$-button-small-fs: var(--wot-button-small-fs, $-fs-secondary) !default; // 小型按钮字号
$-button-small-radius: var(--wot-button-small-radius, 2px) !default; // 小型按钮圆角大小
$-button-small-loading: var(--wot-button-small-loading, 14px) !default; // 小型按钮loading图标大小
$-button-medium-height: var(--wot-button-medium-height, 36px) !default; // 中型按钮高度
$-button-medium-padding: var(--wot-button-medium-padding, 0 16px) !default; // 中型按钮padding
$-button-medium-fs: var(--wot-button-medium-fs, $-fs-content) !default; // 中型按钮字号
$-button-medium-radius: var(--wot-button-medium-radius, 4px) !default; // 中型按钮圆角大小
$-button-medium-loading: var(--wot-button-medium-loading, 18px) !default; // 中型按钮loading图标大小
$-button-medium-box-shadow-size: var(--wot-button-medium-box-shadow-size, 0px 2px 4px 0px) !default; // 中尺寸阴影尺寸
$-button-large-height: var(--wot-button-large-height, 44px) !default; // 大型按钮高度
$-button-large-padding: var(--wot-button-large-padding, 0 36px) !default; // 大型按钮padding
$-button-large-fs: var(--wot-button-large-fs, $-fs-title) !default; // 大型按钮字号
$-button-large-radius: var(--wot-button-large-radius, 8px) !default; // 大型按钮圆角大小
$-button-large-loading: var(--wot-button-large-loading, 24px) !default; // 大小按钮loading图标大小
$-button-large-box-shadow-size: var(--wot-button-large-box-shadow-size, 0px 4px 8px 0px) !default; // 大尺寸阴影尺寸
$-button-icon-fs: var(--wot-button-icon-fs, 1.18em) !default; // 带图标的按钮的图标大小
$-button-icon-size: var(--wot-button-icon-size, 40px) !default; // icon 类型按钮尺寸
$-button-icon-color: var(--wot-button-icon-color, rgba(0, 0, 0, 0.65)) !default; // icon 类型按钮颜色
$-button-icon-disabled-color: var(--wot-button-icon-disabled-color, $-color-icon-disabled) !default; // icon 类型按钮禁用颜色
$-button-normal-color: var(--wot-button-normal-color, $-color-title) !default; // 文字颜色
$-button-normal-disabled-color: var(--wot-button-normal-disabled-color, rgba(0, 0, 0, 0.25)) !default; // 默认按钮禁用文字色
$-button-plain-bg-color: var(--wot-button-plain-bg-color, $-color-white) !default; // 幽灵按钮背景色
$-button-primary-color: var(--wot-button-primary-color, $-color-white) !default; // 主要按钮颜色
$-button-primary-bg-color: var(--wot-button-primary-bg-color, $-color-theme) !default; // 主要按钮背景颜色
$-button-primary-box-shadow-color: var(--wot-button-primary-box-shadow-color, rgba($-color-theme, 0.25)) !default; // 主要按钮阴影颜色
$-button-success-color: var(--wot-button-success-color, $-color-white) !default; // 成功按钮文字颜色
$-button-success-bg-color: var(--wot-button-success-bg-color, $-color-success) !default; // 成功按钮颜色
$-button-success-box-shadow-color: var(--wot-button-success-box-shadow-color, rgba($-color-success, 0.25)) !default; // 主要按钮阴影颜色
$-button-info-color: var(--wot-button-info-color, $-color-title) !default; // 信息按钮颜色
$-button-info-bg-color: var(--wot-button-info-bg-color, #F0F0F0) !default; // 信息按钮背景颜色
$-button-info-bg-color: var(--wot-button-info-bg-color, #f0f0f0) !default; // 信息按钮背景颜色
$-button-info-plain-border-color: var(--wot-button-info-plain-border-color, rgba(0, 0, 0, 0.45)) !default; // 信息按钮禁用颜色
$-button-info-plain-normal-color: var(--wot-button-info-plain-normal-color, rgba(0, 0, 0, 0.85)) !default; // 信息幽灵按钮默认颜色
$-button-warning-color: var(--wot-button-warning-color, $-color-white) !default; // 警告按钮字体颜色
$-button-warning-bg-color: var(--wot-button-warning-bg-color, $-color-warning) !default; // 警告按钮背景颜色
$-button-warning-box-shadow-color: var(--wot-button-warning-box-shadow-color, rgba($-color-warning, 0.25)) !default; // 主要按钮阴影颜色
$-button-error-color: var(--wot-button-error-color, $-color-white) !default; // 错误按钮颜色
$-button-error-bg-color: var(--wot-button-error-bg-color, $-color-danger) !default; // 错误按钮背景颜色
$-button-error-box-shadow-color: var(--wot-button-error-box-shadow-color, rgba($-color-danger, 0.25)) !default; // 主要按钮阴影颜色
$-button-text-hover-opacity: var(--wot-button-text-hover-opacity, 0.7) !default; // 文字button激活时透明度
/* cell */
$-cell-padding: var(--wot-cell-padding, $-size-side-padding) !default; // cell 左右padding距离
$-cell-line-height: var(--wot-cell-line-height, 24px) !default; // 行高
@@ -210,6 +193,7 @@ $-cell-value-fs: var(--wot-cell-value-fs, 14px) !default; // 右侧内容字号
$-cell-value-color: var(--wot-cell-value-color, rgba(0, 0, 0, 0.85)) !default; // 右侧内容文字颜色
$-cell-arrow-size: var(--wot-cell-arrow-size, 18px) !default; // 右箭头大小
$-cell-arrow-color: var(--wot-cell-arrow-color, rgba(0, 0, 0, 0.25)) !default; // 右箭头颜色
$-cell-clear-color: var(--wot-cell-clear-color, #585858) !default; // 清空按钮颜色
$-cell-tap-bg: var(--wot-cell-tap-bg, rgba(0, 0, 0, 0.06)) !default; // 点击态背景色
$-cell-title-fs-large: var(--wot-cell-title-fs-large, 16px) !default; // 大尺寸标题字号
@@ -234,10 +218,13 @@ $-calendar-day-fw: var(--wot-calendar-day-fw, 500) !default;
$-calendar-day-height: var(--wot-calendar-day-height, 64px) !default;
$-calendar-month-width: var(--wot-calendar-month-width, 50px) !default;
$-calendar-active-color: var(--wot-calendar-active-color, $-color-theme) !default;
$-calendar-selected-color: var(--wot-calendar-selected-color, $-color-white) !default;
$-calendar-disabled-color: var(--wot-calendar-disabled-color, rgba(0, 0, 0, 0.25)) !default;
$-calendar-range-color: var(--wot-calendar-range-color, rgba(#4d80f0, 0.09)) !default;
$-calendar-active-border: var(--wot-calendar-active-border, 8px) !default;
$-calendar-info-fs: var(--wot-calendar-info-fs, 10px) !default;
$-calendar-item-margin-bottom: var(--wot-calendar-item-margin-bottom, 4px) !default;
/* checkbox */
$-checkbox-margin: var(--wot-checkbox-margin, 10px) !default; // 多个复选框距离
@@ -270,7 +257,7 @@ $-checkbox-button-disabled-border: var(--wot-checkbox-button-disabled-border, rg
/* collapse */
$-collapse-side-padding: var(--wot-collapse-side-padding, $-size-side-padding) !default; // 左右间距
$-collapse-body-padding: var(--wot-collapse-body-padding, 14px 25px) !default; // body padding
$-collapse-body-padding: var(--wot-collapse-body-padding, 14px $-size-side-padding) !default; // body padding
$-collapse-header-padding: var(--wot-collapse-header-padding, 13px $-size-side-padding) !default; // 头部padding
$-collapse-title-color: var(--wot-collapse-title-color, rgba(0, 0, 0, 0.85)) !default; // 标题颜色
$-collapse-title-fs: var(--wot-collapse-title-fs, 16px) !default; // 标题字号
@@ -284,14 +271,28 @@ $-collapse-more-color: var(--wot-collapse-more-color, $-color-theme) !default; /
/* divider */
$-divider-padding: var(--wot-divider-padding, 0 $-size-side-padding) !default; // 两边间距
$-divider-margin: var(--wot-divider-margin, 16px 0) !default; // 上下间距
$-divider-color: var(--wot-divider-color, rgba(0, 0, 0, 0.45)) !default; // 字体颜色
$-divider-line-color: var(--wot-divider-line-color, rgba(0, 0, 0, 0.15)) !default; // 线条颜色
$-divider-line-color: var(--wot-divider-line-color, currentColor) !default; // 线条颜色
$-divider-line-height: var(--wot-divider-line-height, 1px) !default; // 线条高度
$-divider-fs: var(--wot-divider-fs, 14px) !default; // 字体大小
$-divider-content-left-width: var(--wot-divider-content-left-width, 10%) !default; // 左侧内容宽度
$-divider-content-left-margin: var(--wot-divider-content-left-margin, 12px) !default; // 左侧内容距离线距离
$-divider-content-right-margin: var(--wot-divider-content-right-margin, 12px) !default; // 右侧内容距离线距离
$-divider-content-right-width: var(--wot-divider-content-right-width, 10%) !default; // 右侧内容宽度
$-divider-vertical-height: var(--wot-divider-vertical-height, 16px) !default; // 垂直分割线高度
$-divider-vertical-content-margin: var(--wot-divider-vertical-content-margin, 0 8px) !default; // 垂直分割线内容间距
$-divider-vertical-line-width: var(--wot-divider-vertical-line-width, 1px) !default; // 线条高度
/* drop-menu */
$-drop-menu-height: var(--wot-drop-menu-height, 48px) !default; // 展示选中项的高度
$-drop-menu-color: var(--wot-drop-menu-color, $-color-content) !default; // 展示选中项的颜色
$-drop-menu-fs: var(--wot-drop-menu-fs, $-fs-content) !default; // 展示选中项的字号
$-drop-menu-arrow-fs: var(--wot-drop-menu-arrow-fs, $-fs-content) !default; // 箭头图标大小
$-drop-menu-side-padding: var(--wot-drop-menu-side-padding, $-size-side-padding) !default; // 两边留白间距
$-drop-menu-disabled-color: var(--wot-drop-menu-disabled-color, rgba(0, 0, 0, 0.25)) !default; // 禁用颜色
$-drop-menu-item-height: var(--wot-drop-menu-item-height, 48px) !default; // 选项高度
@@ -359,7 +360,6 @@ $-textarea-clear-color: var(--wot-textarea-clear-color, #585858) !default; //
$-textarea-count-color: var(--wot-textarea-count-color, #bfbfbf) !default; // 计数文字颜色
$-textarea-count-current-color: var(--wot-textarea-count-current-color, #262626) !default; // 当前长度颜色
$-textarea-bg: var(--wot-textarea-bg, $-color-white) !default; // 默认背景颜色
$-textarea-cell-border-color: var(--wot-textarea-cell-border-color, $-color-border-light) !default; // cell 类型边框颜色
$-textarea-cell-padding: var(--wot-textarea-cell-padding, 10px) !default; // cell 容器padding
$-textarea-cell-padding-large: var(--wot-textarea-cell-padding-large, 12px) !default; // large类型cell容器padding
@@ -374,6 +374,8 @@ $-loadmore-height: var(--wot-loadmore-height, 48px) !default; // 高度
$-loadmore-color: var(--wot-loadmore-color, rgba(0, 0, 0, 0.45)) !default; // 颜色
$-loadmore-fs: var(--wot-loadmore-fs, 14px) !default; // 字号
$-loadmore-error-color: var(--wot-loadmore-error-color, $-color-theme) !default; // 点击重试颜色
$-loadmore-refresh-fs: var(--wot-loadmore-refresh-fs, $-fs-title) !default; // refresh图标字号
$-loadmore-loading-size: var(--wot-loadmore-loading-size, $-fs-title) !default; // loading尺寸
/* message-box */
$-message-box-width: var(--wot-message-box-width, 300px) !default; // 宽度
@@ -419,6 +421,7 @@ $-pagination-nav-color: var(--wot-pagination-nav-color, rgba(0, 0, 0, 0.85)) !de
$-pagination-nav-content-fs: var(--wot-pagination-nav-content-fs, 12px) !default;
$-pagination-nav-sepatator-padding: var(--wot-pagination-nav-sepatator-padding, 0 4px) !default;
$-pagination-nav-current-color: var(--wot-pagination-nav-current-color, $-color-theme) !default;
$-pagination-icon-size: var(--wot-pagination-icon-size, $-fs-content) !default;
/* picker */
$-picker-toolbar-height: var(--wot-picker-toolbar-height, 54px) !default; // toolbar 操作条的高度
@@ -438,7 +441,8 @@ $-picker-loading-button-color: var(--wot-picker-loading-button-color, rgba(0, 0,
$-picker-column-padding: var(--wot-picker-column-padding, 0 $-size-side-padding) !default; // 选项内间距
$-picker-column-disabled-color: var(--wot-picker-column-disabled-color, rgba(0, 0, 0, 0.25)) !default; // 选择器选项禁用的颜色
$-picker-mask: var(--wot-picker-mask, linear-gradient(180deg, hsla(0, 0%, 100%, 0.9), hsla(0, 0%, 100%, 0.25)), ) linear-gradient(0deg, hsla(0, 0%, 100%, 0.9), hsla(0, 0%, 100%, 0.25)) !default; // 上下阴影
$-picker-mask: var(--wot-picker-mask, linear-gradient(180deg, hsla(0, 0%, 100%, 0.9), hsla(0, 0%, 100%, 0.25)))
linear-gradient(0deg, hsla(0, 0%, 100%, 0.9), hsla(0, 0%, 100%, 0.25)) !default; // 上下阴影
$-picker-loading-bg: var(--wot-picker-loading-bg, rgba($-color-white, 0.8)) !default; // loading 背景颜色
$-picker-region-separator-color: var(--wot-picker-region-separator-color, rgba(0, 0, 0, 0.65)) !default; // 区域选择文字颜色
$-picker-cell-arrow-size-large: var(--wot-picker-cell-arrow-size-large, $-cell-icon-size) !default; // cell 类型的大尺寸 右侧icon尺寸
@@ -456,7 +460,10 @@ $-col-picker-selected-color: var(--wot-col-picker-selected-color, rgba(0, 0, 0,
$-col-picker-selected-fw: var(--wot-col-picker-selected-fw, 700) !default; // 弹框顶部值高亮字重
$-col-picker-line-width: var(--wot-col-picker-line-width, 16px) !default; // 弹框顶部值高亮线条宽度
$-col-picker-line-height: var(--wot-col-picker-line-height, 3px) !default; // 弹框顶部值高亮线条高度
$-col-picker-line-color: var(--wot-col-picker-line-color, linear-gradient(315deg, rgba(81, 124, 240, 1), rgba(118, 158, 245, 1))) !default; // 弹框顶部值高亮线条颜色
$-col-picker-line-color: var(
--wot-col-picker-line-color,
linear-gradient(315deg, rgba(81, 124, 240, 1), rgba(118, 158, 245, 1))
) !default; // 弹框顶部值高亮线条颜色
$-col-picker-line-box-shadow: var(--wot-col-picker-line-box-shadow, 0px 1px 2px 0px rgba(1, 87, 255, 0.2)) !default; // 弹框顶部值高亮线条阴影
$-col-picker-list-height: var(--wot-col-picker-list-height, 53vh) !default; // 弹框列表高度
$-col-picker-list-padding-bottom: var(--wot-col-picker-list-padding-bottom, 30px) !default; // 弹框列表底部间距
@@ -482,9 +489,9 @@ $-progress-padding: var(--wot-progress-padding, 9px 0 8px) !default; // 进度
$-progress-bg: var(--wot-progress-bg, rgba(229, 229, 229, 1)) !default; // 进度条底色
$-progress-danger-color: var(--wot-progress-danger-color, $-color-danger) !default; // 进度条danger颜色
$-progress-success-color: var(--wot-progress-success-color, $-color-success) !default; // 进度条success进度条颜色
$-progress-color: var(--wot-progress-color, resultColor(315deg, $-color-theme, "dark""light", #517CF0 #769EF5, 0% 100%)) !default; // 进度条渐变
$-progress-linear-success-color: var(--wot-progress-linear-success-color, resultColor(315deg, $-color-theme, "dark""light", #20B080 #2BD69D, 0% 100%)) !default; // success进度条渐变色
$-progress-linear-danger-color: var(--wot-progress-linear-danger-color, resultColor(315deg, $-color-theme, "dark""light", #E04350 #FF5964, 0% 100%)) !default; // danger进度条渐变
$-progress-warning-color: var(--wot-progress-warning-color, $-color-warning) !default; // 进度条warning进度条颜
$-progress-color: var(--wot-progress-color, $-color-theme) !default; // 进度条
$-progress-height: var(--wot-progress-height, 3px) !default; // 进度条高度
$-progress-label-color: var(--wot-progress-label-color, #333) !default; // 文字颜色
$-progress-label-fs: var(--wot-progress-label-fs, 14px) !default; // 文字字号
@@ -494,7 +501,7 @@ $-progress-icon-fs: var(--wot-progress-icon-fs, 18px) !default; // 图标字号
$-radio-margin: var(--wot-radio-margin, $-checkbox-margin) !default; // 多个单选框距离
$-radio-label-margin: var(--wot-radio-label-margin, $-checkbox-label-margin) !default; // 右侧文字与左侧图标距离
$-radio-size: var(--wot-radio-size, 16px) !default; // 左侧图标尺寸
$-radio-bg: var(--wot-radio-bg, $-checkbox-bg) !default; // 左侧图标尺寸
$-radio-bg: var(--wot-radio-bg, $-color-white) !default; // 左侧图标尺寸
$-radio-label-fs: var(--wot-radio-label-fs, $-checkbox-label-fs) !default; // 右侧文字字号
$-radio-label-color: var(--wot-radio-label-color, $-checkbox-label-color) !default; // 右侧文字颜色
$-radio-checked-color: var(--wot-radio-checked-color, $-checkbox-checked-color) !default; // 选中颜色
@@ -531,6 +538,8 @@ $-search-input-padding: var(--wot-search-input-padding, 0 32px 0 42px) !default;
$-search-input-fs: var(--wot-search-input-fs, $-fs-content) !default; // 输入框字号
$-search-input-color: var(--wot-search-input-color, #262626) !default; // 输入框文字颜色
$-search-icon-color: var(--wot-search-icon-color, $-color-icon) !default; // 图标颜色
$-search-icon-size: var(--wot-search-icon-size, 18px) !default; // 图标大小
$-search-clear-icon-size: var(--wot-search-clear-icon-size, $-fs-title) !default; // 清除图标大小
$-search-placeholder-color: var(--wot-search-placeholder-color, #bfbfbf) !default; // placeholder 颜色
$-search-cancel-padding: var(--wot-search-cancel-padding, 0 $-search-side-padding 0 10px) !default; // 取消按钮间距
$-search-cancel-fs: var(--wot-search-cancel-fs, $-fs-title) !default; // 取消按钮字号
@@ -540,11 +549,14 @@ $-search-light-bg: var(--wot-search-light-bg, $-color-bg) !default; // light 类
/* slider */
$-slider-fs: var(--wot-slider-fs, $-fs-content) !default; // 字体大小
$-slider-handle-radius: var(--wot-slider-handle-radius, 12px) !default; // 滑块半径
$-slider-handle-bg: var(--wot-slider-handle-bg, resultColor(139deg, $-color-theme, "dark""light", #FFFFFF #F7F7F7, 0% 100%)) !default; // 滑块背景
$-slider-handle-bg: var(--wot-slider-handle-bg, resultColor(139deg, $-color-theme, 'dark' 'light', #ffffff #f7f7f7, 0% 100%)) !default; // 滑块背景
$-slider-axie-height: var(--wot-slider-axie-height, 3px) !default; // 滑轴高度
$-slider-color: var(--wot-slider-color, #333) !default; // 字体颜色
$-slider-axie-bg: var(--wot-slider-axie-bg, #E5E5E5) !default; // 滑轴的默认背景色
$-slider-line-color: var(--wot-slider-line-color, resultColor(315deg, $-color-theme, "dark""light", #517CF0 #769EF5, 0% 100%)) !default; // 进度条颜色
$-slider-axie-bg: var(--wot-slider-axie-bg, #e5e5e5) !default; // 滑轴的默认背景色
$-slider-line-color: var(
--wot-slider-line-color,
resultColor(315deg, $-color-theme, 'dark' 'light', #517cf0 #769ef5, 0% 100%)
) !default; // 进度条颜色
$-slider-disabled-color: var(--wot-slider-disabled-color, rgba(0, 0, 0, 0.25)) !default; // 禁用状态下字体颜色
/* sort-button */
@@ -577,10 +589,9 @@ $-switch-circle-size: var(--wot-switch-circle-size, 1em) !default; // 圆点大
$-switch-border-color: var(--wot-switch-border-color, #e5e5e5) !default; // 边框颜色选中状态背景颜色
$-switch-active-color: var(--wot-switch-active-color, $-color-theme) !default; // 选中状态背景
$-switch-active-shadow-color: var(--wot-switch-active-shadow-color, rgba(0, 83, 162, 0.5)) !default; // 选中状态shadow颜色
$-switch-inactive-color: var(--wot-switch-inactive-color, #EAEAEA) !default; // 非选中背景颜色
$-switch-inactive-color: var(--wot-switch-inactive-color, #eaeaea) !default; // 非选中背景颜色
$-switch-inactive-shadow-color: var(--wot-switch-inactive-shadow-color, rgba(155, 155, 155, 0.5)) !default; // 非选中状态shadow颜色
/* tabs */
$-tabs-nav-arrow-fs: var(--wot-tabs-nav-arrow-fs, 18px) !default; // 全部Icon字号
$-tabs-nav-arrow-open-fs: var(--wot-tabs-nav-arrow-open-fs, 14px) !default; // 展开Icon字号
@@ -592,11 +603,15 @@ $-tabs-nav-bg: var(--wot-tabs-nav-bg, $-color-white) !default; // 背景颜色
$-tabs-nav-active-color: var(--wot-tabs-nav-active-color, $-color-theme) !default; // 头部高亮颜色
$-tabs-nav-disabled-color: var(--wot-tabs-nav-disabled-color, rgba(0, 0, 0, 0.25)) !default; // 头部禁用颜色
$-tabs-nav-line-height: var(--wot-tabs-nav-line-height, 3px) !default; // 高亮边框高度
$-tabs-nav-line-width: var(--wot-tabs-nav-line-width, 19px) !default; // 高亮边框宽度
$-tabs-nav-line-bg-color: var(--wot-tabs-nav-line-bg-color, $-color-theme) !default; // 底部条颜色
$-tabs-nav-map-fs: var(--wot-tabs-nav-map-fs, $-fs-content) !default; // map 类型按钮字号
$-tabs-nav-map-color: var(--wot-tabs-nav-map-color, rgba(0, 0, 0, 0.85)) !default; // map 类型按钮文字颜色
$-tabs-nav-map-arrow-color: var(--wot-tabs-nav-map-arrow-color, rgba(0, 0, 0, 0.65)) !default; // map 类型箭头颜色
$-tabs-nav-map-btn-before-bg: var(--wot-tabs-nav-map-btn-before-bg, linear-gradient(270deg, rgba(255, 255, 255, 1) 1%, rgba(255, 255, 255, 0) 100%)) !default; // 左侧map遮罩阴影
$-tabs-nav-map-btn-before-bg: var(
--wot-tabs-nav-map-btn-before-bg,
linear-gradient(270deg, rgba(255, 255, 255, 1) 1%, rgba(255, 255, 255, 0) 100%)
) !default; // 左侧map遮罩阴影
$-tabs-nav-map-button-back-color: var(--wot-tabs-nav-map-button-back-color, rgba(0, 0, 0, 0.04)) !default; // map 类型按钮边框颜色
$-tabs-nav-map-button-radius: var(--wot-tabs-nav-map-button-radius, 16px) !default; // map 类型按钮圆角大小
$-tabs-nav-map-modal-bg: var(--wot-tabs-nav-map-modal-bg, $-overlay-bg) !default; // map 类型蒙层背景色
@@ -610,7 +625,7 @@ $-tag-primary-color: var(--wot-tag-primary-color, $-color-theme) !default; //
$-tag-danger-color: var(--wot-tag-danger-color, $-color-danger) !default; // danger 颜色
$-tag-warning-color: var(--wot-tag-warning-color, $-color-warning) !default; // warning 颜色
$-tag-success-color: var(--wot-tag-success-color, $-color-success) !default; // success 颜色
$-tag-info-bg: var(--wot-tag-info-bg, resultColor(49deg, $-color-black, "dark""light", #808080 #999999, 0% 100%)) !default; // info 背景颜色
$-tag-info-bg: var(--wot-tag-info-bg, resultColor(49deg, $-color-black, 'dark' 'light', #808080 #999999, 0% 100%)) !default; // info 背景颜色
$-tag-primary-bg: var(--wot-tag-primary-bg, $-color-theme) !default; // 主背景颜色
$-tag-danger-bg: var(--wot-tag-danger-bg, $-color-danger) !default; // danger 背景颜色
$-tag-warning-bg: var(--wot-tag-warning-bg, $-color-warning) !default; // warning 背景颜色
@@ -630,15 +645,20 @@ $-toast-radius: var(--wot-toast-radius, 8px) !default; // 圆角大小
$-toast-bg: var(--wot-toast-bg, $-overlay-bg) !default; // 背景色
$-toast-fs: var(--wot-toast-fs, $-fs-content) !default; // 字号
$-toast-with-icon-min-width: var(--wot-toast-with-icon-min-width, 150px) !default; // 有图标的情况下最小宽度
$-toast-icon-size: var(--wot-toast-icon-size, 39px) !default; // 图标大小
$-toast-icon-size: var(--wot-toast-icon-size, 32px) !default; // 图标大小
$-toast-icon-margin-right: var(--wot-toast-icon-margin-right, 12px) !default; // 图标右边距
$-toast-icon-margin-bottom: var(--wot-toast-icon-margin-bottom, 12px) !default; // 图标下边距
$-toast-loading-padding: var(--wot-toast-loading-padding, 10px) !default; // loading 下的padding
$-toast-box-shadow: var(--wot-toast-box-shadow, 0px 6px 16px 0px rgba(0, 0, 0, 0.08)) !default; // 外部阴影
/* loading */
$-loading-size: var(--wot-loading-size, 32px) !default; // loading 大小
/* tooltip */
$-tooltip-bg: var(--wot-tooltip-bg, rgba(38, 39, 40, 0.8)) !default; // 背景色
$-tooltip-color: var(--wot-tooltip-color, $-color-white) !default; // 文字颜色
$-tooltip-radius: var(--wot-tooltip-radius, 8px) !default; // 圆角大小
$-tooltip-arrow-size: var(--wot-tooltip-arrow-size, 9px) !default; // 箭头大小
$-tooltip-arrow-size: var(--wot-tooltip-arrow-size, 5px) !default; // 箭头大小
$-tooltip-fs: var(--wot-tooltip-fs, $-fs-content) !default; // 字号
$-tooltip-blur: var(--wot-tooltip-blur, 10px) !default; // 背景高斯模糊效果
$-tooltip-padding: var(--wot-tooltip-padding, 9px 20px) !default; // 间距
@@ -700,10 +720,13 @@ $-upload-evoke-disabled-color: var(--wot-upload-evoke-disabled-color, rgba(0, 0,
$-upload-close-icon-size: var(--wot-upload-close-icon-size, 16px) !default; // 移除按钮尺寸
$-upload-close-icon-color: var(--wot-upload-close-icon-color, rgba(0, 0, 0, 0.65)) !default; // 移除按钮颜色
$-upload-progress-fs: var(--wot-upload-progress-fs, 14px) !default; // 进度文字字号
$-upload-file-fs: var(--wot-upload-file-fs, 12px) !default; // 文件名字号
$-upload-file-color: var(--wot-upload-file-color, $-color-secondary) !default; // 文件名字颜色
$-upload-preview-name-fs: var(--wot-upload-preview-name-fs, 12px) !default; // 预览图片名字号
$-upload-preview-icon-size: var(--wot-upload-preview-icon-size, 24px) !default; // 预览内部图标尺寸
$-upload-preview-name-bg: var(--wot-upload-preview-name-bg, rgba(0, 0, 0, 0.6)) !default; // 预览文件名背景色
$-upload-preview-name-height: var(--wot-upload-preview-name-height, 22px) !default; // 预览文件名背景高度
$-upload-cover-icon-size: var(--wot-upload-cover-icon-size, 22px) !default; // 视频/文件图标尺寸
/* curtain */
$-curtain-content-radius: var(--wot-curtain-content-radius, 24px) !default; // 内容圆角
@@ -738,6 +761,8 @@ $-circle-text-color: var(--wot-circle-text-color, $-color-content) !default; //
/* swiper */
$-swiper-radius: var(--wot-swiper-radius, 8px);
$-swiper-item-padding: var(--wot-swiper-item-padding, 0);
$-swiper-item-text-color: var(--wot-swiper-item-text-color, #ffffff);
$-swiper-item-text-fs: var(--wot-swiper-item-text-fs, $-fs-title);
/* swiper-nav */
@@ -760,19 +785,24 @@ $-swiper-nav-btn-size: var(--wot-swiper-nav-btn-size, 48rpx) !default;
$-segmented-padding: var(--wot-segmented-padding, 4px) !default; // 分段器padding
$-segmented-item-bg-color: var(--wot-segmented-item-bg-color, #eeeeee) !default;
$-segmented-item-color: var(--wot-segmented-item-color, rgba(0, 0, 0, 0.85)) !default; // 标题文字颜色
$-segmented-item-acitve-bg: var(--wot-segmented-item-acitve-bg, #FFFFFF) !default; // 标题文字颜色
$-segmented-item-acitve-bg: var(--wot-segmented-item-acitve-bg, #ffffff) !default; // 标题文字颜色
$-segmented-item-disabled-color: var(--wot-segmented-item-disabled-color, rgba(0, 0, 0, 0.25)) !default; // 标题文字禁用颜色
/* tabbar */
$-tabbar-height: var(--wot-tabbar-height, 50px) !default;
$-tabbar-box-shadow: var(--wot-tabbar-box-shadow, 0 6px 30px 5px rgba(0, 0, 0, 0.05), 0 16px 24px 2px rgba(0, 0, 0, 0.04), 0 8px 10px -5px rgba(0, 0, 0, 0.08)) !default; // round类型tabbar阴影
$-tabbar-box-shadow: var(
--wot-tabbar-box-shadow,
0 6px 30px 5px rgba(0, 0, 0, 0.05),
0 16px 24px 2px rgba(0, 0, 0, 0.04),
0 8px 10px -5px rgba(0, 0, 0, 0.08)
) !default; // round类型tabbar阴影
/* tabbar-item */
$-tabbar-item-title-font-size: var(--wot-tabbar-item-title-font-size, 10px) !default; // tabbar选项文字大小
$-tabbar-item-title-line-height: var(--wot-tabbar-item-title-line-height, initial) !default; // tabbar选项标题文字行高
$-tabbar-inactive-color: var(--wot-tabbar-inactive-color, $-color-title) !default; // 标题文字和图标颜色
$-tabbar-active-color: var(--wot-tabbar-active-color, $-color-theme) !default; // 选中文字和图标颜色
$-tabbar-item-icon-size: var(--wot-tabbar-item-icon-size, 20px) !default; // tabbar选项图标大小
/* navbar */
$-navbar-height: var(--wot-navbar-height, 44px) !default; // navbar高度
@@ -784,17 +814,18 @@ $-navbar-desc-font-color: var(--wot-navbar-desc-font-color, $-font-gray-1) !defa
$-navbar-title-font-size: var(--wot-navbar-title-font-size, 18px); // navbar title字体大小
$-navbar-title-font-weight: var(--wot-navbar-title-font-weight, 600); // navbar title字重
$-navbar-disabled-opacity: var(--wot-navbar-disabled-opacity, 0.6) !default; // navbar左右两侧字体禁用
$-navbar-hover-color :var(--wot-navbar-hover-color, #eee) !default; // navbar hover样式
$-navbar-hover-color: var(--wot-navbar-hover-color, #eee) !default; // navbar hover样式
/* navbar-capsule */
$-navbar-capsule-border-color: var(--wot-navbar-capsule-border-color, #e7e7e7) !default;
$-navbar-capsule-border-radius: var(--wot-navbar-capsule-border-radius, 16px) !default;
$-navbar-capsule-width: var(--wot-navbar-capsule-width, 88px) !default;
$-navbar-capsule-height: var(--wot-navbar-capsule-height, 32px) !default;
$-navbar-capsule-icon-size: var(--wot-navbar-capsule-icon-size, 20px) !default; // navbar capsule图标大小
/* table */
$-table-color: var(--wot-table-color, $-font-gray-1) !default; // 表格字体颜色
$-table-bg: var(--wot-table-bg, #FFFFFF) !default; // 表格背景颜色
$-table-bg: var(--wot-table-bg, #ffffff) !default; // 表格背景颜色
$-table-stripe-bg: var(--wot-table-stripe-bg, #f3f3f3) !default; // 表格背景颜色
$-table-border-color: var(--wot-table-border-color, #ececec) !default; // 表格边框颜色
$-table-font-size: var(--wot-table-font-size, 13px) !default; // 表格字体大小
@@ -805,34 +836,53 @@ $-sidebar-width: var(--wot-sidebar-width, 104px) !default; // 侧边栏宽度
$-sidebar-height: var(--wot-sidebar-height, 100%) !default; // 侧边栏高度
/* sidebar-item */
$-sidebar-color: var(--wd-sidebar-color, $-font-gray-1) !default;
$-sidebar-item-height: var(--wd-sidebar-item-height, 56px) !default;
$-sidebar-item-line-height: var(--wd-sidebar-item-line-height, 24px) !default;
$-sidebar-disabled-color: var(--wd-side-bar-disabled-color, $-font-gray-4) !default;
$-sidebar-active-color: var(--wd-sidebar-active-color, $-color-theme) !default; // 激活项字体颜色
$-sidebar-color: var(--wot-sidebar-color, $-font-gray-1) !default;
$-sidebar-item-height: var(--wot-sidebar-item-height, 56px) !default;
$-sidebar-item-line-height: var(--wot-sidebar-item-line-height, 24px) !default;
$-sidebar-disabled-color: var(--wot-side-bar-disabled-color, $-font-gray-4) !default;
$-sidebar-active-color: var(--wot-sidebar-active-color, $-color-theme) !default; // 激活项字体颜色
$-sidebar-active-bg: var(--wot-sidebar-active-bg, $-color-white) !default; // 激活项背景颜色
$-sidebar-hover-bg: var(--wot-sidebar-hover-bg, $-color-gray-2) !default; // 激活项点击背景颜色
$-sidebar-border-radius: var(--wd-sidebar-border-radius, 8px) !default;
$-sidebar-font-size: var(--wd-sidebar-font-size, 16px) !default;
$-sidebar-icon-size: var(--wd-sidebar-icon-size, 20px) !default;
$-sidebar-active-border-width: var(--wd-sidebar-active-border-width, 4px) !default;
$-sidebar-active-border-height: var(--wd-sidebar-active-border-height, 16px) !default;
$-sidebar-border-radius: var(--wot-sidebar-border-radius, 8px) !default;
$-sidebar-font-size: var(--wot-sidebar-font-size, 16px) !default;
$-sidebar-icon-size: var(--wot-sidebar-icon-size, 20px) !default;
$-sidebar-active-border-width: var(--wot-sidebar-active-border-width, 4px) !default;
$-sidebar-active-border-height: var(--wot-sidebar-active-border-height, 16px) !default;
/* fab */
$-fab-trigger-height: var(--wd-fab-trigger-height, 56px) !default;
$-fab-trigger-width: var(--wd-fab-trigger-width, 56px) !default;
$-fab-actions-padding: var(--wd-actions-padding, 12px) !default;
$-fab-trigger-height: var(--wot-fab-trigger-height, 56px) !default;
$-fab-trigger-width: var(--wot-fab-trigger-width, 56px) !default;
$-fab-actions-padding: var(--wot-actions-padding, 12px) !default;
$-fab-icon-fs: var(--wot-fab-icon-fs, 20px) !default;
/* count-down */
$-count-down-text-color: var(--wd-count-down-text-color, $-color-gray-8) !default;
$-count-down-font-size: var(--wd-count-down-font-size, $-fs-content) !default;
$-count-down-line-height: var(--wd-count-down-line-height, 20px) !default;
$-count-down-text-color: var(--wot-count-down-text-color, $-color-gray-8) !default;
$-count-down-font-size: var(--wot-count-down-font-size, $-fs-content) !default;
$-count-down-line-height: var(--wot-count-down-line-height, 20px) !default;
/* keyboard */
$-keyboard-key-height: var(--wot-keyboard-key-height, 48px) !default;
$-keyboard-key-font-size: var(--wot-keyboard-key-font-size, 28px) !default;
$-keyboard-key-background: var(--wot-keyboard-key-background, $-color-white) !default;
$-keyboard-key-border-radius: var(--wot-keyboard-key-border-radius, 8px) !default;
$-keyboard-delete-font-size: var(--wot-keyboard-delete-font-size, 16px) !default;
$-keyboard-key-active-color: var(--wot-keyboard-key-active-color, $-color-gray-3) !default;
$-keyboard-button-text-color: var(--wot-keyboard-button-text-color, $-color-white) !default;
$-keyboard-button-background: var(--wot-keyboard--button-background, $-color-theme) !default;
$-keyboard-button-active-opacity: var(--wot-keyboard-button-active-opacity, 0.6) !default;
$-keyboard-background: var(--wot-keyboard-background, $-color-gray-2) !default;
$-keyboard-title-height: var(--wot-keyboard-title-height, 34px) !default;
$-keyboard-title-color: var(--wot-keyboard-title-color, $-color-gray-7) !default;
$-keyboard-title-font-size: var(--wot-keyboard-title-font-size, 16px) !default;
$-keyboard-close-padding: var(--wot-keyboard-title-font-size, 0 16px) !default;
$-keyboard-close-color: var(--wot-keyboard-close-color, $-color-theme) !default;
$-keyboard-close-font-size: var(--wot-keyboard-close-font-size, 14px) !default;
$-keyboard-icon-size: var(--wot-keyboard-icon-size, 22px) !default;
/* number-keyboard */
$-number-keyboard-key-height: var(--wd-number-keyboard-key-height, 48px) !default;
$-number-keyboard-key-font-size: var(--wd-number-keyboard-key-font-size, 28px) !default;
$-number-keyboard-key-background: var(--wd-number-keyboard-key-background, $-color-white) !default;
$-number-keyboard-key-height: var(--wot-number-keyboard-key-height, 48px) !default;
$-number-keyboard-key-font-size: var(--wot-number-keyboard-key-font-size, 28px) !default;
$-number-keyboard-key-background: var(--wot-number-keyboard-key-background, $-color-white) !default;
$-number-keyboard-key-border-radius: var(--wot-number-keyboard-key-border-radius, 8px) !default;
$-number-keyboard-delete-font-size: var(--wot-number-keyboard-delete-font-size, 16px) !default;
$-number-keyboard-key-active-color: var(--wot-number-keyboard-key-active-color, $-color-gray-3) !default;
@@ -846,24 +896,25 @@ $-number-keyboard-title-font-size: var(--wot-number-keyboard-title-font-size, 16
$-number-keyboard-close-padding: var(--wot-number-keyboard-title-font-size, 0 16px) !default;
$-number-keyboard-close-color: var(--wot-number-keyboard-close-color, $-color-theme) !default;
$-number-keyboard-close-font-size: var(--wot-number-keyboard-close-font-size, 14px) !default;
$-number-keyboard-icon-size: var(--wot-number-keyboard-icon-size, 22px) !default;
/* passwod-input */
$-password-input-height: var(--wd-password-input-height, 50px);
$-password-input-margin: var(--wd-password-input-margin, 16px);
$-password-input-font-size: var(--wd-password-input-margin, 20px);
$-password-input-radius: var(--wd-password-input-radius, 6px);
$-password-input-background: var(--wd-password-input-background, #fff);
$-password-input-info-color: var(--wd-password-input-info-color, $-color-info);
$-password-input-info-font-size: var(--wd-password-input-info-font-size, $-fs-content);
$-password-input-border-color: var(--wd-password-border-color, #ebedf0);
$-password-input-error-info-color: var(--wd-password-input-error-info-color, $-color-danger);
$-password-input-dot-size: var(--wd-password-input-dot-size, 10px);
$-password-input-dot-color: var(--wd-password-input-dot-color, $-color-gray-8);
$-password-input-text-color: var(--wd-password-input-text-color, $-color-gray-8);
$-password-input-cursor-color: var(--wd-password-input-cursor-color, $-color-gray-8);
$-password-input-cursor-width: var(--wd-password-input-cursor-width, 1px);
$-password-input-cursor-height: var(--wd-password-input-cursor-height, 40%);
$-password-input-cursor-duration: var(--wd-password-input-cursor-duration, 1s);
$-password-input-height: var(--wot-password-input-height, 50px);
$-password-input-margin: var(--wot-password-input-margin, 16px);
$-password-input-font-size: var(--wot-password-input-margin, 20px);
$-password-input-radius: var(--wot-password-input-radius, 6px);
$-password-input-background: var(--wot-password-input-background, #fff);
$-password-input-info-color: var(--wot-password-input-info-color, $-color-info);
$-password-input-info-font-size: var(--wot-password-input-info-font-size, $-fs-content);
$-password-input-border-color: var(--wot-password-border-color, #ebedf0);
$-password-input-error-info-color: var(--wot-password-input-error-info-color, $-color-danger);
$-password-input-dot-size: var(--wot-password-input-dot-size, 10px);
$-password-input-dot-color: var(--wot-password-input-dot-color, $-color-gray-8);
$-password-input-text-color: var(--wot-password-input-text-color, $-color-gray-8);
$-password-input-cursor-color: var(--wot-password-input-cursor-color, $-color-gray-8);
$-password-input-cursor-width: var(--wot-password-input-cursor-width, 1px);
$-password-input-cursor-height: var(--wot-password-input-cursor-height, 40%);
$-password-input-cursor-duration: var(--wot-password-input-cursor-duration, 1s);
/* form-item */
$-form-item-error-message-color: var(--wot-form-item-error-message-color, $-color-danger) !default;
@@ -872,6 +923,44 @@ $-form-item-error-message-line-height: var(--wot-form-item-error-message-line-he
/* backtop */
$-backtop-bg: var(--wot-backtop-bg, #e1e1e1) !default;
$-backtop-icon-size: var(--wot-backtop-icon-size, 20px) !default;
/* index-bar */
$-index-bar-index-font-size: var(--wot-index-bar-index-font-size, $-fs-aid) !default;
/* text */
$-text-info-color: var(--wot-text-info-color, $-color-info) !default;
$-text-primary-color: var(--wot-text-primary-color, $-color-theme) !default;
$-text-error-color: var(--wot-text-error-color, $-color-danger) !default;
$-text-warning-color: var(--wot-text-warning-color, $-color-warning) !default;
$-text-success-color: var(--wot-text-success-color, $-color-success) !default;
/* video-preview */
$-video-preview-bg: var(--wot-video-preview-bg, rgba(0, 0, 0, 0.8)) !default; // 背景色
$-video-preview-close-color: var(--wot-video-preview-close-color, #fff) !default; // 图标颜色
$-video-preview-close-font-size: var(--wot-video-preview-close-font-size, 20px) !default; // 图标大小
/* img-cropper */
$-img-cropper-icon-size: var(--wot-img-cropper-icon-size, $-fs-big) !default; // 图标大小
$-img-cropper-icon-color: var(--wot-img-cropper-icon-color, #fff) !default; // 图标颜色
/* floating-panel */
$-floating-panel-bg: var(--wot-floating-panel-bg, $-color-white) !default; // 背景色
$-floating-panel-radius: var(--wot-floating-panel-radius, 16px) !default; // 圆角
$-floating-panel-z-index: var(--wot-floating-panel-z-index, 99) !default; // 层级
$-floating-panel-header-height: var(--wot-floating-panel-header-height, 30px) !default; // 头部高度
$-floating-panel-bar-width: var(--wot-floating-panel-bar-width, 20px) !default; // bar 宽度
$-floating-panel-bar-height: var(--wot-floating-panel-bar-height, 3px) !default; // bar 高度
$-floating-panel-bar-bg: var(--wot-floating-panel-bar-bg, $-color-gray-5) !default; // bar 背景色
$-floating-panel-bar-radius: var(--wot-floating-panel-bar-radius, 4px) !default; // bar 圆角
$-floating-panel-content-bg: var(--wot-floating-panel-content-bg, $-color-white) !default; // 内容背景色
/* signature */
$-signature-bg: var(--wot-signature-bg, $-color-white) !default; // 背景色
$-signature-radius: var(--wot-signature-radius, 4px) !default; // 圆角
$-signature-border: var(--wot-signature-border, 1px solid $-color-gray-5) !default; // 边框圆角
$-signature-footer-margin-top: var(--wot-signature-footer-margin-top, 8px) !default; // 底部按钮上边距
$-signature-button-margin-left: var(--wot-signature-button-margin-left, 8px) !default; // 底部按钮左边距
@@ -0,0 +1,43 @@
import { isPromise } from './util'
function noop() {}
export type Interceptor = (...args: any[]) => Promise<boolean> | boolean | undefined | void
export function callInterceptor(
interceptor: Interceptor | undefined,
{
args = [],
done,
canceled,
error
}: {
args?: unknown[]
done: () => void
canceled?: () => void
error?: () => void
}
) {
if (interceptor) {
// eslint-disable-next-line prefer-spread
const returnVal = interceptor.apply(null, args)
if (isPromise(returnVal)) {
returnVal
.then((value) => {
if (value) {
done()
} else if (canceled) {
canceled()
}
})
.catch(error || noop)
} else if (returnVal) {
done()
} else if (canceled) {
canceled()
}
} else {
done()
}
}
@@ -1,3 +1,7 @@
import { AbortablePromise } from './AbortablePromise'
type NotUndefined<T> = T extends undefined ? never : T
/**
* uuid
* @returns string
@@ -18,7 +22,7 @@ function s4() {
* @return {string} num+px
*/
export function addUnit(num: number | string) {
return Number.isNaN(Number(num)) ? num : `${num}px`
return Number.isNaN(Number(num)) ? `${num}` : `${num}px`
}
/**
@@ -233,9 +237,10 @@ export type RectResultType<T extends boolean> = T extends true ? UniApp.NodeInfo
* @param selector #id,.class
* @param all selector
* @param scope
* @param useFields 使 fields
* @returns
*/
export function getRect<T extends boolean>(selector: string, all: T, scope?: any): Promise<RectResultType<T>> {
export function getRect<T extends boolean>(selector: string, all: T, scope?: any, useFields?: boolean): Promise<RectResultType<T>> {
return new Promise<RectResultType<T>>((resolve, reject) => {
let query: UniNamespace.SelectorQuery | null = null
if (scope) {
@@ -243,17 +248,24 @@ export function getRect<T extends boolean>(selector: string, all: T, scope?: any
} else {
query = uni.createSelectorQuery()
}
query[all ? 'selectAll' : 'select'](selector)
.boundingClientRect((rect) => {
if (all && isArray(rect) && rect.length > 0) {
resolve(rect as RectResultType<T>)
} else if (!all && rect) {
resolve(rect as RectResultType<T>)
} else {
reject(new Error('No nodes found'))
}
})
.exec()
const method = all ? 'selectAll' : 'select'
const callback = (rect: UniApp.NodeInfo | UniApp.NodeInfo[]) => {
if (all && isArray(rect) && rect.length > 0) {
resolve(rect as RectResultType<T>)
} else if (!all && rect) {
resolve(rect as RectResultType<T>)
} else {
reject(new Error('No nodes found'))
}
}
if (useFields) {
query[method](selector).fields({ size: true, node: true }, callback).exec()
} else {
query[method](selector).boundingClientRect(callback).exec()
}
})
}
@@ -303,7 +315,7 @@ export function isArray(value: any): value is Array<any> {
*/
// eslint-disable-next-line @typescript-eslint/ban-types
export function isFunction<T extends Function>(value: any): value is T {
return getType(value) === 'function'
return getType(value) === 'function' || getType(value) === 'asyncfunction'
}
/**
@@ -330,7 +342,7 @@ export function isNumber(value: any): value is number {
*/
export function isPromise(value: unknown): value is Promise<any> {
// 先将 value 断言为 object 类型
if (isObj(value)) {
if (isObj(value) && isDef(value)) {
// 然后进一步检查 value 是否具有 then 和 catch 方法,并且它们是函数类型
return isFunction((value as Promise<any>).then) && isFunction((value as Promise<any>).catch)
}
@@ -346,6 +358,14 @@ export function isBoolean(value: any): value is boolean {
return typeof value === 'boolean'
}
export function isUndefined(value: any): value is undefined {
return typeof value === 'undefined'
}
export function isNotUndefined<T>(value: T): value is NotUndefined<T> {
return !isUndefined(value)
}
/**
*
* @param value
@@ -417,7 +437,7 @@ export function objToStyle(styles: Record<string, any> | Record<string, any>[]):
}
export const requestAnimationFrame = (cb = () => {}) => {
return new Promise((resolve) => {
return new AbortablePromise((resolve) => {
const timer = setInterval(() => {
clearInterval(timer)
resolve(true)
@@ -426,6 +446,20 @@ export const requestAnimationFrame = (cb = () => {}) => {
})
}
/**
*
* @param ms
* @returns
*/
export const pause = (ms: number = 1000 / 30) => {
return new AbortablePromise((resolve) => {
const timer = setTimeout(() => {
clearTimeout(timer)
resolve(true)
}, ms)
})
}
/**
*
* @param obj
@@ -433,7 +467,7 @@ export const requestAnimationFrame = (cb = () => {}) => {
* @returns
*/
export function deepClone<T>(obj: T, cache: Map<any, any> = new Map()): T {
// 如果对象为 null 或者不是对象类型,则直接返回该对象
// 如果对象为 null 或者不是对象类型,则直接返回该对象
if (obj === null || typeof obj !== 'object') {
return obj
}
@@ -644,7 +678,70 @@ export const getPropByPath = (obj: any, path: string): any => {
*/
export const isDate = (val: unknown): val is Date => Object.prototype.toString.call(val) === '[object Date]' && !Number.isNaN((val as Date).getTime())
/**
* URL是否为视频链接
* @param url URL字符串
* @returns URL是视频链接则为truefalse
*/
export function isVideoUrl(url: string): boolean {
// 使用正则表达式匹配视频文件类型的URL
const videoRegex = /\.(mp4|mpg|mpeg|dat|asf|avi|rm|rmvb|mov|wmv|flv|mkv|video)/i
return videoRegex.test(url)
}
/**
* URL是否为图片URL
* @param url URL字符串
* @returns URL是图片格式truefalse
*/
export function isImageUrl(url: string): boolean {
// 使用正则表达式匹配图片URL
const imageRegex = /\.(jpeg|jpg|gif|png|svg|webp|jfif|bmp|dpg|image)/i
return imageRegex.test(url)
}
/**
* H5
*/
export const isH5 = process.env.UNI_PLATFORM === 'h5'
export const isH5 = (() => {
let isH5 = false
// #ifdef H5
isH5 = true
// #endif
return isH5
})()
/**
*
* @param obj
* @param predicate
* @returns
*/
export function omitBy<O extends Record<string, any>>(obj: O, predicate: (value: any, key: keyof O) => boolean): Partial<O> {
const newObj = deepClone(obj)
Object.keys(newObj).forEach((key) => predicate(newObj[key], key) && delete newObj[key]) // 遍历对象的键,删除值为不满足predicate的字段
return newObj
}
/**
*
* @param t
* @param b
* @param c
* @param d
* @returns
*/
export function easingFn(t: number = 0, b: number = 0, c: number = 0, d: number = 0): number {
return (c * (-Math.pow(2, (-10 * t) / d) + 1) * 1024) / 1023 + b
}
/**
*
*
* @param arr
* @param target
* @returns
*/
export function closest(arr: number[], target: number) {
return arr.reduce((prev, curr) => (Math.abs(curr - target) < Math.abs(prev - target) ? curr : prev))
}
@@ -1,5 +1,6 @@
import { ref, computed, onBeforeUnmount } from 'vue'
import { isDef } from '../common/util'
import { useRaf } from './useRaf'
// 定义倒计时时间的数据结构
export type CurrentTime = {
@@ -48,35 +49,20 @@ function isSameSecond(time1: number, time2: number): boolean {
return Math.floor(time1 / 1000) === Math.floor(time2 / 1000)
}
// 判断当前环境是否为 H5
const isH5 = process.env.UNI_PLATFORM === 'h5'
// 封装 requestAnimationFrame 和 setTimeout
function raf(fn: FrameRequestCallback): number {
return isH5 ? requestAnimationFrame(fn) : setTimeout(fn, 33)
}
function cancelRaf(id: number) {
if (isH5) {
cancelAnimationFrame(id)
} else {
clearTimeout(id)
}
}
// 定义 useCountDown 函数
export function useCountDown(options: UseCountDownOptions) {
let timer: number | null = null // 定时器
let endTime: number // 结束时间
let counting: boolean // 是否计时中
const { start: startRaf, cancel: cancelRaf } = useRaf(tick)
const remain = ref(options.time) // 剩余时间
const current = computed(() => parseTime(remain.value)) // 当前倒计时数据
// 暂停倒计时
const pause = () => {
counting = false
cancelRaf(timer!)
cancelRaf()
}
// 获取当前剩余时间
@@ -86,7 +72,6 @@ export function useCountDown(options: UseCountDownOptions) {
const setRemain = (value: number) => {
remain.value = value
isDef(options.onChange) && options.onChange(current.value)
if (value === 0) {
pause()
isDef(options.onFinish) && options.onFinish()
@@ -95,36 +80,30 @@ export function useCountDown(options: UseCountDownOptions) {
// 每毫秒更新一次倒计时
const microTick = () => {
timer = raf(() => {
if (counting) {
setRemain(getCurrentRemain())
if (remain.value > 0) {
microTick()
}
if (counting) {
setRemain(getCurrentRemain())
if (remain.value > 0) {
startRaf()
}
})
}
}
// 每秒更新一次倒计时
const macroTick = () => {
timer = raf(() => {
if (counting) {
const remainRemain = getCurrentRemain()
if (!isSameSecond(remainRemain, remain.value) || remainRemain === 0) {
setRemain(remainRemain)
}
if (remain.value > 0) {
macroTick()
}
if (counting) {
const remainRemain = getCurrentRemain()
if (!isSameSecond(remainRemain, remain.value) || remainRemain === 0) {
setRemain(remainRemain)
}
})
if (remain.value > 0) {
startRaf()
}
}
}
// 根据配置项选择更新方式
const tick = () => {
function tick() {
if (options.millisecond) {
microTick()
} else {
@@ -137,7 +116,7 @@ export function useCountDown(options: UseCountDownOptions) {
if (!counting) {
endTime = Date.now() + remain.value
counting = true
tick()
startRaf()
}
}
@@ -1,4 +1,4 @@
import { ref, watch } from 'vue'
import { onBeforeUnmount, onDeactivated, ref, watch } from 'vue'
function useLockScroll(shouldLock: () => boolean) {
const scrollLockCount = ref(0)
@@ -19,10 +19,17 @@ function useLockScroll(shouldLock: () => boolean) {
}
}
const destroy = () => {
shouldLock() && unlock()
}
watch(shouldLock, (value) => {
value ? lock() : unlock()
})
onDeactivated(destroy)
onBeforeUnmount(destroy)
return {
lock,
unlock
@@ -1,7 +1,7 @@
import { getCurrentInstance, ref } from 'vue'
import { getRect } from '../common/util'
import { getRect, isObj } from '../common/util'
export function usePopover() {
export function usePopover(visibleArrow = true) {
const { proxy } = getCurrentInstance() as any
const popStyle = ref<string>('')
const arrowStyle = ref<string>('')
@@ -77,10 +77,10 @@ export function usePopover() {
| 'right'
| 'right-start'
| 'right-end',
offset: number
offset: number | number[] | Record<'x' | 'y', number>
) {
// arrow size
const arrowSize = 9
const arrowSize = visibleArrow ? 9 : 0
// 上下位(纵轴)对应的距离左边的距离
const verticalX = width.value / 2
// 上下位(纵轴)对应的距离底部的距离
@@ -90,8 +90,20 @@ export function usePopover() {
// 左右位(横轴)对应的距离底部的距离
const horizontalY = height.value / 2
const offsetX = (verticalX - 17 > 0 ? 0 : verticalX - 25) + offset
const offsetY = (horizontalY - 17 > 0 ? 0 : horizontalY - 25) + offset
let offsetX = 0
let offsetY = 0
if (Array.isArray(offset)) {
offsetX = (verticalX - 17 > 0 ? 0 : verticalX - 25) + offset[0]
offsetY = (horizontalY - 17 > 0 ? 0 : horizontalY - 25) + (offset[1] ? offset[1] : offset[0])
} else if (isObj(offset)) {
offsetX = (verticalX - 17 > 0 ? 0 : verticalX - 25) + offset.x
offsetY = (horizontalY - 17 > 0 ? 0 : horizontalY - 25) + offset.y
} else {
offsetX = (verticalX - 17 > 0 ? 0 : verticalX - 25) + offset
offsetY = (horizontalY - 17 > 0 ? 0 : horizontalY - 25) + offset
}
// const offsetX = (verticalX - 17 > 0 ? 0 : verticalX - 25) + offset
// const offsetY = (horizontalY - 17 > 0 ? 0 : horizontalY - 25) + offset
const placements = new Map([
// 上
@@ -0,0 +1,37 @@
import { ref, onUnmounted } from 'vue'
import { isDef, isH5, isNumber } from '../common/util'
// 定义回调函数类型
type RafCallback = (time: number) => void
export function useRaf(callback: RafCallback) {
const requestRef = ref<number | null | ReturnType<typeof setTimeout>>(null)
// 启动动画帧
const start = () => {
const handle = (time: number) => {
callback(time)
}
if (isH5) {
requestRef.value = requestAnimationFrame(handle)
} else {
requestRef.value = setTimeout(() => handle(Date.now()), 1000 / 30)
}
}
// 取消动画帧
const cancel = () => {
if (isH5 && isNumber(requestRef.value)) {
cancelAnimationFrame(requestRef.value!)
} else if (isDef(requestRef.value)) {
clearTimeout(requestRef.value)
}
}
onUnmounted(() => {
cancel()
})
return { start, cancel }
}
@@ -1,8 +1,8 @@
/*
* @Author: weisheng
* @Date: 2024-01-25 23:06:48
* @LastEditTime: 2024-01-26 14:00:48
* @LastEditors: weisheng
* @LastEditTime: 2025-02-14 11:20:02
* @LastEditors: 810505339
* @Description:
* @FilePath: \wot-design-uni\src\uni_modules\wot-design-uni\components\composables\useTranslate.ts
*
@@ -10,9 +10,13 @@
color: $-dark-color;
background: $-dark-background2;
&:active {
&:not(.wd-action-sheet__action--disabled):not(.wd-action-sheet__action--loading):active {
background: $-dark-background4;
}
@include m(disabled) {
color: $-dark-color-gray;
}
}
@include e(subname) {
@@ -42,7 +46,7 @@
}
}
:deep(.wd-action-sheet__popup){
:deep(.wd-action-sheet__popup) {
border-radius: $-action-sheet-radius $-action-sheet-radius 0 0;
}
@@ -78,12 +82,13 @@
display: none;
}
&:active {
&:not(&--disabled):not(&--loading):active {
background: $-action-sheet-active-color;
}
@include m(disabled) {
color: $-action-sheet-disabled-color;
cursor: not-allowed;
}
@include m(loading) {
@@ -93,6 +98,11 @@
line-height: initial;
}
}
@include edeep(action-loading){
width: $-action-sheet-loading-size;
height: $-action-sheet-loading-size;
}
@include e(name) {
display: inline-block;
@@ -18,19 +18,19 @@ export type Action = {
/**
*
*/
subname: string
subname?: string
/**
*
*/
color: string
color?: string
/**
*
*/
disabled: boolean
disabled?: boolean
/**
*
*/
loading: boolean
loading?: boolean
}
export type Panel = {
@@ -38,7 +38,7 @@
:style="`color: ${action.color}`"
@click="select(rowIndex, 'action')"
>
<wd-loading v-if="action.loading" size="20px" />
<wd-loading custom-class="`wd-action-sheet__action-loading" v-if="action.loading" />
<view v-else class="wd-action-sheet__name">{{ action.name }}</view>
<view v-if="!action.loading && action.subname" class="wd-action-sheet__subname">{{ action.subname }}</view>
</button>
@@ -71,6 +71,9 @@ export default {
</script>
<script lang="ts" setup>
import wdPopup from '../wd-popup/wd-popup.vue'
import wdIcon from '../wd-icon/wd-icon.vue'
import wdLoading from '../wd-loading/wd-loading.vue'
import { watch, ref } from 'vue'
import { actionSheetProps, type Panel } from './types'
import { isArray } from '../common/util'
@@ -101,6 +104,9 @@ function computedValue() {
function select(rowIndex: number, type: 'action' | 'panels', colIndex?: number) {
if (type === 'action') {
if (props.actions[rowIndex].disabled || props.actions[rowIndex].loading) {
return
}
emit('select', {
item: props.actions[rowIndex],
index: rowIndex
@@ -117,13 +123,12 @@ function select(rowIndex: number, type: 'action' | 'panels', colIndex?: number)
colIndex
})
}
close()
if (props.closeOnClickAction) {
close()
}
}
function handleClickModal() {
emit('click-modal')
if (props.closeOnClickModal) {
close()
}
}
function handleCancel() {
emit('cancel')
@@ -11,6 +11,10 @@
align-items: center;
color: $-color-gray-8;
@include edeep(backicon) {
font-size: $-backtop-icon-size;
}
@include when(circle) {
border-radius: 50%;
}
@@ -18,4 +22,4 @@
@include when(square) {
border-radius: 4px;
}
}
}
@@ -6,7 +6,7 @@
@click="handleBacktop"
>
<slot v-if="$slots.default"></slot>
<wd-icon v-else name="backtop" size="20px" :custom-style="iconStyle" />
<wd-icon v-else custom-class="wd-backtop__backicon" name="backtop" :custom-style="iconStyle" />
</view>
</wd-transition>
</template>
@@ -23,6 +23,8 @@ export default {
</script>
<script lang="ts" setup>
import wdTransition from '../wd-transition/wd-transition.vue'
import wdIcon from '../wd-icon/wd-icon.vue'
import { computed } from 'vue'
import { backtopProps } from './types'
@@ -31,6 +31,8 @@
@include when(fixed) {
position: absolute;
top: 0px;
right: 0px;
transform: translateY(-50%) translateX(50%);
}
@@ -1,14 +1,14 @@
/*
* @Author: weisheng
* @Date: 2024-03-15 11:36:12
* @LastEditTime: 2024-03-19 16:33:12
* @LastEditTime: 2024-11-20 20:29:03
* @LastEditors: weisheng
* @Description:
* @FilePath: \wot-design-uni\src\uni_modules\wot-design-uni\components\wd-badge\types.ts
* @FilePath: /wot-design-uni/src/uni_modules/wot-design-uni/components/wd-badge/types.ts
*
*/
import type { ExtractPropTypes, PropType } from 'vue'
import { baseProps, makeBooleanProp, makeStringProp } from '../common/props'
import { baseProps, makeBooleanProp, makeStringProp, numericProp } from '../common/props'
export type BadgeType = 'primary' | 'success' | 'warning' | 'danger' | 'info'
@@ -17,10 +17,7 @@ export const badgeProps = {
/**
*
*/
modelValue: {
type: [Number, String, null] as PropType<number | string | null>,
default: null
},
modelValue: numericProp,
/** 当数值为 0 时,是否展示徽标 */
showZero: makeBooleanProp(false),
bgColor: String,
@@ -43,11 +40,11 @@ export const badgeProps = {
/**
*
*/
top: Number,
top: numericProp,
/**
*
*/
right: Number
right: numericProp
}
export type BadgeProps = ExtractPropTypes<typeof badgeProps>
@@ -2,7 +2,7 @@
<view :class="['wd-badge', customClass]" :style="customStyle">
<slot></slot>
<view
v-if="isBadgeShow"
v-if="shouldShowBadge"
:class="['wd-badge__content', 'is-fixed', type ? 'wd-badge__content--' + type : '', isDot ? 'is-dot' : '']"
:style="contentStyle"
>
@@ -21,42 +21,39 @@ export default {
}
</script>
<script lang="ts" setup>
import { computed, ref, watch } from 'vue'
import { computed, type CSSProperties } from 'vue'
import { badgeProps } from './types'
import { addUnit, isDef, isNumber, objToStyle } from '../common/util'
const props = defineProps(badgeProps)
const content = ref<number | string | null>(null)
watch(
[() => props.modelValue, () => props.max, () => props.isDot],
() => {
notice()
},
{ immediate: true, deep: true }
)
const content = computed(() => {
const { modelValue, max, isDot } = props
if (isDot) return ''
let value = modelValue
if (value && max && isNumber(value) && !Number.isNaN(value) && !Number.isNaN(max)) {
value = max < value ? `${max}+` : value
}
return value
})
const contentStyle = computed(() => {
return `background-color: ${props.bgColor};top:${props.top || 0}px;right:${props.right || 0}px`
const style: CSSProperties = {}
if (isDef(props.bgColor)) {
style.backgroundColor = props.bgColor
}
if (isDef(props.top)) {
style.top = addUnit(props.top)
}
if (isDef(props.right)) {
style.right = addUnit(props.right)
}
return objToStyle(style)
})
//
const isBadgeShow = computed(() => {
let isBadgeShow: boolean = false
if (!props.hidden && (content.value || (content.value === 0 && props.showZero) || props.isDot)) {
isBadgeShow = true
}
return isBadgeShow
})
function notice() {
if (props.isDot) return
let value = props.modelValue
const max = props.max
if (value && max && typeof value === 'number' && !Number.isNaN(value) && !Number.isNaN(max)) {
value = max < value ? `${max}+` : value
}
content.value = value
}
const shouldShowBadge = computed(() => !props.hidden && (content.value || (content.value === 0 && props.showZero) || props.isDot))
</script>
<style lang="scss" scoped>
@@ -41,16 +41,17 @@
}
@include b(button) {
margin-left: initial;
margin-right: initial;
position: relative;
display: inline-flex;
justify-content: center;
align-items: center;
display: inline-block;
outline: none;
-webkit-appearance: none;
outline: none;
background: transparent;
box-sizing: border-box;
border: none;
border-radius: 0;
color: $-button-normal-color;
transition: opacity 0.2s;
user-select: none;
@@ -75,6 +76,14 @@
&::after {
border: none;
border-radius: 0;
}
@include e(content) {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
}
@include m(active) {
@@ -145,29 +154,10 @@
padding: $-button-medium-padding;
border-radius: $-button-medium-radius;
font-size: $-button-medium-fs;
min-width: 120px;
@include when(primary) {
box-shadow: $-button-medium-box-shadow-size $-button-primary-box-shadow-color;
}
@include when(success) {
box-shadow: $-button-medium-box-shadow-size $-button-success-box-shadow-color;
}
@include when(warning) {
box-shadow: $-button-medium-box-shadow-size $-button-warning-box-shadow-color;
}
@include when(error) {
box-shadow: $-button-medium-box-shadow-size $-button-error-box-shadow-color;
}
@include when(plain) {
box-shadow: none;
}
@include when(round) {
min-width: 120px;
@include when(icon) {
min-width: 0;
@@ -196,25 +186,6 @@
border-radius: $-button-large-radius;
}
&:not(.is-plain) {
@include when(primary) {
box-shadow: $-button-large-box-shadow-size $-button-primary-box-shadow-color;
}
@include when(success) {
box-shadow: $-button-large-box-shadow-size $-button-success-box-shadow-color;
}
@include when(warning) {
box-shadow: $-button-large-box-shadow-size $-button-warning-box-shadow-color;
}
@include when(error) {
box-shadow: $-button-large-box-shadow-size $-button-error-box-shadow-color;
}
}
.wd-button__loading {
width: $-button-large-loading;
height: $-button-large-loading;
@@ -224,7 +195,6 @@
@include when(round) {
border-radius: 999px;
overflow: hidden;
}
@include when(text) {
@@ -253,49 +223,72 @@
@include when(plain) {
background: $-button-plain-bg-color;
border: 1px solid currentColor;
@include when(primary) {
color: $-button-primary-bg-color;
border: 1px solid $-button-primary-bg-color;
}
@include when(success) {
color: $-button-success-bg-color;
border: 1px solid $-button-success-bg-color;
}
@include when(info) {
color: $-button-info-plain-normal-color;
border: 1px solid $-button-info-plain-border-color;
border-color: $-button-info-plain-border-color;
}
@include when(warning) {
color: $-button-warning-bg-color;
border: 1px solid $-button-warning-bg-color;
}
@include when(error) {
color: $-button-error-bg-color;
border: 1px solid $-button-error-bg-color;
}
}
@include when(hairline) {
border-width: 0;
&.is-plain {
border-width: 0;
border-radius: 0;
@include halfPixelBorderSurround();
&::before {
border-radius: inherit;
}
&::after {
border-color: inherit;
}
}
&.is-round {
&::after {
border-radius: inherit !important;
}
}
&.is-large {
&::after {
border-radius: calc(2 * $-button-large-radius);
}
}
&.is-medium {
&::after {
border-radius: calc(2 * $-button-medium-radius);
}
}
&.is-small {
&::after {
border-radius: calc(2 * $-button-small-radius);
}
}
}
}
@include when(block) {
display: flex;
display: block;
}
@include when(icon) {
@@ -332,12 +325,6 @@
}
}
// 微信2.8.0以上版本加了较高层级的默认样式需要重置掉
.wd-button {
min-height: auto;
width: auto;
}
@keyframes wd-rotate {
from {
transform: rotate(0deg);
@@ -346,4 +333,4 @@
to {
transform: rotate(360deg);
}
}
}
@@ -1,17 +1,49 @@
/*
* @Author: weisheng
* @Date: 2024-03-15 11:36:12
* @LastEditTime: 2024-03-18 13:24:34
* @LastEditTime: 2024-11-04 21:33:52
* @LastEditors: weisheng
* @Description:
* @FilePath: \wot-design-uni\src\uni_modules\wot-design-uni\components\wd-button\types.ts
*
*/
import type { ExtractPropTypes } from 'vue'
import type { ExtractPropTypes, PropType } from 'vue'
import { baseProps, makeBooleanProp, makeStringProp } from '../common/props'
export type ButtonType = 'primary' | 'success' | 'info' | 'warning' | 'error' | 'default' | 'text' | 'icon'
export type ButtonSize = 'small' | 'medium' | 'large'
export type ButtonLang = 'zh_CN' | 'zh_TW' | 'en'
export type ButtonOpenType =
| 'feedback'
| 'share'
| 'getUserInfo'
| 'contact'
| 'getPhoneNumber'
| 'launchApp'
| 'openSetting'
| 'chooseAvatar'
| 'getAuthorize'
| 'lifestyle'
| 'contactShare'
| 'openGroupProfile'
| 'openGuildProfile'
| 'openPublicProfile'
| 'shareMessageToFriend'
| 'addFriend'
| 'addColorSign'
| 'addGroupApp'
| 'addToFavorites'
| 'chooseAddress'
| 'chooseInvoiceTitle'
| 'login'
| 'subscribe'
| 'favorite'
| 'watchLater'
| 'openProfile'
| 'agreePrivacyAuthorization'
export type ButtonScope = 'phoneNumber' | 'userInfo'
export const buttonProps = {
...baseProps,
@@ -47,6 +79,10 @@ export const buttonProps = {
*
*/
icon: String,
/**
* 使Icon组件
*/
classPrefix: makeStringProp('wd-icon'),
/**
*
*/
@@ -58,8 +94,7 @@ export const buttonProps = {
/**
*
*/
openType: String,
formType: String,
openType: String as PropType<ButtonOpenType>,
/**
*
*/
@@ -67,7 +102,7 @@ export const buttonProps = {
/**
* zh_CN zh_TW en
*/
lang: String,
lang: String as PropType<ButtonLang>,
/**
* open-type="contact"
*/
@@ -91,7 +126,16 @@ export const buttonProps = {
/**
* true"可能要发送的小程序"open-type="contact"
*/
showMessageCard: Boolean
showMessageCard: Boolean,
/**
* id
*/
buttonId: String,
/**
* open-type getAuthorize
* 'phoneNumber' | 'userInfo'
*/
scope: String as PropType<ButtonScope>
}
export type ButtonProps = ExtractPropTypes<typeof buttonProps>
@@ -1,22 +1,23 @@
<template>
<button
:id="buttonId"
:hover-class="`${disabled || loading ? '' : 'wd-button--active'}`"
:style="customStyle"
:class="[
'wd-button',
'is-' + type,
'is-' + size,
plain ? 'is-plain' : '',
disabled ? 'is-disabled' : '',
round ? 'is-round' : '',
hairline ? 'is-hairline' : '',
plain ? 'is-plain' : '',
disabled ? 'is-disabled' : '',
block ? 'is-block' : '',
loading ? 'is-loading' : '',
customClass
]"
:hover-start-time="hoverStartTime"
:hover-stay-time="hoverStayTime"
:open-type="openType"
:open-type="disabled || loading ? undefined : openType"
:send-message-title="sendMessageTitle"
:send-message-path="sendMessagePath"
:send-message-img="sendMessageImg"
@@ -25,8 +26,9 @@
:session-from="sessionFrom"
:lang="lang"
:hover-stop-propagation="hoverStopPropagation"
:form-type="formType"
:scope="scope"
@click="handleClick"
@getAuthorize="handleGetAuthorize"
@getuserinfo="handleGetuserinfo"
@contact="handleConcat"
@getphonenumber="handleGetphonenumber"
@@ -36,11 +38,13 @@
@chooseavatar="handleChooseavatar"
@agreeprivacyauthorization="handleAgreePrivacyAuthorization"
>
<view v-if="loading" class="wd-button__loading">
<view class="wd-button__loading-svg" :style="loadingStyle"></view>
<view class="wd-button__content">
<view v-if="loading" class="wd-button__loading">
<view class="wd-button__loading-svg" :style="loadingStyle"></view>
</view>
<wd-icon v-else-if="icon" custom-class="wd-button__icon" :name="icon" :classPrefix="classPrefix"></wd-icon>
<view class="wd-button__text"><slot /></view>
</view>
<wd-icon v-else-if="icon" custom-class="wd-button__icon" :name="icon"></wd-icon>
<view class="wd-button__text"><slot /></view>
</button>
</template>
@@ -56,6 +60,7 @@ export default {
</script>
<script lang="ts" setup>
import wdIcon from '../wd-icon/wd-icon.vue'
import { computed, watch } from 'vue'
import { ref } from 'vue'
import base64 from '../common/base64'
@@ -101,7 +106,19 @@ watch(
function handleClick(event: any) {
if (!props.disabled && !props.loading) {
emit('click', event.detail)
emit('click', event)
}
}
/**
* 支付宝小程序授权
* @param event
*/
function handleGetAuthorize(event: any) {
if (props.scope === 'phoneNumber') {
handleGetphonenumber(event)
} else if (props.scope === 'userInfo') {
handleGetuserinfo(event)
}
}
@@ -44,6 +44,7 @@
height: $-calendar-day-height;
line-height: $-calendar-day-height;
text-align: center;
margin-bottom: $-calendar-item-margin-bottom;
@include when(disabled) {
.wd-month__day-text {
@@ -55,11 +56,11 @@
color: $-calendar-active-color;
}
@include when(selected) {
@include when(selected, multiple-selected) {
.wd-month__day-container {
border-radius: $-calendar-active-border;
background: $-calendar-active-color;
color: #fff;
color: $-calendar-selected-color;
}
}
@@ -68,6 +69,12 @@
background: $-calendar-range-color;
}
}
@include when(multiple-middle) {
.wd-month__day-container {
background: $-calendar-active-color;
color: $-calendar-selected-color;
}
}
@include when(start) {
&::after {
@@ -87,8 +94,8 @@
.wd-month__day-container {
background: $-calendar-active-color;
color: #fff;
border-radius: $-calendar-active-border;
color: $-calendar-selected-color;
border-radius: $-calendar-active-border 0 0 $-calendar-active-border;
}
}
@@ -106,18 +113,22 @@
.wd-month__day-container {
background: $-calendar-active-color;
color: #fff;
border-radius: $-calendar-active-border;
color: $-calendar-selected-color;
border-radius: 0 $-calendar-active-border $-calendar-active-border 0;
}
}
@include when(same) {
.wd-month__day-container {
background: $-calendar-active-color;
color: #fff;
color: $-calendar-selected-color;
border-radius: $-calendar-active-border;
}
}
@include when(last-row){
margin-bottom: 0;
}
}
@include e(day-container) {
@@ -3,13 +3,15 @@
<wd-toast selector="wd-month" />
<view class="month">
<view class="wd-month">
<view class="wd-month__title">{{ monthTitle(date) }}</view>
<view class="wd-month__title" v-if="showTitle">{{ monthTitle(date) }}</view>
<view class="wd-month__days">
<view
v-for="(item, index) in days"
:key="index"
:class="`wd-month__day ${item.disabled ? 'is-disabled' : ''} ${item.type ? itemClass(item.type, value!, type) : ''}`"
:style="firstDayStyle(index, item.date, firstDayOfWeek)"
:class="`wd-month__day ${item.disabled ? 'is-disabled' : ''} ${item.isLastRow ? 'is-last-row' : ''} ${
item.type ? dayTypeClass(item.type) : ''
}`"
:style="index === 0 ? firstDayStyle : ''"
@click="handleDateClick(index)"
>
<view class="wd-month__day-container">
@@ -37,22 +39,24 @@ export default {
</script>
<script lang="ts" setup>
import { computed, ref, watch } from 'vue'
import wdToast from '../../wd-toast/wd-toast.vue'
import { computed, ref, watch, type CSSProperties } from 'vue'
import {
compareDate,
formatMonthTitle,
getDateByDefaultTime,
getDayByOffset,
getDayOffset,
getFirstDayStyle,
getItemClass,
getMonthEndDay,
getNextDay,
getPrevDay,
getWeekRange
} from '../utils'
import { useToast } from '../../wd-toast'
import { deepClone, isArray, isFunction } from '../../common/util'
import { deepClone, isArray, isFunction, objToStyle } from '../../common/util'
import { useTranslate } from '../../composables/useTranslate'
import type { CalendarDayItem, CalendarDayType, CalendarType } from '../types'
import type { CalendarDayItem, CalendarDayType } from '../types'
import { monthProps } from './types'
const props = defineProps(monthProps)
@@ -64,9 +68,15 @@ const days = ref<Array<CalendarDayItem>>([])
const toast = useToast('wd-month')
const itemClass = computed(() => {
return (monthType: CalendarDayType, value: number | (number | null)[], type: CalendarType) => {
return getItemClass(monthType, value, type)
const offset = computed(() => {
const firstDayOfWeek = props.firstDayOfWeek >= 7 ? props.firstDayOfWeek % 7 : props.firstDayOfWeek
const offset = (7 + new Date(props.date).getDay() - firstDayOfWeek) % 7
return offset
})
const dayTypeClass = computed(() => {
return (monthType: CalendarDayType) => {
return getItemClass(monthType, props.value, props.type)
}
})
@@ -75,12 +85,21 @@ const monthTitle = computed(() => {
return formatMonthTitle(date)
}
})
const firstDayStyle = computed(() => {
return (index: number, date: number, firstDayOfWeek: number) => {
return getFirstDayStyle(index, date, firstDayOfWeek)
}
const dayStyle: CSSProperties = {}
dayStyle.marginLeft = `${(100 / 7) * offset.value}%`
return objToStyle(dayStyle)
})
const isLastRow = (date: number) => {
const currentDate = new Date(date)
const currentDay = currentDate.getDate()
const daysInMonth = getMonthEndDay(currentDate.getFullYear(), currentDate.getMonth() + 1)
const totalDaysShown = offset.value + daysInMonth
const totalRows = Math.ceil(totalDaysShown / 7)
return Math.ceil((offset.value + currentDay) / 7) === totalRows
}
watch(
[() => props.type, () => props.date, () => props.value, () => props.minDate, () => props.maxDate, () => props.formatter],
() => {
@@ -140,17 +159,29 @@ function getDateType(date: number): CalendarDayType {
}
function getDatesType(date: number): CalendarDayType {
if (!isArray(props.value)) return ''
const { value } = props
let type: CalendarDayType = ''
props.value.some((item) => {
if (compareDate(date, item) === 0) {
type = 'selected'
return true
}
return false
})
if (!isArray(value)) return type
const isSelected = (day: number) => {
return value.some((item) => compareDate(day, item) === 0)
}
if (isSelected(date)) {
const prevDay = getPrevDay(date)
const nextDay = getNextDay(date)
const prevSelected = isSelected(prevDay)
const nextSelected = isSelected(nextDay)
if (prevSelected && nextSelected) {
type = 'multiple-middle'
} else if (prevSelected) {
type = 'end'
} else if (nextSelected) {
type = 'start'
} else {
type = 'multiple-selected'
}
}
return type
}
@@ -250,16 +281,12 @@ function handleDateChange(date: CalendarDayItem) {
}
function handleDatesChange(date: CalendarDayItem) {
if (date.disabled) return
const value = deepClone(isArray(props.value) ? props.value : [])
if (date.type !== 'selected') {
value.push(getDate(date.date))
} else {
value.splice(value.indexOf(date.date), 1)
}
emit('change', {
value
})
const currentValue = deepClone(isArray(props.value) ? props.value : [])
const dateIndex = currentValue.findIndex((item) => item && compareDate(item, date.date) === 0)
const value = dateIndex === -1 ? [...currentValue, getDate(date.date)] : currentValue.filter((_, index) => index !== dateIndex)
emit('change', { value })
}
function handleDateRangeChange(date: CalendarDayItem) {
if (date.disabled) return
@@ -344,7 +371,8 @@ function getFormatterDate(date: number, day: string | number, type?: CalendarDay
topInfo: '',
bottomInfo: '',
type,
disabled: compareDate(date, props.minDate) === -1 || compareDate(date, props.maxDate) === 1
disabled: compareDate(date, props.minDate) === -1 || compareDate(date, props.maxDate) === 1,
isLastRow: isLastRow(date)
}
if (props.formatter) {
if (isFunction(props.formatter)) {
@@ -15,5 +15,6 @@ export const monthProps = {
allowSameDay: makeBooleanProp(false),
defaultTime: {
type: [Array] as PropType<Array<number[]>>
}
},
showTitle: makeBooleanProp(true)
}
@@ -26,6 +26,7 @@
:range-prompt="rangePrompt"
:allow-same-day="allowSameDay"
:default-time="defaultTime"
:showTitle="index !== 0"
@change="handleDateChange"
/>
</view>
@@ -40,6 +41,7 @@
v-model="timeValue"
:columns="timeData"
:columns-height="125"
:immediate-change="immediateChange"
@change="handleTimeChange"
@pickstart="handlePickStart"
@pickend="handlePickEnd"
@@ -60,8 +62,9 @@ export default {
</script>
<script lang="ts" setup>
import wdPickerView from '../../wd-picker-view/wd-picker-view.vue'
import { computed, ref, watch, onMounted } from 'vue'
import { debounce, isArray, isEqual, isNumber, requestAnimationFrame } from '../../common/util'
import { debounce, isArray, isEqual, isNumber, pause } from '../../common/util'
import { compareMonth, formatMonthTitle, getMonthEndDay, getMonths, getTimeData, getWeekLabel } from '../utils'
import Month from '../month/month.vue'
import { monthPanelProps, type MonthInfo, type MonthPanelTimeType, type MonthPanelExpose } from './types'
@@ -129,17 +132,18 @@ const weekLabel = computed(() => {
//
const scrollHeight = computed(() => {
const scrollHeight: number = timeType.value ? (props.panelHeight || 378) - 125 : props.panelHeight || 378
const scrollHeight: number = timeType.value ? props.panelHeight - 125 : props.panelHeight
return scrollHeight
})
//
const months = computed<MonthInfo[]>(() => {
return getMonths(props.minDate, props.maxDate).map((month) => {
return getMonths(props.minDate, props.maxDate).map((month, index) => {
const offset = (7 + new Date(month).getDay() - props.firstDayOfWeek) % 7
const totalDay = getMonthEndDay(new Date(month).getFullYear(), new Date(month).getMonth() + 1)
const rows = Math.ceil((offset + totalDay) / 7)
return {
height: (offset + totalDay > 35 ? 64 * 6 : 64 * 5) + 45,
height: rows * 64 + (rows - 1) * 4 + (index === 0 ? 0 : 45), // 64px,4px margin,45px
date: month
}
})
@@ -183,31 +187,45 @@ onMounted(() => {
/**
* 使当前日期或者选中日期滚动到可视区域
*/
function scrollIntoView() {
requestAnimationFrame(() => {
let activeDate: number | null = 0
if (isArray(props.value)) {
activeDate = props.value![0]
} else if (isNumber(props.value)) {
activeDate = props.value
}
async function scrollIntoView() {
//
await pause()
let activeDate: number | null = 0
if (isArray(props.value)) {
// ,
const sortedValue = [...props.value].sort((a, b) => (a || 0) - (b || 0))
activeDate = sortedValue[0]
} else if (isNumber(props.value)) {
activeDate = props.value
}
if (!activeDate) {
activeDate = Date.now()
}
if (!activeDate) {
activeDate = Date.now()
}
let top: number = 0
for (let index = 0; index < months.value.length; index++) {
if (compareMonth(months.value[index].date, activeDate) === 0) {
break
}
top += months.value[index] ? Number(months.value[index].height) : 0
let top: number = 0
let activeMonthIndex = -1
for (let index = 0; index < months.value.length; index++) {
if (compareMonth(months.value[index].date, activeDate) === 0) {
activeMonthIndex = index
// ,
const date = new Date(activeDate)
const day = date.getDate()
const firstDay = new Date(date.getFullYear(), date.getMonth(), 1)
const offset = (7 + firstDay.getDay() - props.firstDayOfWeek) % 7
const row = Math.floor((offset + day - 1) / 7)
// 64px,4px margin
top += row * 64 + row * 4
break
}
scrollTop.value = 0
requestAnimationFrame(() => {
scrollTop.value = top
})
})
top += months.value[index] ? Number(months.value[index].height) : 0
}
scrollTop.value = 0
if (top > 0) {
await pause()
// 45
scrollTop.value = top + (activeMonthIndex > 0 ? 45 : 0)
}
}
/**
* 获取时间 picker 的数据
@@ -339,7 +357,7 @@ function doSetSubtitle(scrollTop: number) {
let height: number = 0 //
for (let index = 0; index < months.value.length; index++) {
height = height + months.value[index].height
if (scrollTop < height + 45) {
if (scrollTop < height) {
scrollIndex.value = index
return
}
@@ -27,7 +27,11 @@ export const monthPanelProps = {
panelHeight: makeRequiredProp(Number),
// type 为 'datetime' 或 'datetimerange' 时有效,用于过滤时间选择器的数据
timeFilter: Function as PropType<CalendarTimeFilter>,
hideSecond: makeBooleanProp(false)
hideSecond: makeBooleanProp(false),
/**
* picker-view的 change change 1.2.25
*/
immediateChange: makeBooleanProp(false)
}
export type MonthPanelProps = ExtractPropTypes<typeof monthPanelProps>
@@ -61,12 +61,16 @@ export const calendarViewProps = {
/**
* type 'datetime' 'datetimerange'
*/
hideSecond: makeBooleanProp(false)
hideSecond: makeBooleanProp(false),
/**
* picker-view的 change change 1.2.25
*/
immediateChange: makeBooleanProp(false)
}
export type CalendarViewProps = ExtractPropTypes<typeof calendarViewProps>
export type CalendarDayType = '' | 'start' | 'middle' | 'end' | 'selected' | 'same' | 'current'
export type CalendarDayType = '' | 'start' | 'middle' | 'end' | 'selected' | 'same' | 'current' | 'multiple-middle' | 'multiple-selected'
export type CalendarDayItem = {
date: number
@@ -75,6 +79,7 @@ export type CalendarDayItem = {
bottomInfo?: string
type?: CalendarDayType
disabled?: boolean
isLastRow?: boolean
}
export type CalendarFormatter = (day: CalendarDayItem) => CalendarDayItem
@@ -116,24 +116,6 @@ export function getWeekLabel(index: number) {
return weeks.value[index]
}
/**
*
* @param {number} index
* @param {timestamp} date
* @param {number} firstDayOfWeek
*/
export function getFirstDayStyle(index: number, date: number, firstDayOfWeek: number) {
if (firstDayOfWeek >= 7) {
firstDayOfWeek = firstDayOfWeek % 7
}
if (index !== 0) return ''
const offset = (7 + new Date(date).getDay() - firstDayOfWeek) % 7
return 'margin-left: ' + (100 / 7) * offset + '%'
}
/**
*
* @param {timestamp} date
@@ -222,6 +204,9 @@ export function getDayByOffset(date: number, offset: number) {
return dateValue.getTime()
}
export const getPrevDay = (date: number) => getDayByOffset(date, -1)
export const getNextDay = (date: number) => getDayByOffset(date, 1)
/**
*
* @param {timestamp} date1
@@ -431,7 +416,7 @@ export function getWeekNumber(date: number | Date) {
return 1 + Math.round(((date.getTime() - week.getTime()) / 86400000 - 3 + ((week.getDay() + 6) % 7)) / 7)
}
export function getItemClass(monthType: CalendarDayType, value: number | (number | null)[], type: CalendarType) {
export function getItemClass(monthType: CalendarDayType, value: number | null | (number | null)[], type: CalendarType) {
const classList = ['is-' + monthType]
if (type.indexOf('range') > -1 && isArray(value)) {
@@ -31,6 +31,7 @@
:show-panel-title="showPanelTitle"
:default-time="formatDefauleTime"
:panel-height="panelHeight"
:immediate-change="immediateChange"
:time-filter="timeFilter"
:hide-second="hideSecond"
@change="handleChange"
@@ -45,6 +45,7 @@
height: $-calendar-day-height;
line-height: $-calendar-day-height;
text-align: center;
margin-bottom: $-calendar-item-margin-bottom;
@include when(disabled) {
.wd-year__month-text {
@@ -70,7 +71,7 @@
}
@include when(start) {
color: #fff;
color: $-calendar-selected-color;
&::after {
position: absolute;
@@ -84,7 +85,7 @@
.wd-year__month-text {
background: $-calendar-active-color;
border-radius: $-calendar-active-border;
border-radius: $-calendar-active-border 0 0 $-calendar-active-border;
}
&.is-without-end::after {
@@ -93,7 +94,7 @@
}
@include when(end) {
color: #fff;
color: $-calendar-selected-color;
&::after {
position: absolute;
@@ -107,18 +108,21 @@
.wd-year__month-text {
background: $-calendar-active-color;
border-radius: $-calendar-active-border;
border-radius: 0 $-calendar-active-border $-calendar-active-border 0;
}
}
@include when(same) {
color: #fff;
color: $-calendar-selected-color;
.wd-year__month-text {
background: $-calendar-active-color;
border-radius: $-calendar-active-border;
}
}
@include when(last-row){
margin-bottom: 0;
}
}
@include e(month-text) {
@@ -15,5 +15,6 @@ export const yearProps = {
allowSameDay: makeBooleanProp(false),
defaultTime: {
type: [Array] as PropType<Array<number[]>>
}
},
showTitle: makeBooleanProp(true)
}
@@ -2,12 +2,14 @@
<wd-toast selector="wd-year" />
<view class="wd-year year">
<view class="wd-year__title">{{ yearTitle(date) }}</view>
<view class="wd-year__title" v-if="showTitle">{{ yearTitle(date) }}</view>
<view class="wd-year__months">
<view
v-for="(item, index) in months"
:key="index"
:class="`wd-year__month ${item.disabled ? 'is-disabled' : ''} ${item.type ? itemClass(item.type, value!, type) : ''}`"
:class="`wd-year__month ${item.disabled ? 'is-disabled' : ''} ${item.isLastRow ? 'is-last-row' : ''} ${
item.type ? monthTypeClass(item.type) : ''
}`"
@click="handleDateClick(index)"
>
<view class="wd-year__month-top">{{ item.topInfo }}</view>
@@ -28,6 +30,7 @@ export default {
</script>
<script lang="ts" setup>
import wdToast from '../../wd-toast/wd-toast.vue'
import { computed, ref, watch } from 'vue'
import { deepClone, isArray, isFunction } from '../../common/util'
import { compareMonth, formatYearTitle, getDateByDefaultTime, getItemClass, getMonthByOffset, getMonthOffset } from '../utils'
@@ -35,7 +38,7 @@ import { useToast } from '../../wd-toast'
import { useTranslate } from '../../composables/useTranslate'
import { dayjs } from '../../common/dayjs'
import { yearProps } from './types'
import type { CalendarDayItem, CalendarDayType, CalendarType } from '../types'
import type { CalendarDayItem, CalendarDayType } from '../types'
const props = defineProps(yearProps)
const emit = defineEmits(['change'])
@@ -45,9 +48,9 @@ const { translate } = useTranslate('calendar-view')
const months = ref<CalendarDayItem[]>([])
const itemClass = computed(() => {
return (monthType: CalendarDayType, value: number | (number | null)[], type: CalendarType) => {
return getItemClass(monthType, value, type)
const monthTypeClass = computed(() => {
return (monthType: CalendarDayType) => {
return getItemClass(monthType, props.value, props.type)
}
})
@@ -178,8 +181,10 @@ function getFormatterDate(date: number, month: number, type?: CalendarDayType) {
topInfo: '',
bottomInfo: '',
type,
disabled: compareMonth(date, props.minDate) === -1 || compareMonth(date, props.maxDate) === 1
disabled: compareMonth(date, props.minDate) === -1 || compareMonth(date, props.maxDate) === 1,
isLastRow: month >= 8
}
if (props.formatter) {
if (isFunction(props.formatter)) {
monthObj = props.formatter(monthObj)
@@ -14,6 +14,7 @@
:range-prompt="rangePrompt"
:allow-same-day="allowSameDay"
:default-time="defaultTime"
:showTitle="index !== 0"
@change="handleDateChange"
/>
</view>
@@ -33,7 +34,7 @@ export default {
<script lang="ts" setup>
import { computed, ref, onMounted } from 'vue'
import { compareYear, formatYearTitle, getYears } from '../utils'
import { isArray, isNumber, requestAnimationFrame } from '../../common/util'
import { isArray, isNumber, pause } from '../../common/util'
import Year from '../year/year.vue'
import { yearPanelProps, type YearInfo, type YearPanelExpose } from './types'
@@ -45,16 +46,16 @@ const scrollIndex = ref<number>(0) // 当前显示的年份索引
//
const scrollHeight = computed(() => {
const scrollHeight: number = (props.panelHeight || 378) + (props.showPanelTitle ? 26 : 16)
const scrollHeight: number = props.panelHeight + (props.showPanelTitle ? 26 : 16)
return scrollHeight
})
//
const years = computed<YearInfo[]>(() => {
return getYears(props.minDate, props.maxDate).map((year) => {
return getYears(props.minDate, props.maxDate).map((year, index) => {
return {
date: year,
height: 237
height: index === 0 ? 200 : 245
}
})
})
@@ -68,38 +69,38 @@ onMounted(() => {
scrollIntoView()
})
function scrollIntoView() {
requestAnimationFrame(() => {
let activeDate: number | null = null
if (isArray(props.value)) {
activeDate = props.value![0]
} else if (isNumber(props.value)) {
activeDate = props.value
}
async function scrollIntoView() {
await pause()
let activeDate: number | null = null
if (isArray(props.value)) {
activeDate = props.value![0]
} else if (isNumber(props.value)) {
activeDate = props.value
}
if (!activeDate) {
activeDate = Date.now()
}
if (!activeDate) {
activeDate = Date.now()
}
let top: number = 0
for (let index = 0; index < years.value.length; index++) {
if (compareYear(years.value[index].date, activeDate) === 0) {
break
}
top += years.value[index] ? Number(years.value[index].height) : 0
let top: number = 0
for (let index = 0; index < years.value.length; index++) {
if (compareYear(years.value[index].date, activeDate) === 0) {
break
}
scrollTop.value = 0
requestAnimationFrame(() => {
scrollTop.value = top
})
})
top += years.value[index] ? Number(years.value[index].height) : 0
}
scrollTop.value = 0
if (top > 0) {
await pause()
scrollTop.value = top + 45
}
}
const yearScroll = (e: Event) => {
const yearScroll = (event: { detail: { scrollTop: number } }) => {
if (years.value.length <= 1) {
return
}
const scrollTop = Math.max(0, (e.target as Element).scrollTop)
const scrollTop = Math.max(0, event.detail.scrollTop)
doSetSubtitle(scrollTop)
}
@@ -111,7 +112,7 @@ function doSetSubtitle(scrollTop: number) {
let height: number = 0 //
for (let index = 0; index < years.value.length; index++) {
height = height + years.value[index].height
if (scrollTop < height + 45) {
if (scrollTop < height) {
scrollIndex.value = index
return
}
@@ -7,6 +7,10 @@
background-color: $-dark-background2;
color: $-dark-color;
}
@include e(label) {
color: $-dark-color;
}
@include e(value) {
color: $-dark-color;
@@ -1,13 +1,13 @@
/*
* @Author: weisheng
* @Date: 2024-03-15 20:40:34
* @LastEditTime: 2024-03-18 13:37:40
* @LastEditTime: 2024-12-08 19:13:33
* @LastEditors: weisheng
* @Description:
* @FilePath: \wot-design-uni\src\uni_modules\wot-design-uni\components\wd-calendar\types.ts
* @FilePath: /wot-design-uni/src/uni_modules/wot-design-uni/components/wd-calendar/types.ts
*
*/
import type { PropType } from 'vue'
import type { ComponentPublicInstance, ExtractPropTypes, PropType } from 'vue'
import { baseProps, makeArrayProp, makeBooleanProp, makeNumberProp, makeRequiredProp, makeStringProp } from '../common/props'
import type { CalendarFormatter, CalendarTimeFilter, CalendarType } from '../wd-calendar-view/types'
import type { FormItemRule } from '../wd-form/types'
@@ -72,14 +72,6 @@ export const calendarProps = {
*
*/
labelWidth: String,
/**
* 使 label
*/
useLabelSlot: makeBooleanProp(false),
/**
* 使
*/
useDefaultSlot: makeBooleanProp(false),
/**
*
*/
@@ -180,7 +172,16 @@ export const calendarProps = {
/**
* value
*/
customValueClass: makeStringProp('')
customValueClass: makeStringProp(''),
/**
* picker-view的 change change 1.2.25
*/
immediateChange: makeBooleanProp(false),
/**
* 使
* true使
*/
withCell: makeBooleanProp(true)
}
export type CalendarDisplayFormat = (value: number | number[], type: CalendarType) => string
@@ -207,3 +208,7 @@ export type CalendarExpose = {
/** 打开时间选择器弹窗 */
open: () => void
}
export type CalendarProps = ExtractPropTypes<typeof calendarProps>
export type CalendarInstance = ComponentPublicInstance<CalendarExpose, CalendarProps>
@@ -1,20 +1,19 @@
<template>
<view :class="`wd-calendar ${cell.border.value ? 'is-border' : ''} ${customClass}`">
<view class="wd-calendar__field" @click="open">
<slot v-if="useDefaultSlot"></slot>
<view class="wd-calendar__field" @click="open" v-if="withCell">
<slot v-if="$slots.default"></slot>
<view
v-else
:class="`wd-calendar__cell ${disabled ? 'is-disabled' : ''} ${readonly ? 'is-readonly' : ''} ${alignRight ? 'is-align-right' : ''} ${
:class="`wd-calendar__cell ${disabled ? 'is-disabled' : ''} ${props.readonly ? 'is-readonly' : ''} ${alignRight ? 'is-align-right' : ''} ${
error ? 'is-error' : ''
} ${size ? 'is-' + size : ''} ${center ? 'is-center' : ''}`"
>
<view
v-if="label || useLabelSlot"
v-if="label || $slots.label"
:class="`wd-calendar__label ${isRequired ? 'is-required' : ''} ${customLabelClass}`"
:style="labelWidth ? 'min-width:' + labelWidth + ';max-width:' + labelWidth + ';' : ''"
>
<block v-if="label">{{ label }}</block>
<slot v-else name="label"></slot>
<slot name="label">{{ label }}</slot>
</view>
<view class="wd-calendar__body">
<view class="wd-calendar__value-wraper">
@@ -93,6 +92,7 @@
:time-filter="timeFilter"
:hide-second="hideSecond"
:show-panel-title="!range(type)"
:immediate-change="immediateChange"
@change="handleChange"
/>
</view>
@@ -115,9 +115,13 @@ export default {
</script>
<script lang="ts" setup>
import wdIcon from '../wd-icon/wd-icon.vue'
import wdCalendarView from '../wd-calendar-view/wd-calendar-view.vue'
import wdActionSheet from '../wd-action-sheet/wd-action-sheet.vue'
import wdButton from '../wd-button/wd-button.vue'
import { ref, computed, watch } from 'vue'
import { dayjs } from '../common/dayjs'
import { deepClone, isArray, isEqual, padZero, requestAnimationFrame } from '../common/util'
import { deepClone, isArray, isEqual, padZero, pause } from '../common/util'
import { getWeekNumber, isRange } from '../wd-calendar-view/utils'
import { useCell } from '../composables/useCell'
import { FORM_KEY, type FormItemRule } from '../wd-form/types'
@@ -148,17 +152,35 @@ const defaultDisplayFormat = (value: number | number[], type: CalendarType): str
'to'
)}\n${(value as number[])[1] ? dayjs((value as number[])[1]).format(translate('timeFormat')) : translate('endTime')}`
case 'week': {
const year = new Date(value as number).getFullYear()
const date = new Date(value as number)
const year = date.getFullYear()
const week = getWeekNumber(value as number)
return translate('weekFormat', year, padZero(week))
const weekStart = new Date(date)
weekStart.setDate(date.getDate() - date.getDay() + 1)
const weekEnd = new Date(date)
weekEnd.setDate(date.getDate() + (7 - date.getDay()))
const adjustedYear = weekEnd.getFullYear() > year ? weekEnd.getFullYear() : year
return translate('weekFormat', adjustedYear, padZero(week))
}
case 'weekrange': {
const year1 = new Date((value as number[])[0]).getFullYear()
const date1 = new Date((value as number[])[0])
const date2 = new Date((value as number[])[1])
const year1 = date1.getFullYear()
const year2 = date2.getFullYear()
const week1 = getWeekNumber((value as number[])[0])
const year2 = new Date((value as number[])[1]).getFullYear()
const week2 = getWeekNumber((value as number[])[1])
return `${(value as number[])[0] ? translate('weekFormat', year1, padZero(week1)) : translate('startWeek')} - ${
(value as number[])[1] ? translate('weekFormat', year2, padZero(week2)) : translate('endWeek')
const weekStart1 = new Date(date1)
weekStart1.setDate(date1.getDate() - date1.getDay() + 1)
const weekEnd1 = new Date(date1)
weekEnd1.setDate(date1.getDate() + (7 - date1.getDay()))
const weekStart2 = new Date(date2)
weekStart2.setDate(date2.getDate() - date2.getDay() + 1)
const weekEnd2 = new Date(date2)
weekEnd2.setDate(date2.getDate() + (7 - date2.getDay()))
const adjustedYear1 = weekEnd1.getFullYear() > year1 ? weekEnd1.getFullYear() : year1
const adjustedYear2 = weekEnd2.getFullYear() > year2 ? weekEnd2.getFullYear() : year2
return `${(value as number[])[0] ? translate('weekFormat', adjustedYear1, padZero(week1)) : translate('startWeek')} - ${
(value as number[])[1] ? translate('weekFormat', adjustedYear2, padZero(week2)) : translate('endWeek')
}`
}
case 'month':
@@ -200,7 +222,7 @@ const formatRange = (value: number, rangeType: 'start' | 'end', type: CalendarTy
}
const props = defineProps(calendarProps)
const emit = defineEmits(['cancel', 'change', 'update:modelValue', 'confirm'])
const emit = defineEmits(['cancel', 'change', 'update:modelValue', 'confirm', 'open'])
const pickerShow = ref<boolean>(false)
const calendarValue = ref<null | number | number[]>(null)
@@ -308,7 +330,7 @@ function scrollIntoView() {
calendarView.value && calendarView.value && calendarView.value.$.exposed.scrollIntoView()
}
//
function open() {
async function open() {
const { disabled, readonly } = props
if (disabled || readonly) return
@@ -318,16 +340,16 @@ function open() {
lastCalendarValue.value = deepClone(calendarValue.value)
lastTab.value = currentTab.value
lastCurrentType.value = currentType.value
requestAnimationFrame(() => {
scrollIntoView()
})
//
await pause()
scrollIntoView()
setTimeout(() => {
if (props.showTypeSwitch) {
calendarTabs.value.scrollIntoView()
calendarTabs.value.updateLineStyle(false)
}
}, 250)
emit('open')
}
//
function close() {
@@ -344,7 +366,6 @@ function handleTypeChange({ index }: { index: number }) {
const tabs = ['date', 'week', 'month']
const rangeTabs = ['daterange', 'weekrange', 'monthrange']
const type = props.type.indexOf('range') > -1 ? rangeTabs[index] : tabs[index]
currentTab.value = index
currentType.value = type as CalendarType
}
@@ -390,7 +411,8 @@ function onConfirm() {
lastCurrentType.value = currentType.value
emit('update:modelValue', calendarValue.value)
emit('confirm', {
value: calendarValue.value
value: calendarValue.value,
type: currentType.value
})
}
@@ -1,6 +1,6 @@
<template>
<view :class="['wd-card', type == 'rectangle' ? 'is-rectangle' : '', customClass]" :style="customStyle">
<view :class="['wd-card__title-content', customTitleClass]">
<view :class="['wd-card__title-content', customTitleClass]" v-if="title || $slots.title">
<view class="wd-card__title">
<text v-if="title">{{ title }}</text>
<slot v-else name="title"></slot>
@@ -9,7 +9,7 @@
<view :class="`wd-card__content ${customContentClass}`">
<slot></slot>
</view>
<view :class="`wd-card__footer ${customFooterClass}`">
<view :class="`wd-card__footer ${customFooterClass}`" v-if="$slots.footer">
<slot name="footer"></slot>
</view>
</view>
@@ -111,7 +111,6 @@
margin-top: 2px;
font-size: $-cell-label-fs;
color: $-cell-label-color;
@include lineEllipsis;
}
@include edeep(icon) {
@@ -44,7 +44,7 @@ export const cellProps = {
/**
* 线
*/
border: Boolean,
border: makeBooleanProp(void 0),
/**
*
*/
@@ -3,7 +3,7 @@
:class="['wd-cell', isBorder ? 'is-border' : '', size ? 'is-' + size : '', center ? 'is-center' : '', customClass]"
:style="customStyle"
:hover-class="isLink || clickable ? 'is-hover' : 'none'"
hover-stay-time="70"
:hover-stay-time="70"
@click="onClick"
>
<view :class="['wd-cell__wrapper', vertical ? 'is-vertical' : '']">
@@ -57,6 +57,7 @@ export default {
</script>
<script lang="ts" setup>
import wdIcon from '../wd-icon/wd-icon.vue'
import { computed } from 'vue'
import { useCell } from '../composables/useCell'
import { useParent } from '../composables/useParent'
@@ -70,7 +71,7 @@ const emit = defineEmits(['click'])
const cell = useCell()
const isBorder = computed(() => {
return isDef(cell.border.value) ? cell.border.value : props.border
return Boolean(isDef(props.border) ? props.border : cell.border.value)
})
const { parent: form } = useParent(FORM_KEY)
@@ -111,8 +111,6 @@
display: inline-block;
font-size: $-checkbox-icon-size;
margin-right: 4px;
height: $-checkbox-icon-size;
width: $-checkbox-icon-size;
vertical-align: middle;
}
@@ -18,7 +18,9 @@ export const checkboxProps = {
/**
* circle / square / button
*/
shape: makeStringProp<CheckShape>('circle'),
shape: {
type: String as PropType<CheckShape>
},
/**
*
*/
@@ -14,7 +14,7 @@
:class="`wd-checkbox__shape ${innerShape === 'square' ? 'is-square' : ''} ${customShapeClass}`"
:style="isChecked && !innerDisabled && innerCheckedColor ? 'color :' + innerCheckedColor : ''"
>
<wd-icon custom-class="wd-checkbox__check" name="check-bold" size="14px" />
<wd-icon custom-class="wd-checkbox__check" name="check-bold" />
</view>
<!--shape为button时只保留wd-checkbox__label-->
<view
@@ -22,7 +22,7 @@
:style="isChecked && innerShape === 'button' && !innerDisabled && innerCheckedColor ? 'color:' + innerCheckedColor : ''"
>
<!--button选中时展示的icon-->
<wd-icon v-if="innerShape === 'button' && isChecked" custom-class="wd-checkbox__btn-check" name="check-bold" size="14px" />
<wd-icon v-if="innerShape === 'button' && isChecked" custom-class="wd-checkbox__btn-check" name="check-bold" />
<!--文案-->
<view class="wd-checkbox__txt" :style="maxWidth ? 'max-width:' + maxWidth : ''">
<slot></slot>
@@ -43,10 +43,11 @@ export default {
</script>
<script lang="ts" setup>
import wdIcon from '../wd-icon/wd-icon.vue'
import { computed, getCurrentInstance, onBeforeMount, watch } from 'vue'
import { useParent } from '../composables/useParent'
import { CHECKBOX_GROUP_KEY } from '../wd-checkbox-group/types'
import { isDef } from '../common/util'
import { getPropByPath, isDef } from '../common/util'
import { checkboxProps, type CheckboxExpose } from './types'
const props = defineProps(checkboxProps)
@@ -90,67 +91,45 @@ watch(
() => props.shape,
(newValue) => {
const type = ['circle', 'square', 'button']
if (type.indexOf(newValue) === -1) console.error(`shape must be one of ${type.toString()}`)
if (isDef(newValue) && type.indexOf(newValue) === -1) console.error(`shape must be one of ${type.toString()}`)
}
)
const innerShape = computed(() => {
if (!props.shape && checkboxGroup && checkboxGroup.props.shape) {
return checkboxGroup.props.shape
} else {
return props.shape
}
return props.shape || getPropByPath(checkboxGroup, 'props.shape') || 'circle'
})
const innerCheckedColor = computed(() => {
if (!props.checkedColor && checkboxGroup && checkboxGroup.props.checkedColor) {
return checkboxGroup.props.checkedColor
} else {
return props.checkedColor
}
return props.checkedColor || getPropByPath(checkboxGroup, 'props.checkedColor')
})
const innerDisabled = computed(() => {
let innerDisabled = props.disabled
if (checkboxGroup) {
if (
// max group
(checkboxGroup.props.max && checkboxGroup.props.modelValue.length >= checkboxGroup.props.max && !isChecked.value) ||
// min group
(checkboxGroup.props.min && checkboxGroup.props.modelValue.length <= checkboxGroup.props.min && isChecked.value) ||
// disabled disabled
props.disabled === true ||
// disabled disabled
(checkboxGroup.props.disabled && props.disabled === null)
) {
innerDisabled = true
}
if (!checkboxGroup) {
return props.disabled
}
return innerDisabled
const { max, min, modelValue, disabled } = checkboxGroup.props
if (
(max && modelValue.length >= max && !isChecked.value) ||
(min && modelValue.length <= min && isChecked.value) ||
props.disabled === true ||
(disabled && props.disabled === null)
) {
return true
}
return props.disabled
})
const innerInline = computed(() => {
if (checkboxGroup && checkboxGroup.props.inline) {
return checkboxGroup.props.inline
} else {
return false
}
return getPropByPath(checkboxGroup, 'props.inline') || false
})
const innerCell = computed(() => {
if (checkboxGroup && checkboxGroup.props.cell) {
return checkboxGroup.props.cell
} else {
return false
}
return getPropByPath(checkboxGroup, 'props.cell') || false
})
const innerSize = computed(() => {
if (!props.size && checkboxGroup && checkboxGroup.props.size) {
return checkboxGroup.props.size
} else {
return props.size
}
return props.size || getPropByPath(checkboxGroup, 'props.size')
})
onBeforeMount(() => {
@@ -31,7 +31,9 @@ export default {
import { computed, getCurrentInstance, onBeforeMount, onMounted, onUnmounted, ref, watch } from 'vue'
import { addUnit, isObj, objToStyle, uuid } from '../common/util'
import { circleProps } from './types'
// #ifdef MP-WEIXIN
import { canvas2dAdapter } from '../common/canvasHelper'
// #endif
// 0100
function format(rate: number) {
@@ -25,6 +25,17 @@
}
}
@include e(list-item) {
@include when(disabled) {
color: $-dark-color3;
}
}
@include e(list-item-tip) {
color: $-dark-color-gray;
}
@include e(value) {
color: $-dark-color;
@@ -1,5 +1,5 @@
import type { ComponentPublicInstance, ExtractPropTypes, PropType } from 'vue'
import { baseProps, makeArrayProp, makeBooleanProp, makeNumberProp, makeRequiredProp, makeStringProp } from '../common/props'
import { baseProps, makeArrayProp, makeBooleanProp, makeNumberProp, makeRequiredProp, makeStringProp, numericProp } from '../common/props'
import type { FormItemRule } from '../wd-form/types'
export const colPickerProps = {
@@ -116,6 +116,14 @@ export const colPickerProps = {
* wd-form组件使用
*/
rules: makeArrayProp<FormItemRule>(),
/**
*
*/
lineWidth: numericProp,
/**
*
*/
lineHeight: numericProp,
/**
* label
*/
@@ -4,7 +4,7 @@
<slot v-if="useDefaultSlot"></slot>
<view
v-else
:class="`wd-col-picker__cell ${disabled && 'is-disabled'} ${readonly && 'is-readonly'} ${alignRight && 'is-align-right'} ${
:class="`wd-col-picker__cell ${disabled && 'is-disabled'} ${props.readonly && 'is-readonly'} ${alignRight && 'is-align-right'} ${
error && 'is-error'
} ${size && 'is-' + size}`"
>
@@ -38,19 +38,20 @@
:safe-area-inset-bottom="safeAreaInsetBottom"
@open="handlePickerOpend"
@close="handlePickerClose"
@closed="handlePickerClosed"
>
<view class="wd-col-picker__selected">
<scroll-view :scroll-x="true" scroll-with-animation :scroll-left="scrollLeft">
<view class="wd-col-picker__selected-container">
<view
v-for="(select, colIndex) in selectList"
v-for="(_, colIndex) in selectList"
:key="colIndex"
:class="`wd-col-picker__selected-item ${colIndex === currentCol && 'is-selected'}`"
@click="handleColClick(colIndex)"
>
{{ selectShowList[colIndex] || translate('select') }}
</view>
<view class="wd-col-picker__selected-line" :style="lineStyle"></view>
<view class="wd-col-picker__selected-line" :style="state.lineStyle"></view>
</view>
</scroll-view>
</view>
@@ -95,8 +96,11 @@ export default {
</script>
<script lang="ts" setup>
import { computed, getCurrentInstance, onMounted, ref, watch } from 'vue'
import { debounce, getRect, isArray, isBoolean, isFunction } from '../common/util'
import wdIcon from '../wd-icon/wd-icon.vue'
import wdLoading from '../wd-loading/wd-loading.vue'
import wdActionSheet from '../wd-action-sheet/wd-action-sheet.vue'
import { computed, getCurrentInstance, onMounted, ref, watch, type CSSProperties, reactive, nextTick } from 'vue'
import { addUnit, debounce, getRect, isArray, isBoolean, isDef, isFunction, objToStyle } from '../common/util'
import { useCell } from '../composables/useCell'
import { FORM_KEY, type FormItemRule } from '../wd-form/types'
import { useParent } from '../composables/useParent'
@@ -120,10 +124,14 @@ const loading = ref<boolean>(false)
const isChange = ref<boolean>(false)
const lastSelectList = ref<Record<string, any>[][]>([])
const lastPickerColSelected = ref<(string | number)[]>([])
const lineStyle = ref<string>('')
const scrollLeft = ref<number>(0)
const inited = ref<boolean>(false)
const isCompleting = ref<boolean>(false)
const state = reactive({
lineStyle: 'display:none;' // 线
})
const { proxy } = getCurrentInstance() as any
const cell = useCell()
@@ -275,7 +283,10 @@ function handlePickerOpend() {
function handlePickerClose() {
pickerShow.value = false
// popuppopup 250
emit('close')
}
function handlePickerClosed() {
if (isChange.value) {
setTimeout(() => {
selectList.value = lastSelectList.value.slice(0)
@@ -287,8 +298,8 @@ function handlePickerClose() {
isChange.value = false
}, 250)
}
emit('close')
}
function showPicker() {
const { disabled, readonly } = props
@@ -328,8 +339,14 @@ function chooseItem(colIndex: number, index: number) {
selectShowList.value = newPickerColSelected.map((item, colIndex) => {
return getSelectedItem(item, colIndex, selectList.value)[props.labelKey]
})
if (selectShowList.value[colIndex] && colIndex === currentCol.value) {
updateLineAndScroll(true)
}
handleColChange(colIndex, item, index)
}
function handleColChange(colIndex: number, item: Record<string, any>, index: number, callback?: () => void) {
loading.value = true
const { columnChange, beforeConfirm } = props
@@ -414,40 +431,47 @@ function handleColClick(index: number) {
* @description 更新navBar underline的偏移量
* @param {Boolean} animation 是否伴随动画
*/
function setLineStyle(animation = true) {
function setLineStyle(animation: boolean = true) {
if (!inited.value) return
getRect($item, true, proxy).then((rects) => {
const rect = rects[currentCol.value]
// const width = lineWidth || (slidableNum < items.length ? rect.width : (rect.width - 14))
const width = 16
let left = rects.slice(0, currentCol.value).reduce((prev: any, curr: any) => prev + curr.width, 0)
left += (Number(rect.width) - width) / 2
const transition = animation ? 'transition: width 300ms ease, transform 300ms ease;' : ''
const { lineWidth, lineHeight } = props
getRect($item, true, proxy)
.then((rects) => {
const lineStyle: CSSProperties = {}
if (isDef(lineWidth)) {
lineStyle.width = addUnit(lineWidth)
}
if (isDef(lineHeight)) {
lineStyle.height = addUnit(lineHeight)
lineStyle.borderRadius = `calc(${addUnit(lineHeight)} / 2)`
}
const rect = rects[currentCol.value]
let left = rects.slice(0, currentCol.value).reduce((prev, curr) => prev + Number(curr.width), 0) + Number(rect.width) / 2
lineStyle.transform = `translateX(${left}px) translateX(-50%)`
const lineStyleTemp = `
transform: translateX(${left}px);
${transition}
`
//
if (lineStyle.value !== lineStyleTemp) {
lineStyle.value = lineStyleTemp
}
})
if (animation) {
lineStyle.transition = 'width 300ms ease, transform 300ms ease'
}
state.lineStyle = objToStyle(lineStyle)
})
.catch(() => {})
}
/**
* @description scroll-view滑动到active的tab_nav
*/
function lineScrollIntoView() {
if (!inited.value) return
Promise.all([getRect($item, true, proxy), getRect($container, false, proxy)]).then(([navItemsRects, navRect]) => {
if (!isArray(navItemsRects) || navItemsRects.length === 0) return
//
const selectItem = navItemsRects[currentCol.value]
//
const offsetLeft = navItemsRects.slice(0, currentCol.value).reduce((prev, curr) => prev + Number(curr.width), 0)
// scroll-viewselectItem
scrollLeft.value = offsetLeft - ((navRect as any).width - Number(selectItem.width)) / 2
})
Promise.all([getRect($item, true, proxy), getRect($container, false, proxy)])
.then(([navItemsRects, navRect]) => {
if (!isArray(navItemsRects) || navItemsRects.length === 0) return
//
const selectItem = navItemsRects[currentCol.value]
//
const offsetLeft = navItemsRects.slice(0, currentCol.value).reduce((prev, curr) => prev + Number(curr.width), 0)
// scroll-viewselectItem
scrollLeft.value = offsetLeft - ((navRect as any).width - Number(selectItem.width)) / 2
})
.catch(() => {})
}
//
@@ -39,6 +39,14 @@
padding: $-collapse-header-padding;
overflow: hidden;
user-select: none;
@include when(expanded) {
@include halfPixelBorder('bottom');
}
@include when(custom) {
display: block;
}
}
@include e(title) {
@@ -60,7 +68,6 @@
@include e(wrapper) {
position: relative;
transition: height 0.3s ease-in-out;
overflow: hidden;
will-change: height;
}
@@ -1,14 +1,22 @@
import type { ComponentPublicInstance, ExtractPropTypes, PropType } from 'vue'
import { baseProps, makeBooleanProp, makeRequiredProp } from '../common/props'
import { baseProps, makeBooleanProp, makeRequiredProp, makeStringProp } from '../common/props'
export type CollapseItemBeforeExpand = (name: string) => void
export type CollapseItemBeforeExpand = (name: string) => boolean | Promise<unknown>
export const collapseItemProps = {
...baseProps,
/**
*
*
*/
title: String,
customBodyClass: makeStringProp(''),
/**
*
*/
customBodyStyle: makeStringProp(''),
/**
* , slot
*/
title: makeStringProp(''),
/**
*
*/
@@ -31,6 +39,10 @@ export type CollapseItemExpose = {
* @returns boolean
*/
getExpanded: () => boolean
/**
*
*/
updateExpand: () => Promise<void>
}
export type CollapseItemInstance = ComponentPublicInstance<CollapseItemProps, CollapseItemExpose>
@@ -1,11 +1,18 @@
<template>
<view :class="`wd-collapse-item ${disabled ? 'is-disabled' : ''} is-border ${customClass}`" :style="customStyle">
<view :class="`wd-collapse-item__header ${isFirst ? 'wd-collapse-item__header-first' : ''}`" @click="handleClick">
<text class="wd-collapse-item__title">{{ title }}</text>
<wd-icon name="arrow-down" :custom-class="`wd-collapse-item__arrow ${expanded ? 'is-retract' : ''}`" />
<view
:class="`wd-collapse-item__header ${expanded ? 'is-expanded' : ''} ${isFirst ? 'wd-collapse-item__header-first' : ''} ${
$slots.title ? 'is-custom' : ''
}`"
@click="handleClick"
>
<slot name="title" :expanded="expanded" :disabled="disabled" :isFirst="isFirst">
<text class="wd-collapse-item__title">{{ title }}</text>
<wd-icon name="arrow-down" :custom-class="`wd-collapse-item__arrow ${expanded ? 'is-retract' : ''}`" />
</slot>
</view>
<view class="wd-collapse-item__wrapper" :style="contentStyle">
<view class="wd-collapse-item__body">
<view class="wd-collapse-item__wrapper" :style="contentStyle" @transitionend="handleTransitionEnd">
<view class="wd-collapse-item__body" :class="customBodyClass" :style="customBodyStyle" :id="collapseId">
<slot />
</view>
</view>
@@ -23,23 +30,22 @@ export default {
</script>
<script lang="ts" setup>
import { computed, getCurrentInstance, onMounted, ref, watch } from 'vue'
import { getRect, isArray, isDef, isPromise, objToStyle } from '../common/util'
import wdIcon from '../wd-icon/wd-icon.vue'
import { computed, getCurrentInstance, onMounted, ref, watch, type CSSProperties } from 'vue'
import { addUnit, getRect, isArray, isDef, isPromise, isString, objToStyle, pause, uuid } from '../common/util'
import { useParent } from '../composables/useParent'
import { COLLAPSE_KEY } from '../wd-collapse/types'
import { collapseItemProps, type CollapseItemExpose } from './types'
const $body = '.wd-collapse-item__body'
const collapseId = ref<string>(`collapseId${uuid()}`)
const props = defineProps(collapseItemProps)
const { parent: collapse, index } = useParent(COLLAPSE_KEY)
const height = ref<string | number>('')
const inited = ref<boolean>(false)
const expanded = ref<boolean>(false)
const transD = ref<string>('0.3s')
const { proxy } = getCurrentInstance() as any
/**
@@ -53,100 +59,111 @@ const isFirst = computed(() => {
* 容器样式(动画)
*/
const contentStyle = computed(() => {
let style: Record<string, string> = {
height: expanded.value ? height.value + 'px' : '0px',
'transition-duration': transD.value
const style: CSSProperties = {}
if (inited.value) {
style.transition = 'height 0.3s ease-in-out'
}
if (!expanded.value) {
style.height = '0px'
} else if (height.value) {
style.height = addUnit(height.value)
}
return objToStyle(style)
})
const selected = computed(() => {
if (collapse) {
return collapse.props.modelValue
} else {
return []
}
/**
* 是否选中
*/
const isSelected = computed(() => {
const modelValue = collapse ? collapse?.props.modelValue || [] : []
const { name } = props
return (isString(modelValue) && modelValue === name) || (isArray(modelValue) && modelValue.indexOf(name as string) >= 0)
})
watch(
() => selected.value,
() => isSelected.value,
(newVal) => {
const name = props.name
if (isDef(newVal)) {
if (typeof newVal === 'string' && newVal === name) {
doResetHeight($body)
expanded.value = true
} else if (isArray(newVal) && newVal.indexOf(name as string) >= 0) {
doResetHeight($body)
expanded.value = true
} else {
expanded.value = false
}
} else {
expanded.value = false
}
},
{
deep: true,
immediate: true
updateExpand(newVal)
}
)
onMounted(() => {
init()
updateExpand(isSelected.value)
})
/**
* 初始化将组件信息注入父组件
*/
function init() {
doResetHeight($body)
async function updateExpand(useBeforeExpand: boolean = true) {
try {
if (useBeforeExpand) {
await handleBeforeExpand()
}
initRect()
} catch (error) {
/* empty */
}
}
/**
* 控制折叠面板滚动
* @param {String} select 选择器名称
* @param {Boolean} firstRender 是否首次渲染
*/
function doResetHeight(select: string) {
getRect(select, false, proxy).then((rect) => {
if (!rect) return
function initRect() {
getRect(`#${collapseId.value}`, false, proxy).then(async (rect) => {
const { height: rectHeight } = rect
height.value = Number(rectHeight)
height.value = isDef(rectHeight) ? Number(rectHeight) : ''
await pause()
if (isSelected.value) {
expanded.value = true
} else {
expanded.value = false
}
if (!inited.value) {
inited.value = true
}
})
}
function handleTransitionEnd() {
if (expanded.value) {
height.value = ''
}
}
//
function handleClick() {
async function handleClick() {
if (props.disabled) return
let name = props.name
const nexexpanded = !expanded.value //
if (nexexpanded) {
if (props.beforeExpend) {
const response: any = props.beforeExpend(name)
try {
await updateExpand()
const { name } = props
collapse && collapse.toggle(name, !expanded.value)
} catch (error) {
/* empty */
}
}
/**
* 展开前钩子
*/
function handleBeforeExpand() {
return new Promise<void>((resolve, reject) => {
const { name } = props
const nextexpanded = !expanded.value
if (nextexpanded && props.beforeExpend) {
const response = props.beforeExpend(name)
if (!response) {
return
reject()
}
if (isPromise(response)) {
response.then(() => {
collapse && collapse.toggle(name, !expanded.value)
})
response.then(() => resolve()).catch(reject)
} else {
collapse && collapse.toggle(name, !expanded.value)
resolve()
}
} else {
collapse && collapse.toggle(name, !expanded.value)
resolve()
}
} else {
collapse && collapse.toggle(name, !expanded.value)
}
})
}
function getExpanded() {
return expanded.value
}
defineExpose<CollapseItemExpose>({ getExpanded })
defineExpose<CollapseItemExpose>({ getExpanded, updateExpand })
</script>
<style lang="scss" scoped>
@@ -52,7 +52,7 @@ export type CollapseExpose = {
* true false
* @param options
*/
toggleAll: (options?: boolean | CollapseToggleAllOptions) => void
toggleAll: (options?: CollapseToggleAllOptions) => void
}
export type CollapseInstance = ComponentPublicInstance<CollapseProps, CollapseExpose>
@@ -41,10 +41,11 @@ export default {
</script>
<script lang="ts" setup>
import wdIcon from '../wd-icon/wd-icon.vue'
import { onBeforeMount, ref, watch } from 'vue'
import { COLLAPSE_KEY, collapseProps, type CollapseExpose, type CollapseToggleAllOptions } from './types'
import { useChildren } from '../composables/useChildren'
import { isArray, isDef } from '../common/util'
import { isArray, isBoolean, isDef } from '../common/util'
import { useTranslate } from '../composables/useTranslate'
const props = defineProps(collapseProps)
@@ -68,7 +69,7 @@ watch(
console.error('value must be Array')
}
},
{ deep: true, immediate: true }
{ deep: true }
)
watch(
@@ -108,26 +109,23 @@ function toggle(name: string, expanded: boolean) {
* 切换所有面板展开状态 true 为全部展开false 为全部收起不传参为全部切换
* @param options 面板状态
*/
const toggleAll = (options: boolean | CollapseToggleAllOptions = {}) => {
const toggleAll = (options: CollapseToggleAllOptions = {}) => {
if (props.accordion) {
return
}
if (typeof options === 'boolean') {
if (isBoolean(options)) {
options = { expanded: options }
}
const { expanded, skipDisabled } = options
const names: string[] = []
children.forEach((item, index: number) => {
children.forEach((item, index) => {
if (item.disabled && skipDisabled) {
if (item.$.exposed!.getExpanded()) {
names.push(item.name || index)
}
} else {
if (isDef(expanded) ? expanded : !item.$.exposed!.getExpanded()) {
names.push(item.name || index)
}
} else if (isDef(expanded) ? expanded : !item.$.exposed!.getExpanded()) {
names.push(item.name || index)
}
})
updateChange(names)
@@ -1,9 +1,10 @@
import type { ExtractPropTypes, PropType } from 'vue'
import { makeStringProp } from '../common/props'
import { makeStringProp, baseProps } from '../common/props'
export type ConfigProviderTheme = 'light' | 'dark'
export const configProviderProps = {
...baseProps,
/**
* dark
*/
@@ -83,6 +84,7 @@ export type baseThemeVars = {
export type actionSheetThemeVars = {
actionSheetWeight?: string
actionSheetRadius?: string
actionSheetLoadingSize?: string
actionSheetActionHeight?: string
actionSheetColor?: string
actionSheetFs?: string
@@ -123,74 +125,55 @@ export type badgeThemeVars = {
export type buttonThemeVars = {
buttonDisabledOpacity?: string
buttonSmallHeight?: string
buttonSmallPadding?: string
buttonSmallFs?: string
buttonSmallRadius?: string
buttonSmallLoading?: string
buttonMediumHeight?: string
buttonMediumPadding?: string
buttonMediumFs?: string
buttonMediumRadius?: string
buttonMediumLoading?: string
buttonMediumBoxShadowSize?: string
buttonLargeHeight?: string
buttonLargePadding?: string
buttonLargeFs?: string
buttonLargeRadius?: string
buttonLargeLoading?: string
buttonLargeBoxShadowSize?: string
buttonIconFs?: string
buttonIconSize?: string
buttonIconColor?: string
buttonIconDisabledColor?: string
buttonNormalColor?: string
buttonNormalDisabledColor?: string
buttonPlainBgColor?: string
buttonPrimaryColor?: string
buttonPrimaryBgColor?: string
buttonPrimaryBoxShadowColor?: string
buttonSuccessColor?: string
buttonSuccessBgColor?: string
buttonSuccessBoxShadowColor?: string
buttonInfoColor?: string
buttonInfoBgColor?: string
buttonInfoPlainBorderColor?: string
buttonInfoPlainNormalColor?: string
buttonWarningColor?: string
buttonWarningBgColor?: string
buttonWarningBoxShadowColor?: string
buttonErrorColor?: string
buttonErrorBgColor?: string
buttonErrorBoxShadowColor?: string
buttonTextHoverOpacity?: string
}
export type cellThemeVars = {
cellPadding?: string
cellLineHeight?: string
cellGroupTitleFs?: string
cellGroupPadding?: string
cellGroupTitleColor?: string
cellGroupValueFs?: string
cellGroupValueColor?: string
cellWrapperPadding?: string
cellWrapperPaddingLarge?: string
cellWrapperPaddingWithLabel?: string
cellIconRight?: string
cellIconSize?: string
@@ -202,12 +185,11 @@ export type cellThemeVars = {
cellValueColor?: string
cellArrowSize?: string
cellArrowColor?: string
cellClearColor?: string
cellTapBg?: string
cellTitleFsLarge?: string
cellLabelFsLarge?: string
cellIconSizeLarge?: string
cellRequiredColor?: string
cellRequiredSize?: string
cellVerticalTop?: string
@@ -227,10 +209,12 @@ export type calendarThemeVars = {
calendarDayHeight?: string
calendarMonthWidth?: string
calendarActiveColor?: string
calendarSelectedColor?: string
calendarDisabledColor?: string
calendarRangeColor?: string
calendarActiveBorder?: string
calendarInfoFs?: string
calendarItemMarginBottom?: string
}
export type checkboxThemeVars = {
@@ -244,16 +228,13 @@ export type checkboxThemeVars = {
checkboxLabelFs?: string
checkboxLabelColor?: string
checkboxCheckedColor?: string
checkboxDisabledColor?: string
checkboxDisabledLabelColor?: string
checkboxDisabledCheckColor?: string
checkboxDisabledCheckBg?: string
checkboxSquareRadius?: string
checkboxLargeSize?: string
checkboxLargeLabelFs?: string
checkboxButtonHeight?: string
checkboxButtonMinWidth?: string
checkboxButtonRadius?: string
@@ -280,15 +261,25 @@ export type collapseThemeVars = {
export type dividerThemeVars = {
dividerPadding?: string
dividerMargin?: string
dividerColor?: string
dividerLineColor?: string
dividerLineHeight?: string
dividerFs?: string
dividerContentLeftWidth?: string
dividerContentLeftMargin?: string
dividerContentRightMargin?: string
dividerContentRightWidth?: string
dividerVerticalHeight?: string
dividerVerticalContentMargin?: string
dividerVerticalLineWidth?: string
}
export type dropMenuThemeVars = {
dropMenuHeight?: string
dropMenuColor?: string
dropMenuFs?: string
dropMenuArrowFs?: string
dropMenuSidePadding?: string
dropMenuDisabledColor?: string
dropMenuItemHeight?: string
@@ -331,7 +322,6 @@ export type inputThemeVars = {
inputCountColor?: string
inputCountCurrentColor?: string
inputBg?: string
inputCellBg?: string
inputCellBorderColor?: string
inputCellPadding?: string
@@ -359,7 +349,6 @@ export type textareaThemeVars = {
textareaCountColor?: string
textareaCountCurrentColor?: string
textareaBg?: string
textareaCellBorderColor?: string
textareaCellPadding?: string
textareaCellPaddingLarge?: string
@@ -375,6 +364,8 @@ export type loadmoreThemeVars = {
loadmoreColor?: string
loadmoreFs?: string
loadmoreErrorColor?: string
loadmoreRefreshFs?: string
loadmoreLoadingSize?: string
}
export type messageBoxThemeVars = {
@@ -423,6 +414,7 @@ export type paginationThemeVars = {
paginationNavContentFs?: string
paginationNavSepatatorPadding?: string
paginationNavCurrentColor?: string
paginationIconSize?: string
}
export type pickerThemeVars = {
@@ -441,16 +433,13 @@ export type pickerThemeVars = {
pickerColumnSelectBg?: string
pickerLoadingButtonColor?: string
pickerColumnPadding?: string
pickerColumnDisabledColor?: string
pickerMask?: string
pickerLoadingBg?: string
pickerRegionSeparatorColor?: string
pickerCellArrowSizeLarge?: string
pickerRegionColor?: string
pickerRegionBgActiveColor?: string
pickerRegionFs?: string
}
@@ -491,9 +480,8 @@ export type progressThemeVars = {
progressBg?: string
progressDangerColor?: string
progressSuccessColor?: string
progressWarningColor?: string
progressColor?: string
progressLinearSuccessColor?: string
progressLinearDangerColor?: string
progressHeight?: string
progressLabelColor?: string
progressLabelFs?: string
@@ -510,10 +498,8 @@ export type radioThemeVars = {
radioCheckedColor?: string
radioDisabledColor?: string
radioDisabledLabelColor?: string
radioLargeSize?: string
radioLargeLabelFs?: string
radioButtonHeight?: string
radioButtonMinWidth?: string
radioButtonMaxWidth?: string
@@ -522,7 +508,6 @@ export type radioThemeVars = {
radioButtonFs?: string
radioButtonBorder?: string
radioButtonDisabledBorder?: string
radioDotSize?: string
radioDotLargeSize?: string
radioDotCheckedBg?: string
@@ -542,6 +527,8 @@ export type searchThemeVars = {
searchInputFs?: string
searchInputColor?: string
searchIconColor?: string
searchIconSize?: string
searchClearIconSize?: string
searchPlaceholderColor?: string
searchCancelPadding?: string
searchCancelFs?: string
@@ -607,6 +594,7 @@ export type tabsThemeVars = {
tabsNavActiveColor?: string
tabsNavDisabledColor?: string
tabsNavLineHeight?: string
tabsNavLineWidth?: string
tabsNavLineBgColor?: string
tabsNavMapFs?: string
tabsNavMapColor?: string
@@ -648,10 +636,16 @@ export type toastThemeVars = {
toastFs?: string
toastWithIconMinWidth?: string
toastIconSize?: string
toastIconMarginRight?: string
toastIconMarginBottom?: string
toastLoadingPadding?: string
toastBoxShadow?: string
}
export type loadingThemeVars = {
loadingSize?: string
}
export type tooltipThemeVars = {
tooltipBg?: string
tooltipColor?: string
@@ -723,10 +717,13 @@ export type uploadThemeVars = {
uploadCloseIconSize?: string
uploadCloseIconColor?: string
uploadProgressFs?: string
uploadFileFs?: string
uploadFileColor?: string
uploadPreviewNameFs?: string
uploadPreviewIconSize?: string
uploadPreviewNameBg?: string
uploadPreviewNameHeight?: string
uploadCoverIconSize?: string
}
export type curtainThemeVars = {
@@ -766,20 +763,19 @@ export type circleThemeVars = {
export type swiperThemeVars = {
swiperRadius?: string
swiperItemPadding?: string
swiperItemTextColor?: string
swiperItemTextFs?: string
}
export type swiperNavThemeVars = {
// dot & dots-bar
swiperNavDotColor?: string
swiperNavDotActiveColor?: string
swiperNavDotSize?: string
swiperNavDotsBarActiveWidth?: string
// fraction
swiperNavFractionColor?: string
swiperNavFractionBgColor?: string
swiperNavFractionHeight?: string
swiperNavFractionFontSize?: string
// button
swiperNavBtnColor?: string
swiperNavBtnBgColor?: string
swiperNavBtnSize?: string
@@ -803,6 +799,7 @@ export type tabbarItemThemeVars = {
tabbarItemTitleLineHeight?: string
tabbarInactiveColor?: string
tabbarActiveColor?: string
tabbarItemIconSize?: string
}
export type navbarThemeVars = {
@@ -823,6 +820,7 @@ export type navbarCapsuleThemeVars = {
navbarCapsuleBorderRadius?: string
navbarCapsuleWidth?: string
navbarCapsuleHeight?: string
navbarCapsuleIconSize?: string
}
export type tableThemeVars = {
@@ -858,10 +856,7 @@ export type fabThemeVars = {
fabTriggerHeight?: string
fabTriggerWidth?: string
fabActionsPadding?: string
fabTop?: string
fabLeft?: string
fabRight?: string
fabBottom?: string
fabIconFs?: string
}
export type countDownThemeVars = {
@@ -870,6 +865,26 @@ export type countDownThemeVars = {
countDownLineHeight?: string
}
export type keyboardThemeVars = {
keyboardKeyHeight?: string
keyboardKeyFontSize?: string
keyboardKeyBackground?: string
keyboardKeyBorderRadius?: string
keyboardDeleteFontSize?: string
keyboardKeyActiveColor?: string
keyboardButtonTextColor?: string
keyboardButtonBackground?: string
keyboardButtonActiveOpacity?: string
keyboardBackground?: string
keyboardTitleHeight?: string
keyboardTitleColor?: string
keyboardTitleFontSize?: string
keyboardClosePadding?: string
keyboardCloseColor?: string
keyboardCloseFontSize?: string
keyboardIconSize?: string
}
export type numberKeyboardThemeVars = {
numberKeyboardKeyHeight?: string
numberKeyboardKeyFontSize?: string
@@ -887,6 +902,7 @@ export type numberKeyboardThemeVars = {
numberKeyboardClosePadding?: string
numberKeyboardCloseColor?: string
numberKeyboardCloseFontSize?: string
numberKeyboardIconSize?: string
}
export type passwodInputThemeVars = {
@@ -914,6 +930,54 @@ export type formItemThemeVars = {
formItemErrorMessageLineHeight?: string
}
export type backtopThemeVars = {
backtopBg?: string
backtopIconSize?: string
}
export type indexBarThemeVars = {
indexBarIndexFontSize?: string
}
export type textThemeVars = {
textInfoColor?: string
textPrimaryColor?: string
textErrorColor?: string
textWarningColor?: string
textSuccessColor?: string
}
export type videoPreviewThemeVars = {
videoPreviewBg?: string
videoPreviewCloseColor?: string
videoPreviewCloseFontSize?: string
}
export type imgCropperThemeVars = {
imgCropperIconSize?: string
imgCropperIconColor?: string
}
export type floatingPanelThemeVars = {
floatingPanelBg?: string
floatingPanelRadius?: string
floatingPanelZIndex?: string
floatingPanelHeaderHeight?: string
floatingPanelBarWidth?: string
floatingPanelBarHeight?: string
floatingPanelBarBg?: string
floatingPanelBarRadius?: string
floatingPanelContentBg?: string
}
export type signatureThemeVars = {
signatureBg?: string
signatureRadius?: string
signatureBorder?: string
signatureFooterMarginTop?: string
signatureButtonMarginLeft?: string
}
export type ConfigProviderThemeVars = baseThemeVars &
actionSheetThemeVars &
badgeThemeVars &
@@ -945,6 +1009,7 @@ export type ConfigProviderThemeVars = baseThemeVars &
tabsThemeVars &
tagThemeVars &
toastThemeVars &
loadingThemeVars &
tooltipThemeVars &
popoverThemeVars &
gridItemThemeVars &
@@ -967,6 +1032,14 @@ export type ConfigProviderThemeVars = baseThemeVars &
sidebarItemThemeVars &
fabThemeVars &
countDownThemeVars &
keyboardThemeVars &
numberKeyboardThemeVars &
passwodInputThemeVars &
formItemThemeVars
formItemThemeVars &
backtopThemeVars &
indexBarThemeVars &
textThemeVars &
videoPreviewThemeVars &
imgCropperThemeVars &
floatingPanelThemeVars &
signatureThemeVars
@@ -27,15 +27,17 @@ export default {
<script lang="ts" setup>
import { computed } from 'vue'
import { configProviderProps } from './types'
import { objToStyle } from '../common/util'
const props = defineProps(configProviderProps)
const themeClass = computed(() => {
return `wot-theme-${props.theme}`
return `wot-theme-${props.theme} ${props.customClass}`
})
const themeStyle = computed(() => {
return mapThemeVarsToCSSVars(props.themeVars)
const styleObj = mapThemeVarsToCSSVars(props.themeVars)
return styleObj ? `${objToStyle(styleObj)};${props.customStyle}` : props.customStyle
})
const kebabCase = (str: string): string => {
@@ -50,7 +50,3 @@ export function parseFormat(format: string, timeData: TimeData): string {
return format
}
export function isSameSecond(time1: number, time2: number): boolean {
return Math.floor(time1 / 1000) === Math.floor(time2 / 1000)
}
@@ -17,7 +17,7 @@ export default {
</script>
<script setup lang="ts">
import { watch, computed } from 'vue'
import { watch, computed, onMounted } from 'vue'
import { parseFormat } from './utils'
import { useCountDown } from '../composables/useCountDown'
import { countDownProps, type CountDownExpose } from './types'
@@ -37,13 +37,16 @@ const timeText = computed(() => parseFormat(props.format, current.value))
const resetTime = () => {
reset(props.time)
if (props.autoStart) {
start()
}
}
watch(() => props.time, resetTime, { immediate: true })
watch(() => props.time, resetTime, { immediate: false })
onMounted(() => {
resetTime()
})
defineExpose<CountDownExpose>({
start,
@@ -0,0 +1,7 @@
@import '../common/abstracts/variable';
@import '../common/abstracts/mixin';
.wd-count-to{
vertical-align: bottom;
}
@@ -0,0 +1,117 @@
import type { ComponentPublicInstance, ExtractPropTypes } from 'vue'
import { baseProps, makeBooleanProp, makeNumberProp, makeStringProp } from '../common/props'
import type { TextType } from '../wd-text/types'
export const countToProps = {
...baseProps,
// 字体大小
fontSize: makeNumberProp(16),
// 文本颜色
color: makeStringProp(''),
/**
*
* string
* 'default' /'primary' / 'error' / 'warning' / 'success'
* 'default'
*/
type: makeStringProp<TextType>('default'),
/**
*
* number
* 0
*/
startVal: makeNumberProp(0),
/**
*
* number
* 2021
*/
endVal: makeNumberProp(2024),
/**
*
* number
* 3000
*/
duration: makeNumberProp(3000),
/**
*
* boolean
* true
*/
autoStart: makeBooleanProp(true),
/**
*
* number
* 0
* 0
*/
decimals: {
type: Number,
required: false,
default: 0,
validator(value: number) {
return value >= 0
}
},
// 小数点
decimal: makeStringProp('.'),
// 三位三位的隔开效果
separator: makeStringProp(','),
/**
*
* string
* ''
* @example '¥'
*/
prefix: makeStringProp(''),
/**
*
* string
* ''
*/
suffix: makeStringProp(''),
/**
*
* boolean
* true
*/
useEasing: makeBooleanProp(true),
/**
*
*/
customStyle: makeStringProp(''),
/**
*
*/
customClass: makeStringProp('')
}
export type CountDownProps = ExtractPropTypes<typeof countToProps>
export type CountUpExpose = {
/**
*
*/
start: () => void
/**
*
*/
pause: () => void
/**
* auto-start true
*/
reset: () => void
}
export type CountToInstance = ComponentPublicInstance<CountDownProps, CountUpExpose>
@@ -0,0 +1,125 @@
<template>
<view :class="rootClass">
<!-- 前缀插槽 -->
<slot name="prefix">
<wd-text :type="props.type" :color="props.color" :size="`${props.fontSize * 0.7}px`" :text="props.prefix"></wd-text>
</slot>
<!-- 默认文本插槽 -->
<slot>
<wd-text :type="props.type" :color="props.color" :size="`${props.fontSize}px`" :text="timeText"></wd-text>
</slot>
<!-- 后缀插槽 -->
<slot name="suffix">
<wd-text :type="props.type" :color="props.color" :size="`${props.fontSize * 0.7}px`" :text="props.suffix"></wd-text>
</slot>
</view>
</template>
<script lang="ts">
export default {
name: 'wd-count-to',
options: {
virtualHost: true,
addGlobalClass: true,
styleIsolation: 'shared'
}
}
</script>
<script lang="ts" setup>
import wdText from '../wd-text/wd-text.vue'
import { computed, watch, onMounted } from 'vue'
import { countToProps } from './types'
import { easingFn, isNumber } from '../common/util'
import { useCountDown } from '../composables/useCountDown'
import type { CountDownExpose } from '../wd-count-down/types'
const props = defineProps(countToProps)
const emit = defineEmits(['mounted', 'finish'])
const { start, pause, reset, current } = useCountDown({
time: props.duration,
millisecond: true,
onFinish: () => emit('finish')
})
//
const rootClass = computed(() => {
return `wd-count-to ${props.customClass}`
})
const timeText = computed(() => {
return parseFormat(current.value.total)
})
watch([() => props.startVal, () => props.endVal, () => props.duration], resetTime, { immediate: false })
onMounted(() => {
resetTime()
emit('mounted')
})
//
function resetTime() {
reset(props.duration)
if (props.autoStart) {
start()
}
}
function parseFormat(remain: number) {
const { startVal, endVal, duration, useEasing } = props
const progress = duration - remain //
const isPositive = startVal > endVal // startValendVal
const progressRatio = progress / duration //
let currentVal: number
if (useEasing) {
// 使currentVal
if (isPositive) {
currentVal = startVal - easingFn(progress, 0, startVal - endVal, duration) || 0
} else {
currentVal = easingFn(progress, startVal, endVal - startVal, duration)
}
} else {
// 使
if (isPositive) {
currentVal = startVal - (startVal - endVal) * progressRatio
} else {
currentVal = startVal + (endVal - startVal) * progressRatio
}
}
// currentValstartValendVal
currentVal = isPositive ? Math.max(endVal, currentVal) : Math.min(endVal, currentVal)
return formatNumber(currentVal)
}
//
function formatNumber(num: any): string {
if (typeof num !== 'number') {
num = parseFloat(num)
if (isNaN(num)) {
return '0'
}
}
num = num.toFixed(props.decimals)
const parts = num.split('.')
let integerPart = parts[0]
const decimalPart = parts.length > 1 ? props.decimal + parts[1] : ''
const rgx = /(\d+)(\d{3})/
if (props.separator && !isNumber(props.separator)) {
while (rgx.test(integerPart)) {
integerPart = integerPart.replace(rgx, '$1' + props.separator + '$2')
}
}
return integerPart + decimalPart
}
defineExpose<CountDownExpose>({ start, reset: resetTime, pause })
</script>
<style lang="scss" scoped>
@import './index.scss';
</style>
@@ -1,14 +1,18 @@
@import "./../common/abstracts/_mixin.scss";
@import "./../common/abstracts/variable.scss";
:deep(.wd-curtain){
display: inline-block;
border-radius: $-curtain-content-radius;
overflow-y: visible;
background: transparent;
font-size: 0;
@include b(curtain-wrapper){
:deep(.wd-curtain){
display: inline-block;
border-radius: $-curtain-content-radius;
overflow-y: visible !important;
background: transparent;
font-size: 0;
}
}
@include bdeep(curtain) {
@include b(curtain) {
@include e(content) {
position: relative;
@@ -33,6 +37,7 @@
top: 10px;
right: 10px;
color: $-curtain-content-close-color;
font-size: $-curtain-content-close-fs;
-webkit-tap-highlight-color: transparent;
&.top {
margin: 0 0 0 -18px;
@@ -1,5 +1,14 @@
/*
* @Author: weisheng
* @Date: 2025-01-25 23:46:29
* @LastEditTime: 2025-02-13 13:16:45
* @LastEditors: weisheng
* @Description:
* @FilePath: /wot-design-uni/src/uni_modules/wot-design-uni/components/wd-curtain/types.ts
*
*/
import type { ExtractPropTypes } from 'vue'
import { baseProps, makeBooleanProp, makeStringProp } from '../common/props'
import { baseProps, makeBooleanProp, makeNumberProp, makeStringProp } from '../common/props'
export type ClosePosition = 'inset' | 'top' | 'bottom' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
@@ -7,8 +16,13 @@ export const curtainProps = {
...baseProps,
/**
* /
* @deprecated 使 modelValue
*/
value: makeBooleanProp(false),
/**
* /
*/
modelValue: makeBooleanProp(false),
/**
* inset / top / bottom / top-left / top-right / bottom-left / bottom-right
*/
@@ -32,7 +46,25 @@ export const curtainProps = {
/**
* display: none)
*/
hideWhenClose: makeBooleanProp(true)
hideWhenClose: makeBooleanProp(true),
/**
*
* number
* 10
*/
zIndex: makeNumberProp(10),
/**
*
* string
* ''
*/
customCloseClass: makeStringProp(''),
/**
*
* string
* ''
*/
customCloseStyle: makeStringProp('')
}
export type CurtainProps = ExtractPropTypes<typeof curtainProps>
@@ -1,11 +1,12 @@
<template>
<view>
<view class="wd-curtain-wrapper">
<wd-popup
v-model="show"
v-model="modelValue"
transition="zoom-in"
position="center"
:close-on-click-modal="closeOnClickModal"
:hide-when-close="hideWhenClose"
:z-index="zIndex"
@before-enter="beforeenter"
@enter="enter"
@after-enter="afterenter"
@@ -19,7 +20,14 @@
>
<view class="wd-curtain__content">
<image :src="src" class="wd-curtain__content-img" :style="imgStyle" @click="clickImage" @error="imgErr" @load="imgLoad"></image>
<wd-icon name="close-outline" size="24px" :custom-class="`wd-curtain__content-close ${closePosition}`" @click="close" />
<slot name="close">
<wd-icon
name="close-outline"
:custom-class="`wd-curtain__content-close ${closePosition} ${customCloseClass}`"
:custom-style="customCloseStyle"
@click="close"
/>
</slot>
</view>
</wd-popup>
</view>
@@ -37,11 +45,12 @@ export default {
</script>
<script lang="ts" setup>
import { ref, watch } from 'vue'
import wdIcon from '../wd-icon/wd-icon.vue'
import wdPopup from '../wd-popup/wd-popup.vue'
import { computed, ref, watch } from 'vue'
import { curtainProps } from './types'
const props = defineProps(curtainProps)
const emit = defineEmits([
'beforeenter',
'enter',
@@ -54,53 +63,41 @@ const emit = defineEmits([
'click-modal',
'load',
'error',
'click'
'click',
'update:modelValue'
])
const show = ref<boolean>(false)
const imgSucc = ref<boolean>(true)
const imgStyle = ref<string>('')
const imgScale = ref<number>(1)
const modelValue = ref(props.modelValue || props.value)
watch(
() => props.modelValue,
(newVal) => {
modelValue.value = newVal
}
)
watch(
() => props.value,
() => {
computedShowImg()
},
{
deep: true,
immediate: true
(newVal) => {
modelValue.value = newVal
}
)
watch(
() => props.width,
() => {
computeImgStyle()
},
{
deep: true,
immediate: true
}
)
watch(modelValue, (newVal) => {
emit('update:modelValue', newVal)
})
function computedShowImg() {
if (props.value && imgSucc.value) {
show.value = true
} else {
show.value = false
close()
}
}
const imgSucc = ref<boolean>(true)
const imgScale = ref<number>(1)
function computeImgStyle() {
const imgStyle = computed(() => {
let style = ''
if (props.width) {
style += `width: ${props.width}px ;`
style += `height: ${props.width / imgScale.value}px`
}
imgStyle.value = style
}
return style
})
function beforeenter() {
emit('beforeenter')
@@ -127,7 +124,7 @@ function afterleave() {
}
function close() {
show.value = false
modelValue.value = false
emit('close')
}
@@ -139,7 +136,6 @@ function imgLoad(event: any) {
const { height, width } = event.detail
imgScale.value = width / height
imgSucc.value = true
computeImgStyle()
emit('load')
}
function imgErr() {
@@ -31,7 +31,7 @@ export const datetimePickerViewProps = {
/**
* type time
*/
modelValue: makeRequiredProp([String, Number, Date]),
modelValue: makeRequiredProp([String, Number]),
/**
*
*/
@@ -86,6 +86,10 @@ export const datetimePickerViewProps = {
* time类型时生效
*/
maxMinute: makeNumberProp(59),
/**
* picker-view的 change change 1.2.25
*/
immediateChange: makeBooleanProp(false),
startSymbol: makeBooleanProp(false)
}
@@ -1,9 +1,10 @@
<template>
<view>
<wd-picker-view
ref="datePickerview"
:custom-class="customClass"
:custom-style="customStyle"
ref="datePickerview"
:immediate-change="immediateChange"
v-model="pickerValue"
:columns="columns"
:columns-height="columnsHeight"
@@ -26,6 +27,7 @@ export default {
</script>
<script lang="ts" setup>
import wdPickerView from '../wd-picker-view/wd-picker-view.vue'
import { getCurrentInstance, onBeforeMount, ref, watch } from 'vue'
import { debounce, isFunction, isDef, padZero, range, isArray } from '../common/util'
import {
@@ -208,7 +210,6 @@ function onChange({ value }: { value: string | string[] }) {
*/
function updateColumns(): DatetimePickerViewOption[][] {
const { formatter, columnFormatter } = props
if (columnFormatter) {
return columnFormatter(proxy.$.exposed)
} else {
@@ -464,19 +465,18 @@ function columnChange(picker: PickerViewInstance) {
//
innerValue.value = correctValue(value)
// innerValue
const newColumns = updateColumns().slice(0, 3)
const newColumns = updateColumns()
//
const selectedIndex = picker.getSelectedIndex().slice(0)
/**
* 选中年会修改对应的年份的月数和月份对应的日期
* 选中月会修改月份对应的日数
*/
newColumns.forEach((_columns, index) => {
const nextColumnIndex = index + 1
const nextColumnData = newColumns[nextColumnIndex]
// ``
if (index === 2) return
if (nextColumnIndex > newColumns.length - 1) return
picker.setColumnData(
nextColumnIndex,
nextColumnData,
@@ -8,6 +8,10 @@
color: $-dark-color;
}
@include e(title) {
color: $-dark-color;
}
@include e(label) {
color: $-dark-color;
}
@@ -90,7 +90,7 @@ export const datetimePickerProps = {
/**
* type time type Array
*/
modelValue: makeRequiredProp([String, Number, Date, Array] as PropType<string | number | Date | Array<string | number | Date>>),
modelValue: makeRequiredProp([String, Number, Array] as PropType<string | number | Array<string | number>>),
/**
* date / year-month / time
*/
@@ -102,7 +102,7 @@ export const datetimePickerProps = {
/**
*
*/
maxDate: makeNumberProp(new Date(new Date().getFullYear() + 10, 11, 31).getTime()),
maxDate: makeNumberProp(new Date(new Date().getFullYear() + 10, 11, 31, 23, 59, 59).getTime()),
/**
* time类型时生效
*/
@@ -155,6 +155,10 @@ export const datetimePickerProps = {
* wd-form组件使用
*/
rules: makeArrayProp<FormItemRule>(),
/**
* picker cell
*/
customCellClass: makeStringProp(''),
/**
* pickerView
*/
@@ -166,7 +170,11 @@ export const datetimePickerProps = {
/**
* value
*/
customValueClass: makeStringProp('')
customValueClass: makeStringProp(''),
/**
* picker-view的 change change 1.2.25
*/
immediateChange: makeBooleanProp(false)
}
export type DatetimePickerDisplayFormat = (items: Record<string, any>[]) => string
@@ -7,15 +7,15 @@
>
<!--文案-->
<view class="wd-picker__field" @click="showPopup">
<slot v-if="useDefaultSlot"></slot>
<view v-else class="wd-picker__cell">
<slot v-if="$slots.default"></slot>
<view v-else :class="['wd-picker__cell', customCellClass]">
<view
v-if="label || useLabelSlot"
v-if="label || $slots.label"
:class="`wd-picker__label ${customLabelClass} ${isRequired ? 'is-required' : ''}`"
:style="labelWidth ? 'min-width:' + labelWidth + ';max-width:' + labelWidth + ';' : ''"
>
<block v-if="label">{{ label }}</block>
<slot v-else name="label"></slot>
<slot v-if="$slots.label" name="label"></slot>
<block v-else>{{ label }}</block>
</view>
<view class="wd-picker__body">
<view class="wd-picker__value-wraper">
@@ -102,6 +102,7 @@
:max-minute="maxMinute"
:min-minute="minMinute"
:start-symbol="true"
:immediate-change="immediateChange"
@change="onChangeStart"
@pickstart="onPickStart"
@pickend="onPickEnd"
@@ -128,6 +129,7 @@
:max-minute="maxMinute"
:min-minute="minMinute"
:start-symbol="false"
:immediate-change="immediateChange"
@change="onChangeEnd"
@pickstart="onPickStart"
@pickend="onPickEnd"
@@ -150,6 +152,8 @@ export default {
</script>
<script lang="ts" setup>
import wdPopup from '../wd-popup/wd-popup.vue'
import wdDatetimePickerView from '../wd-datetime-picker-view/wd-datetime-picker-view.vue'
import { computed, getCurrentInstance, nextTick, onBeforeMount, onMounted, ref, watch } from 'vue'
import { deepClone, isArray, isDef, isEqual, isFunction, padZero } from '../common/util'
import { useCell } from '../composables/useCell'
@@ -163,6 +167,7 @@ import { FORM_KEY, type FormItemRule } from '../wd-form/types'
import { useParent } from '../composables/useParent'
import { useTranslate } from '../composables/useTranslate'
import { datetimePickerProps, type DatetimePickerExpose } from './types'
import { dayjs } from '../common/dayjs'
const props = defineProps(datetimePickerProps)
const emit = defineEmits(['change', 'open', 'toggle', 'cancel', 'confirm', 'update:modelValue'])
@@ -172,7 +177,7 @@ const { translate } = useTranslate('datetime-picker')
const datetimePickerView = ref<DatetimePickerViewInstance>()
const datetimePickerView1 = ref<DatetimePickerViewInstance>()
const showValue = ref<string | Date | Array<string | Date>>([])
const showValue = ref<string | Date | Array<string | Date>>('')
const popupShow = ref<boolean>(false)
const showStart = ref<boolean>(true)
const region = ref<boolean>(false)
@@ -314,33 +319,105 @@ const isRequired = computed(() => {
})
/**
* @description 自定义列项筛选规则对每列单项进行禁用校验最终返回传入PickerView的columns数组
* @param {Component} picker datetimePickerView对象
* @return {Array} columns
* @description 处理时间边界值判断
* @param isStart 是否是开始时间
* @param columnType 当前列类型
* @param value 当前值
* @param currentArray 当前完整选择的数组
* @param boundary 边界值数组
* @returns 是否超出边界
*/
function handleBoundaryValue(
isStart: boolean,
columnType: DatetimePickerViewColumnType,
value: number,
currentArray: number[],
boundary: number[]
): boolean {
const { type } = props
switch (type) {
case 'datetime': {
const [year, month, date, hour, minute] = boundary
if (columnType === 'year') {
return isStart ? value > year : value < year
}
if (columnType === 'month' && currentArray[0] === year) {
return isStart ? value > month : value < month
}
if (columnType === 'date' && currentArray[0] === year && currentArray[1] === month) {
return isStart ? value > date : value < date
}
if (columnType === 'hour' && currentArray[0] === year && currentArray[1] === month && currentArray[2] === date) {
return isStart ? value > hour : value < hour
}
if (columnType === 'minute' && currentArray[0] === year && currentArray[1] === month && currentArray[2] === date && currentArray[3] === hour) {
return isStart ? value > minute : value < minute
}
break
}
case 'year-month': {
const [year, month] = boundary
if (columnType === 'year') {
return isStart ? value > year : value < year
}
if (columnType === 'month' && currentArray[0] === year) {
return isStart ? value > month : value < month
}
break
}
case 'year': {
const [year] = boundary
if (columnType === 'year') {
return isStart ? value > year : value < year
}
break
}
case 'date': {
const [year, month, date] = boundary
if (columnType === 'year') {
return isStart ? value > year : value < year
}
if (columnType === 'month' && currentArray[0] === year) {
return isStart ? value > month : value < month
}
if (columnType === 'date' && currentArray[0] === year && currentArray[1] === month) {
return isStart ? value > date : value < date
}
break
}
case 'time': {
const [hour, minute] = boundary
if (columnType === 'hour') {
return isStart ? value > hour : value < hour
}
if (columnType === 'minute' && currentArray[0] === hour) {
return isStart ? value > minute : value < minute
}
break
}
}
return false
}
/**
* @description 自定义列项筛选规则
*/
const customColumnFormatter: DatetimePickerViewColumnFormatter = (picker) => {
if (!picker) {
return []
}
if (!picker) return []
const { type } = props
const { startSymbol, formatter } = picker
// pickervalueinnerValue
const start = picker.correctValue(innerValue.value)
const end = picker.correctValue(endInnerValue.value)
/**
* 如果是上方picekr 那么将下方picker的值作为下边界
* 如果是下方picekr 那么将上方picker的值作为上边界
*/
const currentValue = startSymbol ? picker.getPickerValue(start, type) : picker.getPickerValue(end, type)
const boundary = startSymbol ? picker.getPickerValue(end, type) : picker.getPickerValue(start, type)
// picekr
const columns = picker.getOriginColumns()
// index
return columns.map((column, cIndex) => {
return columns.map((column, _) => {
return column.values.map((value) => {
const disabled = columnDisabledRules(startSymbol, columns, cIndex, value, currentValue, boundary)
const disabled = handleBoundaryValue(startSymbol, column.type, value, currentValue, boundary)
return {
label: formatter ? formatter(column.type, padZero(value)) : padZero(value),
value,
@@ -387,18 +464,14 @@ function getSelects(picker: 'before' | 'after') {
function noop() {}
function getDefaultInnerValue(isRegion?: boolean, isEnd?: boolean): string | number {
const { modelValue: value, defaultValue } = props
const { modelValue: value, defaultValue, maxDate, minDate, type } = props
if (isRegion) {
if (isEnd) {
return (
(isArray(value) ? (value[1] as string) : '') || (defaultValue && isArray(defaultValue) ? (defaultValue[1] as string) : '') || props.maxDate
)
} else {
return (
(isArray(value) ? (value[0] as string) : '') || (defaultValue && isArray(defaultValue) ? (defaultValue[0] as string) : '') || props.minDate
)
}
const index = isEnd ? 1 : 0
const targetValue = isArray(value) ? (value[index] as string) : ''
const targetDefault = isArray(defaultValue) ? (defaultValue[index] as string) : ''
const maxValue = type === 'time' ? dayjs(maxDate).format('HH:mm') : maxDate
const minValue = type === 'time' ? dayjs(minDate).format('HH:mm') : minDate
return targetValue || targetDefault || (isEnd ? maxValue : minValue)
} else {
return isDef(value || defaultValue) ? (value as string) || (defaultValue as string) : ''
}
@@ -414,9 +487,6 @@ function close() {
onCancel()
}
/**
* @description 展示popup小程序有个bug在picker-view弹出时设置value会触发change事件而且会将picker-view的value多次触发change重置为第一项
*/
function showPopup() {
if (props.disabled || props.readonly) return
@@ -449,15 +519,34 @@ function tabChange() {
* @description datetimePickerView change 事件
*/
function onChangeStart({ value }: { value: number | string }) {
innerValue.value = deepClone(value)
if (!datetimePickerView.value) return
if (region.value && !datetimePickerView1.value) return
if (region.value) {
showTabLabel.value = [setTabLabel(), deepClone(showTabLabel.value[1])]
emit('change', {
value: [value, endInnerValue.value]
//
const currentArray = datetimePickerView.value.getPickerValue(value, props.type)
const boundaryArray = datetimePickerView.value.getPickerValue(endInnerValue.value, props.type)
const columns = datetimePickerView.value.getOriginColumns()
//
const needsAdjust = columns.some((column, index) => {
return handleBoundaryValue(true, column.type, currentArray[index], currentArray, boundaryArray)
})
innerValue.value = deepClone(needsAdjust ? endInnerValue.value : value)
nextTick(() => {
showTabLabel.value = [setTabLabel(), deepClone(showTabLabel.value[1])]
emit('change', {
value: [innerValue.value, endInnerValue.value]
})
// picker
datetimePickerView.value && datetimePickerView.value.setColumns(datetimePickerView.value.updateColumns())
datetimePickerView1.value && datetimePickerView1.value.setColumns(datetimePickerView1.value.updateColumns())
})
datetimePickerView.value && datetimePickerView.value.setColumns(datetimePickerView.value.updateColumns())
datetimePickerView1.value && datetimePickerView1.value.setColumns(datetimePickerView1.value.updateColumns())
} else {
//
innerValue.value = deepClone(value)
emit('change', {
value: innerValue.value
})
@@ -468,13 +557,28 @@ function onChangeStart({ value }: { value: number | string }) {
* @description 区域选择 下方 datetimePickerView change 事件
*/
function onChangeEnd({ value }: { value: number | string }) {
endInnerValue.value = deepClone(value)
showTabLabel.value = [deepClone(showTabLabel.value[0]), setTabLabel(1)]
emit('change', {
value: [innerValue.value, value]
if (!datetimePickerView.value || !datetimePickerView1.value) return
const currentArray = datetimePickerView1.value.getPickerValue(value, props.type)
const boundaryArray = datetimePickerView1.value.getPickerValue(innerValue.value, props.type)
const columns = datetimePickerView1.value.getOriginColumns()
//
const needsAdjust = columns.some((column, index) => {
return handleBoundaryValue(false, column.type, currentArray[index], currentArray, boundaryArray)
})
endInnerValue.value = deepClone(needsAdjust ? innerValue.value : value)
nextTick(() => {
showTabLabel.value = [deepClone(showTabLabel.value[0]), setTabLabel(1)]
emit('change', {
value: [innerValue.value, endInnerValue.value]
})
// picker
datetimePickerView.value && datetimePickerView.value.setColumns(datetimePickerView.value.updateColumns())
datetimePickerView1.value && datetimePickerView1.value.setColumns(datetimePickerView1.value.updateColumns())
})
datetimePickerView.value && datetimePickerView.value.setColumns(datetimePickerView.value.updateColumns())
datetimePickerView1.value && datetimePickerView1.value.setColumns(datetimePickerView1.value.updateColumns())
}
/**
@@ -619,11 +723,6 @@ function defaultDisplayFormat(items: Record<string, any>[], tabLabel: boolean =
// 使formatterdefaultDisplayFormat
if (props.formatter) {
/**
* 不建议使用 this.picker.picker.getLabels() 拉取
* 在初始展示时需要使用模拟 nextTick 来等待内部 pickerView 渲染后labels才可得到format后的labels
* 但使用模拟nextTick会造成页面延迟展示问题对用户感知来讲不友好因此不适用该方法
*/
const typeMaps = {
year: ['year'],
datetime: ['year', 'month', 'date', 'hour', 'minute'],
@@ -652,100 +751,6 @@ function defaultDisplayFormat(items: Record<string, any>[], tabLabel: boolean =
}
}
/**
* @description 区域选择time禁用规则根据传入的位置标志以及日期类型 返回该节点是否禁用
* @param {Boolean} isStart 时间段类型 truestart | falseend
* @param {Array} column 当前遍历到的列数组
* @param {Number} cindex 外层column的索引对应每一个类型
* @param {Number / String} value 遍历到的当前值
* @param {Array} currentValue 当前选中的值 this.pickerValue
* @param {Array} boundary 当前变量的限制值决定禁用的边界值
* @return {Boolean} disabled
*/
function columnDisabledRules(
isStart: boolean,
columns: {
type: DatetimePickerViewColumnType
values: number[]
}[],
cIndex: number,
value: number,
currentValue: number[],
boundary: number[]
) {
const { type } = props
// 0 1 2 3 4
// startPicker , endPicker , startPicker boundary min->boundary
// endPicker , startPicker , endPicker boundary boundary->max
const column = columns[cIndex]
// ranges[0][0] minYear ranges[0][1] maxYear
if (type === 'datetime') {
const year = boundary[0]
const month = boundary[1]
const date = boundary[2]
const hour = boundary[3]
const minute = boundary[4]
if (column.type === 'year') {
return isStart ? value > year : value < year
}
if (column.type === 'month' && currentValue[0] === year) {
return isStart ? value > month : value < month
}
if (column.type === 'date' && currentValue[0] === year && currentValue[1] === month) {
return isStart ? value > date : value < date
}
if (column.type === 'hour' && currentValue[0] === year && currentValue[1] === month && currentValue[2] === date) {
return isStart ? value > hour : value < hour
}
if (column.type === 'minute' && currentValue[0] === year && currentValue[1] === month && currentValue[2] === date && currentValue[3] === hour) {
return isStart ? value > minute : value < minute
}
} else if (type === 'year-month') {
const year = boundary[0]
const month = boundary[1]
if (column.type === 'year') {
return isStart ? value > year : value < year
}
if (column.type === 'month' && currentValue[0] === year) {
return isStart ? value > month : value < month
}
} else if (type === 'year') {
const year = boundary[0]
if (column.type === 'year') {
return isStart ? value > year : value < year
}
} else if (type === 'date') {
const year = boundary[0]
const month = boundary[1]
const date = boundary[2]
if (column.type === 'year') {
return isStart ? value > year : value < year
}
if (column.type === 'month' && currentValue[0] === year) {
return isStart ? value > month : value < month
}
if (column.type === 'date' && currentValue[0] === year && currentValue[1] === month) {
return isStart ? value > date : value < date
}
} else if (type === 'time') {
const hour = boundary[0]
const minute = boundary[1]
if (column.type === 'hour') {
return isStart ? value > hour : value < hour
}
if (column.type === 'minute' && currentValue[0] === hour) {
return isStart ? value > minute : value < minute
}
}
return false
}
function setLoading(loading: boolean) {
isLoading.value = loading
}
@@ -15,18 +15,86 @@
position: relative;
display: flex;
padding: $-divider-padding;
margin: $-divider-margin;
align-items: center;
color: $-divider-color;
font-size: $-divider-fs;
@include e(line) {
display: block;
&::after,
&::before {
flex: 1;
height: 1px;
transform: scaleY(0.5);
background: $-divider-line-color;
display: block;
box-sizing: border-box;
border-style: solid;
border-color: $-divider-line-color;
border-width: $-divider-line-height 0 0;
}
@include e(content) {
padding: 0 12px;
&::before {
content: '';
}
}
@include m(center, left, right) {
&::after {
content: '';
margin-left: $-divider-content-left-margin;
}
&::before {
margin-right: $-divider-content-right-margin;
}
}
@include m(left) {
&::before {
max-width: $-divider-content-left-width;
}
}
@include m(right) {
&::after {
max-width: $-divider-content-right-width;
}
}
@include when(hairline) {
&::before,
&::after {
transform: scaleY(0.5);
}
}
@include when(dashed) {
&::before,
&::after {
border-style: dashed;
}
}
@include m(vertical) {
display: inline-block;
width: $-divider-vertical-line-width;
height: $-divider-vertical-height;
margin: $-divider-vertical-content-margin;
padding: 0;
vertical-align: middle;
&::before {
height: 100%;
border-width: 0 0 0 $-divider-vertical-line-width;
}
&::after {
display: none;
}
@include when(hairline) {
&::before {
transform: scaleX(0.5);
}
}
}
}
@@ -1,12 +1,35 @@
import type { ExtractPropTypes } from 'vue'
import { baseProps, makeStringProp } from '../common/props'
import { baseProps, makeBooleanProp, makeStringProp } from '../common/props'
export type DividerPosition = 'center' | 'left' | 'right'
export type DividerDirection = 'horizontal' | 'vertical'
export const dividerProps = {
...baseProps,
/**
*
*
*/
color: makeStringProp('')
color: String,
/**
* `left` `right` `center`
* `center`
*/
contentPosition: makeStringProp<DividerPosition>('center'),
/**
* 线
* `false`
*/
dashed: Boolean,
/**
* 线
* `false`
*/
vertical: makeBooleanProp(false),
/**
* 0.5px 线
* `true`
*/
hairline: makeBooleanProp(true)
}
export type DividerProps = ExtractPropTypes<typeof dividerProps>
@@ -1,10 +1,6 @@
<template>
<view :class="`wd-divider ${customClass}`" :style="customStyle">
<view class="wd-divider__line" :style="color ? 'background: ' + color : ''"></view>
<view class="wd-divider__content" :style="color ? 'color: ' + color : ''">
<slot></slot>
</view>
<view class="wd-divider__line" :style="color ? 'background: ' + color : ''"></view>
<view :class="rootClass" :style="rootStyle">
<slot v-if="!vertical"></slot>
</view>
</template>
<script lang="ts">
@@ -19,9 +15,36 @@ export default {
</script>
<script lang="ts" setup>
import { computed, useSlots, type CSSProperties } from 'vue'
import { dividerProps } from './types'
import { objToStyle } from '../common/util'
defineProps(dividerProps)
const props = defineProps(dividerProps)
const slots = useSlots()
const rootStyle = computed(() => {
const { color } = props
const style: CSSProperties = {}
if (color) {
style.color = color
}
return `${objToStyle(style)};${props.customStyle}`
})
const rootClass = computed(() => {
const prefixCls = 'wd-divider'
const classes: Record<string, boolean> = {
[prefixCls]: true,
['is-dashed']: props.dashed,
['is-hairline']: props.hairline,
[`${prefixCls}--vertical`]: props.vertical,
[`${prefixCls}--center`]: !props.vertical && !!slots.default,
[`${prefixCls}--left`]: !props.vertical && props.contentPosition === 'left',
[`${prefixCls}--right`]: !props.vertical && props.contentPosition === 'right',
[props.customClass]: !!props.customClass
}
return classes
})
</script>
<style lang="scss" scoped>
@@ -1,6 +1,15 @@
import type { ComponentPublicInstance, ExtractPropTypes } from 'vue'
import type { ComponentPublicInstance, ExtractPropTypes, PropType } from 'vue'
import { baseProps, makeArrayProp, makeBooleanProp, makeStringProp } from '../common/props'
export type DropMenuItemBeforeToggleOption = {
// 操作状态:true 打开下拉菜单,false 关闭下拉菜单
status: boolean
// 回调函数,用于控制是否允许打开或关闭下拉菜单,true 允许打开或关闭,false 不允许打开或关闭
resolve: (isPass: boolean) => void
}
export type DropMenuItemBeforeToggle = (option: DropMenuItemBeforeToggleOption) => void
export const dorpMenuItemProps = {
...baseProps,
/**
@@ -31,6 +40,18 @@ export const dorpMenuItemProps = {
*
*/
title: String,
/**
*
*/
icon: makeStringProp('arrow-down'),
/**
*
*/
iconSize: makeStringProp('14px'),
/**
*
*/
beforeToggle: Function as PropType<DropMenuItemBeforeToggle>,
/**
* value key
*/
@@ -42,16 +63,24 @@ export const dorpMenuItemProps = {
/**
* key
*/
tipKey: makeStringProp('tip')
tipKey: makeStringProp('tip'),
/**
* popup样式类
*/
customPopupClass: makeStringProp(''),
/**
* popup样式
*/
customPopupStyle: makeStringProp('')
}
export type DropMenuItemProps = ExtractPropTypes<typeof dorpMenuItemProps>
export type DropMenuItemExpose = {
setShowPop: (show: boolean) => void
getShowPop: () => boolean
open: () => void
close: () => void
toggle: () => void
}
export type DropMenuItemInstance = ComponentPublicInstance<DropMenuItemProps>
export type DropMenuItemInstance = ComponentPublicInstance<DropMenuItemProps, DropMenuItemExpose>
@@ -5,15 +5,16 @@
:z-index="zIndex"
:duration="duration"
:position="position"
custom-style="position: absolute; max-height: 80%;"
:custom-style="`position: absolute; max-height: 80%;${customPopupStyle}`"
:custom-class="customPopupClass"
modal-style="position: absolute;"
:modal="modal"
:close-on-click-modal="closeOnClickModal"
@click-modal="close"
@before-enter="handleOpen"
@after-enter="handleOpened"
@before-leave="handleClose"
@after-leave="onPopupClose"
:close-on-click-modal="false"
@click-modal="closeOnClickModal && close()"
@before-enter="beforeEnter"
@after-enter="afterEnter"
@before-leave="beforeLeave"
@after-leave="afterLeave"
>
<view v-if="options.length">
<view
@@ -50,13 +51,15 @@ export default {
</script>
<script lang="ts" setup>
import wdPopup from '../wd-popup/wd-popup.vue'
import wdIcon from '../wd-icon/wd-icon.vue'
import { computed, getCurrentInstance, inject, onBeforeMount, onBeforeUnmount, ref, watch } from 'vue'
import { pushToQueue, removeFromQueue } from '../common/clickoutside'
import { type Queue, queueKey } from '../composables/useQueue'
import type { PopupType } from '../wd-popup/types'
import { useParent } from '../composables/useParent'
import { DROP_MENU_KEY } from '../wd-drop-menu/types'
import { isDef } from '../common/util'
import { isDef, isFunction } from '../common/util'
import { dorpMenuItemProps, type DropMenuItemExpose } from './types'
const props = defineProps(dorpMenuItemProps)
@@ -75,6 +78,19 @@ const { parent: dropMenu } = useParent(DROP_MENU_KEY)
const { proxy } = getCurrentInstance() as any
const positionStyle = computed(() => {
let style: string = ''
if (showWrapper.value && dropMenu) {
style =
dropMenu.props.direction === 'down'
? `top: calc(var(--window-top) + ${dropMenu.offset.value}px); bottom: 0;`
: `top: 0; bottom: calc(var(--window-bottom) + ${dropMenu.offset.value}px)`
} else {
style = ''
}
return style
})
watch(
() => props.modelValue,
(newValue) => {
@@ -104,14 +120,6 @@ onBeforeUnmount(() => {
}
})
/**
* 父组件更改子组件内部
* @param show
*/
function setShowPop(show: boolean) {
showPop.value = show
}
function getShowPop() {
return showPop.value
}
@@ -120,35 +128,54 @@ function choose(index: number) {
if (props.disabled) return
const { valueKey } = props
const item = props.options[index]
emit('update:modelValue', item[valueKey] !== '' && item[valueKey] !== undefined ? item[valueKey] : item)
close()
const newValue = item[valueKey] !== undefined ? item[valueKey] : item
emit('update:modelValue', newValue)
emit('change', {
value: item[valueKey] !== '' && item[valueKey] !== undefined ? item[valueKey] : item,
value: newValue,
selectedItem: item
})
close()
}
//
function close() {
if (showPop.value) {
showPop.value = false
dropMenu && dropMenu.fold()
if (!showPop.value) {
return
}
if (isFunction(props.beforeToggle)) {
props.beforeToggle({
status: false,
resolve: (isPass: boolean) => {
isPass && handleClose()
}
})
} else {
handleClose()
}
}
const positionStyle = computed(() => {
let style: string = ''
if (showWrapper.value && dropMenu) {
style =
dropMenu.props.direction === 'down'
? `top: calc(var(--window-top) + ${dropMenu.offset.value}px); bottom: 0;`
: `top: 0; bottom: calc(var(--window-bottom) + ${dropMenu.offset.value}px)`
} else {
style = ''
function handleClose() {
if (showPop.value) {
showPop.value = false
}
return style
})
}
function open() {
if (showPop.value) {
return
}
if (isFunction(props.beforeToggle)) {
props.beforeToggle({
status: true,
resolve: (isPass) => {
isPass && handleOpen()
}
})
} else {
handleOpen()
}
}
function handleOpen() {
showWrapper.value = true
showPop.value = true
if (dropMenu) {
@@ -157,24 +184,32 @@ function open() {
closeOnClickModal.value = Boolean(dropMenu.props.closeOnClickModal)
position.value = dropMenu.props.direction === 'down' ? 'top' : 'bottom'
}
emit('open')
}
function onPopupClose() {
function toggle() {
if (showPop.value) {
close()
} else {
open()
}
}
function afterLeave() {
showWrapper.value = false
emit('closed')
}
function handleOpen() {
function beforeEnter() {
emit('open')
}
function handleOpened() {
function afterEnter() {
emit('opened')
}
function handleClose() {
function beforeLeave() {
emit('close')
}
defineExpose<DropMenuItemExpose>({ setShowPop, getShowPop, open, close })
defineExpose<DropMenuItemExpose>({ getShowPop, open, close, toggle })
</script>
<style lang="scss" scoped>
@@ -84,5 +84,6 @@
right: -4px;
transition: transform 0.3s;
transform: scale(0.6);
font-size: $-drop-menu-arrow-fs;
}
}
@@ -8,11 +8,11 @@
v-for="(child, index) in children"
:key="index"
@click="toggle(child)"
:class="`wd-drop-menu__item ${child.disabled ? 'is-disabled' : ''} ${currentUid === child.$.uid ? 'is-active' : ''}`"
:class="`wd-drop-menu__item ${child.disabled ? 'is-disabled' : ''} ${child.$.exposed!.getShowPop() ? 'is-active' : ''}`"
>
<view class="wd-drop-menu__item-title">
<view class="wd-drop-menu__item-title-text">{{ getDisplayTitle(child) }}</view>
<wd-icon name="arrow-down" size="14px" custom-class="wd-drop-menu__arrow" />
<wd-icon :name="child.icon" :size="child.iconSize" custom-class="wd-drop-menu__arrow" />
</view>
</view>
</view>
@@ -43,10 +43,7 @@ import { DROP_MENU_KEY, dropMenuProps } from './types'
const props = defineProps(dropMenuProps)
const queue = inject<Queue | null>(queueKey, null)
const dropMenuId = ref<string>(`dropMenuId${uuid()}`)
// -1
const currentUid = ref<number | null>(null)
const offset = ref<number>(0)
const windowHeight = ref<number>(0)
@@ -59,7 +56,7 @@ linkChildren({ props, fold, offset })
watch(
() => props.direction,
(newValue) => {
if (newValue !== 'up' && newValue !== 'down') {
if (!['up', 'down'].includes(newValue)) {
// eslint-disable-next-line quotes
console.error("[wot design] warning(wd-drop-menu): direction must be 'up' or 'down'")
}
@@ -92,7 +89,6 @@ function getDisplayTitle(child: any) {
function toggle(child: any) {
// menu, menu
if (child && !child.disabled) {
if (queue && queue.closeOther) {
queue.closeOther(child)
@@ -102,40 +98,20 @@ function toggle(child: any) {
fold(child)
}
}
/**
* 控制菜单内容是否展开
*/
function fold(child?: any) {
currentUid.value = child ? child.$.uid : null
if (!child) {
children.forEach((item) => {
item.$.exposed!.setShowPop(false)
})
return
}
function fold(child: any) {
getRect(`#${dropMenuId.value}`, false, proxy).then((rect) => {
if (!rect) return
const { top, bottom } = rect
if (props.direction === 'down') {
offset.value = Number(bottom)
} else {
offset.value = windowHeight.value - Number(top)
}
const showPop = child.$.exposed!.getShowPop()
if (showPop) {
child.$.exposed!.setShowPop(false)
currentUid.value = null
} else {
//
children.forEach((item) => {
if (child.$.uid === item.$.uid) {
item.$.exposed!.open()
} else {
item.$.exposed!.setShowPop(false)
}
})
}
child.$.exposed!.toggle()
})
}
</script>
@@ -111,6 +111,6 @@
}
@include edeep(icon) {
font-size: 20px;
font-size: $-fab-icon-fs;
}
}
@@ -1,10 +1,11 @@
import type { ComponentPublicInstance, ExtractPropTypes } from 'vue'
import { baseProps, makeBooleanProp, makeNumberProp, makeStringProp } from '../common/props'
import type { PropType } from 'vue'
export type FabType = 'primary' | 'success' | 'info' | 'warning' | 'error' | 'default'
export type FabPosition = 'left-top' | 'right-top' | 'left-bottom' | 'right-bottom'
export type FabPosition = 'left-top' | 'right-top' | 'left-bottom' | 'right-bottom' | 'left-center' | 'right-center' | 'top-center' | 'bottom-center'
export type FabDirection = 'top' | 'right' | 'bottom' | 'left'
export type FabGap = Partial<Record<FabDirection, number>>
export const fabProps = {
...baseProps,
/**
@@ -16,7 +17,7 @@ export const fabProps = {
*/
type: makeStringProp<FabType>('primary'),
/**
* left-top right-top left-bottom right-bottom
* left-top right-top left-bottom right-bottom left-center right-center top-center bottom-center
*/
position: makeStringProp<FabPosition>('right-bottom'),
/**
@@ -42,7 +43,15 @@ export const fabProps = {
/**
*
*/
draggable: makeBooleanProp(false)
draggable: makeBooleanProp(false),
gap: {
type: Object as PropType<FabGap>,
default: () => ({})
},
/**
*
*/
expandable: makeBooleanProp(true)
}
export type FabProps = ExtractPropTypes<typeof fabProps>
@@ -7,12 +7,14 @@
:style="rootStyle"
@click.stop=""
>
<view @click.stop="">
<wd-button @click="handleClick" custom-class="wd-fab__trigger" round :type="type" :disabled="disabled">
<view @click.stop="" :style="{ visibility: inited ? 'visible' : 'hidden' }" id="trigger">
<slot name="trigger" v-if="$slots.trigger"></slot>
<wd-button v-else @click="handleClick" custom-class="wd-fab__trigger" round :type="type" :disabled="disabled">
<wd-icon custom-class="wd-fab__icon" :name="isActive ? activeIcon : inactiveIcon"></wd-icon>
</wd-button>
</view>
<wd-transition
v-if="expandable"
:enter-class="`wd-fab__transition-enter--${fabDirection}`"
enter-active-class="wd-fab__transition-enter-active"
:leave-to-class="`wd-fab__transition-leave-to--${fabDirection}`"
@@ -20,7 +22,6 @@
:custom-class="`wd-fab__actions wd-fab__actions--${fabDirection}`"
:show="isActive"
:duration="300"
name=""
>
<slot></slot>
</wd-transition>
@@ -39,16 +40,20 @@ export default {
</script>
<script lang="ts" setup>
import { type CSSProperties, computed, onBeforeMount, ref, watch, inject, getCurrentInstance, onBeforeUnmount } from 'vue'
import { isDef, isH5, objToStyle } from '../common/util'
import wdButton from '../wd-button/wd-button.vue'
import wdIcon from '../wd-icon/wd-icon.vue'
import wdTransition from '../wd-transition/wd-transition.vue'
import { type CSSProperties, computed, ref, watch, inject, getCurrentInstance, onBeforeUnmount, onMounted, nextTick } from 'vue'
import { getRect, isDef, isH5, objToStyle } from '../common/util'
import { type Queue, queueKey } from '../composables/useQueue'
import { closeOther, pushToQueue, removeFromQueue } from '../common/clickoutside'
import { fabProps, type FabExpose } from './types'
import { onMounted, reactive } from 'vue'
import { reactive } from 'vue'
import { useRaf } from '../composables/useRaf'
const props = defineProps(fabProps)
const emit = defineEmits(['update:active'])
const emit = defineEmits(['update:active', 'click'])
const inited = ref<boolean>(false) //
const isActive = ref<boolean>(false) //
const queue = inject<Queue | null>(queueKey, null)
const { proxy } = getCurrentInstance() as any
@@ -86,10 +91,10 @@ watch(
() => initPosition()
)
const top = ref(0)
const left = ref(0)
const top = ref<number>(0)
const left = ref<number>(0)
const screen = reactive({ width: 0, height: 0 })
const fabSize = ref(56)
const fabSize = reactive({ width: 56, height: 56 })
const bounding = reactive({
minTop: 0,
minLeft: 0,
@@ -97,44 +102,70 @@ const bounding = reactive({
maxLeft: 0
})
function getBounding() {
async function getBounding() {
const sysInfo = uni.getSystemInfoSync()
const gap = 16
try {
const trigerInfo = await getRect('#trigger', false, proxy)
fabSize.width = trigerInfo.width || 56
fabSize.height = trigerInfo.height || 56
} catch (error) {
console.log(error)
}
const { top = 16, left = 16, right = 16, bottom = 16 } = props.gap
screen.width = sysInfo.windowWidth
screen.height = isH5 ? sysInfo.windowTop + sysInfo.windowHeight : sysInfo.windowHeight
bounding.minTop = isH5 ? sysInfo.windowTop + gap : gap
bounding.minLeft = gap
bounding.maxLeft = screen.width - fabSize.value - gap
bounding.maxTop = screen.height - fabSize.value - gap
bounding.minTop = isH5 ? sysInfo.windowTop + top : top
bounding.minLeft = left
bounding.maxLeft = screen.width - fabSize.width - right
bounding.maxTop = screen.height - fabSize.height - bottom
}
function initPosition() {
const pos = props.position
const { minLeft, minTop, maxLeft, maxTop } = bounding
if (pos === 'left-top') {
top.value = minTop
left.value = minLeft
} else if (pos === 'right-top') {
top.value = minTop
left.value = maxLeft
} else if (pos === 'left-bottom') {
top.value = maxTop
left.value = minLeft
} else if (pos === 'right-bottom') {
top.value = maxTop
left.value = maxLeft
const centerY = (maxTop + minTop) / 2
const centerX = (maxLeft + minLeft) / 2
switch (pos) {
case 'left-top':
top.value = minTop
left.value = minLeft
break
case 'right-top':
top.value = minTop
left.value = maxLeft
break
case 'left-bottom':
top.value = maxTop
left.value = minLeft
break
case 'right-bottom':
top.value = maxTop
left.value = maxLeft
break
case 'left-center':
top.value = centerY
left.value = minLeft
break
case 'right-center':
top.value = centerY
left.value = maxLeft
break
case 'top-center':
top.value = minTop
left.value = centerX
break
case 'bottom-center':
top.value = maxTop
left.value = centerX
break
}
}
onMounted(() => {
initPosition()
})
//
const touchOffset = reactive({ x: 0, y: 0 })
const attractTransition = ref(false)
const attractTransition = ref<boolean>(false)
function handleTouchStart(e: TouchEvent) {
if (props.draggable === false) return
@@ -166,7 +197,7 @@ function handleTouchEnd() {
if (props.draggable === false) return
const screenCenterX = screen.width / 2
const fabCenterX = left.value + fabSize.value / 2
const fabCenterX = left.value + fabSize.width / 2
attractTransition.value = true
if (fabCenterX < screenCenterX) {
left.value = bounding.minLeft
@@ -189,13 +220,19 @@ const rootStyle = computed(() => {
return `${objToStyle(style)};${props.customStyle}`
})
onBeforeMount(() => {
getBounding()
onMounted(() => {
if (queue && queue.pushToQueue) {
queue.pushToQueue(proxy)
} else {
pushToQueue(proxy)
}
const { start } = useRaf(async () => {
await getBounding()
initPosition()
inited.value = true
})
start()
})
onBeforeUnmount(() => {
@@ -210,6 +247,10 @@ function handleClick() {
if (props.disabled) {
return
}
if (!props.expandable) {
emit('click')
return
}
isActive.value = !isActive.value
emit('update:active', isActive.value)
}
@@ -0,0 +1,64 @@
@import '../common/abstracts/variable';
@import '../common/abstracts/mixin';
.wot-theme-dark {
@include b(floating-panel) {
background: $-dark-background2;
@include e(content) {
background: $-dark-background2;
}
}
}
@include b(floating-panel) {
position: fixed;
bottom: 0;
left: 0;
z-index: $-floating-panel-z-index;
display: flex;
flex-direction: column;
box-sizing: border-box;
width: 100vw;
border-top-left-radius: $-floating-panel-radius;
border-top-right-radius: $-floating-panel-radius;
background-color: $-floating-panel-bg;
touch-action: none;
will-change: transform;
@include when(safe) {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
&::after {
position: absolute;
bottom: -100vh;
display: block;
width: 100vw;
height: 100vh;
content: '';
background-color: inherit;
}
@include e(header) {
display: flex;
justify-content: center;
align-items: center;
height: $-floating-panel-header-height;
cursor: grab;
user-select: none;
&-bar {
width: $-floating-panel-bar-width;
height: $-floating-panel-bar-height;
background-color: $-floating-panel-bar-bg;
border-radius: $-floating-panel-bar-radius;
}
}
@include e(content) {
flex: 1;
min-width: 0;
min-height: 0;
background-color: $-floating-panel-content-bg;
}
}
@@ -0,0 +1,32 @@
import type { ExtractPropTypes } from 'vue'
import { baseProps, makeArrayProp, makeBooleanProp, makeNumberProp, makeNumericProp, truthProp } from '../common/props'
export const floatingPanelProps = {
...baseProps,
/**
*
*/
height: makeNumberProp(0),
/**
* [100, windowHeight * 0.6]
*/
anchors: makeArrayProp<number>(),
/**
* iphone X
*/
safeAreaInsetBottom: makeBooleanProp(false),
/**
* true
*/
showScrollbar: truthProp,
/**
* 300ms
*/
duration: makeNumericProp(300),
/**
* true
*/
contentDraggable: truthProp
}
export type FloatingPanelProps = ExtractPropTypes<typeof floatingPanelProps>
@@ -0,0 +1,140 @@
<template>
<view
:class="`wd-floating-panel ${customClass} ${safeAreaInsetBottom ? 'is-safe' : ''}`"
:style="rootStyle"
@touchstart.passive="handleTouchStart"
@touchmove.passive="handleTouchMove"
@touchend="handleTouchEnd"
@touchcancel="handleTouchEnd"
>
<view :class="`wd-floating-panel__header`">
<view :class="`wd-floating-panel__header-bar`"></view>
</view>
<scroll-view
:class="`wd-floating-panel__content`"
data-id="content"
:show-scrollbar="showScrollbar"
scroll-y
@touchmove.stop.prevent="handleTouchMove"
>
<slot />
</scroll-view>
</view>
</template>
<script lang="ts">
export default {
name: 'wd-floating-panel',
options: {
virtualHost: true,
addGlobalClass: true,
styleIsolation: 'shared'
}
}
</script>
<script lang="ts" setup>
import { computed, onBeforeMount, ref, watch, type CSSProperties } from 'vue'
import { floatingPanelProps } from './type'
import { addUnit, closest, objToStyle } from '../common/util'
import { useTouch } from '../composables/useTouch'
const touch = useTouch()
const props = defineProps(floatingPanelProps)
const emit = defineEmits(['update:height', 'height-change'])
const heightValue = ref<number>(props.height)
const DAMP = 0.2 //
let startY: number //
const windowHeight = ref<number>(0)
const dragging = ref<boolean>(false) //
const boundary = computed(() => ({
min: props.anchors[0] ? props.anchors[0] : 100,
max: props.anchors[props.anchors.length - 1] ? props.anchors[props.anchors.length - 1] : Math.round(windowHeight.value * 0.6)
}))
const anchors = computed(() => (props.anchors.length >= 2 ? props.anchors : [boundary.value.min, boundary.value.max]))
const rootStyle = computed(() => {
const style: CSSProperties = {
height: addUnit(boundary.value.max),
transform: `translateY(calc(100% + ${addUnit(-heightValue.value)}))`,
transition: !dragging.value ? `transform ${props.duration}ms cubic-bezier(0.18, 0.89, 0.32, 1.28)` : 'none'
}
return `${objToStyle(style)};${props.customStyle}`
})
const updateHeight = (value: number) => {
heightValue.value = value
emit('update:height', value)
}
const handleTouchStart = (event: TouchEvent) => {
touch.touchStart(event)
dragging.value = true
startY = -heightValue.value
}
const handleTouchMove = (event: TouchEvent) => {
const target = event.currentTarget as any
if (target.dataset.id == 'content') {
if (!props.contentDraggable) return
}
touch.touchMove(event)
const moveY = touch.deltaY.value + startY
updateHeight(-ease(moveY))
}
const handleTouchEnd = () => {
dragging.value = false
updateHeight(closest(anchors.value, heightValue.value))
if (heightValue.value !== -startY) {
emit('height-change', { height: heightValue.value })
}
}
const ease = (y: number) => {
const absDistance = Math.abs(y)
const { min, max } = boundary.value
if (absDistance > max) {
return -(max + (absDistance - max) * DAMP)
}
if (absDistance < min) {
return -(min - (min - absDistance) * DAMP)
}
return y
}
watch(
() => props.height,
(value) => {
heightValue.value = value
}
)
watch(
boundary,
() => {
updateHeight(closest(anchors.value, heightValue.value))
},
{ immediate: true }
)
onBeforeMount(() => {
const { windowHeight: _windowHeight } = uni.getSystemInfoSync()
windowHeight.value = _windowHeight
})
</script>
<style lang="scss" scoped>
@import './index.scss';
</style>
@@ -7,7 +7,7 @@
}
@include bdeep(form-item) {
@include b(form-item) {
@include e(error-message){
color: $-form-item-error-message-color;
font-size: $-form-item-error-message-font-size;
@@ -1,10 +1,10 @@
/*
* @Author: weisheng
* @Date: 2023-12-14 11:21:58
* @LastEditTime: 2024-03-18 12:50:41
* @LastEditTime: 2025-01-11 13:31:20
* @LastEditors: weisheng
* @Description:
* @FilePath: \wot-design-uni\src\uni_modules\wot-design-uni\components\wd-form\types.ts
* @FilePath: /wot-design-uni/src/uni_modules/wot-design-uni/components/wd-form/types.ts
*
*/
import { type ComponentPublicInstance, type ExtractPropTypes, type InjectionKey, type PropType } from 'vue'
@@ -56,7 +56,14 @@ export const formProps = {
/**
*
*/
resetOnChange: makeBooleanProp(true)
resetOnChange: makeBooleanProp(true),
/**
*
*/
errorType: {
type: String as PropType<'toast' | 'message' | 'none'>,
default: 'message'
}
}
export type FormProps = ExtractPropTypes<typeof formProps>
@@ -65,7 +72,7 @@ export type FormExpose = {
*
* @param prop
*/
validate: (prop?: string) => Promise<{
validate: (prop?: string | Array<string>) => Promise<{
valid: boolean
errors: ErrorMessage[]
}>
@@ -1,6 +1,7 @@
<template>
<view :class="`wd-form ${customClass}`" :style="customStyle">
<slot></slot>
<wd-toast v-if="props.errorType === 'toast'" selector="wd-form-toast" />
</view>
</template>
@@ -16,17 +17,20 @@ export default {
</script>
<script lang="ts" setup>
import wdToast from '../wd-toast/wd-toast.vue'
import { reactive, watch } from 'vue'
import { deepClone, getPropByPath, isDef, isPromise } from '../common/util'
import { deepClone, getPropByPath, isArray, isDef, isPromise, isString } from '../common/util'
import { useChildren } from '../composables/useChildren'
import { useToast } from '../wd-toast'
import { type FormRules, FORM_KEY, type ErrorMessage, formProps, type FormExpose } from './types'
const { show: showToast } = useToast('wd-form-toast')
const props = defineProps(formProps)
const { children, linkChildren } = useChildren(FORM_KEY)
let errorMessages = reactive<Record<string, string>>({})
linkChildren({ props, errorMessages: errorMessages })
linkChildren({ props, errorMessages })
watch(
() => props.model,
@@ -40,22 +44,33 @@ watch(
/**
* 表单校验
* @param prop 指定校验字段
* @param prop 指定校验字段或字段数组
*/
async function validate(prop?: string): Promise<{ valid: boolean; errors: ErrorMessage[] }> {
async function validate(prop?: string | string[]): Promise<{ valid: boolean; errors: ErrorMessage[] }> {
const errors: ErrorMessage[] = []
let valid: boolean = true
const promises: Promise<void>[] = []
const formRules: FormRules = getMergeRules()
const rulesToValidate: FormRules = prop ? { [prop]: formRules[prop] } : formRules
for (const prop in rulesToValidate) {
const rules = rulesToValidate[prop]
const value = getPropByPath(props.model, prop)
const propsToValidate = isArray(prop) ? prop : isDef(prop) ? [prop] : []
const rulesToValidate: FormRules =
propsToValidate.length > 0
? propsToValidate.reduce((acc, key) => {
if (formRules[key]) {
acc[key] = formRules[key]
}
return acc
}, {} as FormRules)
: formRules
for (const propName in rulesToValidate) {
const rules = rulesToValidate[propName]
const value = getPropByPath(props.model, propName)
if (rules && rules.length > 0) {
for (const rule of rules) {
if (rule.required && (!isDef(value) || value === '')) {
errors.push({
prop,
prop: propName,
message: rule.message
})
valid = false
@@ -63,7 +78,7 @@ async function validate(prop?: string): Promise<{ valid: boolean; errors: ErrorM
}
if (rule.pattern && !rule.pattern.test(value)) {
errors.push({
prop,
prop: propName,
message: rule.message
})
valid = false
@@ -75,33 +90,31 @@ async function validate(prop?: string): Promise<{ valid: boolean; errors: ErrorM
if (isPromise(result)) {
promises.push(
result
.then((res: any) => {
.then((res) => {
if (typeof res === 'string') {
errors.push({
prop,
prop: propName,
message: res
})
valid = false
} else if (typeof res === 'boolean' && !res) {
errors.push({
prop,
prop: propName,
message: rule.message
})
valid = false
}
})
.catch((error) => {
errors.push({
prop,
message: error || rule.message
})
.catch((error?: string | Error) => {
const message = isDef(error) ? (isString(error) ? error : error.message || rule.message) : rule.message
errors.push({ prop: propName, message })
valid = false
})
)
} else {
if (!result) {
errors.push({
prop,
prop: propName,
message: rule.message
})
valid = false
@@ -114,13 +127,11 @@ async function validate(prop?: string): Promise<{ valid: boolean; errors: ErrorM
await Promise.all(promises)
errors.forEach((error) => {
showMessage(error)
})
showMessage(errors)
if (valid) {
if (prop) {
clearMessage(prop)
if (propsToValidate.length) {
propsToValidate.forEach(clearMessage)
} else {
clearMessage()
}
@@ -135,6 +146,15 @@ async function validate(prop?: string): Promise<{ valid: boolean; errors: ErrorM
// rulesrules
function getMergeRules() {
const mergedRules: FormRules = deepClone(props.rules)
const childrenProps = children.map((child) => child.prop)
// children
Object.keys(mergedRules).forEach((key) => {
if (!childrenProps.includes(key)) {
delete mergedRules[key]
}
})
children.forEach((item) => {
if (isDef(item.prop) && isDef(item.rules) && item.rules.length) {
if (mergedRules[item.prop]) {
@@ -147,9 +167,20 @@ function getMergeRules() {
return mergedRules
}
function showMessage(errorMsg: ErrorMessage) {
if (errorMsg.message) {
errorMessages[errorMsg.prop] = errorMsg.message
function showMessage(errors: ErrorMessage[]) {
const childrenProps = children.map((e) => e.prop).filter(Boolean)
const messages = errors.filter((error) => error.message && childrenProps.includes(error.prop))
if (messages.length) {
messages.sort((a, b) => {
return childrenProps.indexOf(a.prop) - childrenProps.indexOf(b.prop)
})
if (props.errorType === 'toast') {
showToast(messages[0].message)
} else if (props.errorType === 'message') {
messages.forEach((error) => {
errorMessages[error.prop] = error.message
})
}
}
}
@@ -1,5 +1,5 @@
import type { ExtractPropTypes, PropType } from 'vue'
import { baseProps, makeBooleanProp, makeStringProp } from '../common/props'
import { baseProps, makeBooleanProp, makeStringProp, numericProp } from '../common/props'
import type { BadgeProps, BadgeType } from '../wd-badge/types'
export type LinkType = 'navigateTo' | 'switchTab' | 'reLaunch' | 'redirectTo'
@@ -49,7 +49,10 @@ export const gridItemProps = {
/**
*
*/
isDot: Boolean,
isDot: {
type: Boolean,
default: undefined
},
/**
* badge primary / success / warning / danger / info
*/
@@ -57,7 +60,7 @@ export const gridItemProps = {
/**
* badge
*/
value: Number,
value: numericProp,
/**
* badge '{max}+' value Number
*/
@@ -4,7 +4,7 @@
<slot v-if="useSlot" />
<block v-else>
<view :style="'width:' + iconSize + '; height: ' + iconSize" class="wd-grid-item__wrapper">
<wd-badge custom-class="badge" :is-dot="isDot" :modelValue="value" :max="max" :type="type" v-bind="badgeProps">
<wd-badge custom-class="badge" v-bind="customBadgeProps">
<template v-if="useIconSlot">
<slot name="icon" />
</template>
@@ -29,11 +29,14 @@ export default {
</script>
<script lang="ts" setup>
import wdIcon from '../wd-icon/wd-icon.vue'
import wdBadge from '../wd-badge/wd-badge.vue'
import { onMounted, ref, watch, computed } from 'vue'
import { useParent } from '../composables/useParent'
import { GRID_KEY } from '../wd-grid/types'
import { isDef } from '../common/util'
import { deepAssign, isDef, isUndefined, omitBy } from '../common/util'
import { gridItemProps } from './types'
import type { BadgeProps } from '../wd-badge/types'
const props = defineProps(gridItemProps)
const emit = defineEmits(['itemclick'])
@@ -54,6 +57,22 @@ const childCount = computed(() => {
}
})
const customBadgeProps = computed(() => {
const badgeProps: Partial<BadgeProps> = deepAssign(
isDef(props.badgeProps) ? omitBy(props.badgeProps, isUndefined) : {},
omitBy(
{
max: props.max,
isDot: props.isDot,
modelValue: props.value,
type: props.type
},
isUndefined
)
)
return badgeProps
})
watch(
() => childCount.value,
() => {
@@ -1,10 +1,5 @@
@import '../common/abstracts/variable';
@import '../common/abstracts/mixin';
.wot-theme-dark {
@include b(grid) {
background-color: $-dark-background2;
}
}
@include b(grid) {
position: relative;
@@ -3,9 +3,9 @@
@font-face {
font-family: 'wd-icons';
src: url('//at.alicdn.com/t/c/font_4245058_s5cpwl25n7o.woff2?t=1696817709651') format('woff2'),
url('//at.alicdn.com/t/c/font_4245058_s5cpwl25n7o.woff?t=1696817709651') format('woff'),
url('//at.alicdn.com/t/c/font_4245058_s5cpwl25n7o.ttf?t=1696817709651') format('truetype');
src: url('https://at.alicdn.com/t/c/font_4245058_s5cpwl25n7o.woff2?t=1696817709651') format('woff2'),
url('https://at.alicdn.com/t/c/font_4245058_s5cpwl25n7o.woff?t=1696817709651') format('woff'),
url('https://at.alicdn.com/t/c/font_4245058_s5cpwl25n7o.ttf?t=1696817709651') format('truetype');
font-weight: normal;
font-style: normal;
}
@@ -1,6 +1,6 @@
<template>
<view @click="handleClick" :class="rootClass" :style="rootStyle">
<image v-if="isImageUrl" class="wd-icon__image" :src="name"></image>
<image v-if="isImage" class="wd-icon__image" :src="name"></image>
</view>
</template>
@@ -16,35 +16,29 @@ export default {
</script>
<script lang="ts" setup>
import { computed, ref, watch } from 'vue'
import { objToStyle } from '../common/util'
import { computed, type CSSProperties } from 'vue'
import { addUnit, isDef, objToStyle, isImageUrl } from '../common/util'
import { iconProps } from './types'
const props = defineProps(iconProps)
const emit = defineEmits(['click'])
const emit = defineEmits(['click', 'touch'])
const isImageUrl = ref<boolean>(false)
watch(
() => props.name,
(val) => {
isImageUrl.value = val.indexOf('/') > -1
},
{ deep: true, immediate: true }
)
const isImage = computed(() => {
return isDef(props.name) && isImageUrl(props.name)
})
const rootClass = computed(() => {
const prefix = props.classPrefix
return `${prefix} ${props.customClass} ${isImageUrl.value ? 'wd-icon--image' : prefix + '-' + props.name}`
return `${prefix} ${props.customClass} ${isImage.value ? 'wd-icon--image' : prefix + '-' + props.name}`
})
const rootStyle = computed(() => {
const style: Record<string, any> = {}
const style: CSSProperties = {}
if (props.color) {
style['color'] = props.color
}
if (props.size) {
style['font-size'] = props.size
style['font-size'] = addUnit(props.size)
}
return `${objToStyle(style)}; ${props.customStyle}`
})
@@ -9,11 +9,13 @@
width: 100vw;
height: 100vh;
z-index: 1;
// 裁剪框包裹器
@include e(wrapper) {
position: relative;
background: rgba(0, 0, 0, 0.45);
}
@include e(cut) {
z-index: 9;
position: absolute;
@@ -30,21 +32,26 @@
// 拖动中背景蒙层为0 拖动结束为0.85
background-color: rgba(0, 0, 0, 0.85);
transition: background 0.2s;
@include when(hightlight) {
background-color: rgba(0, 0, 0, 0);
}
}
.wd-img-cropper__cut--bottom,
.wd-img-cropper__cut--right {
flex: auto;
}
@include m(middle) {
display: flex;
}
@include m(body) {
// 若需要变化窗体大小支持控制窗体的大小来控制下方所有对应的展示
background-color: transparent;
position: relative;
// 节选框的窗体最外部边缘线
&::before {
content: "";
@@ -59,6 +66,7 @@
// 结算框对角尺寸
$border-size: 2px;
// 节选框的四个角
.is-left-top,
.is-left-bottom,
@@ -71,6 +79,7 @@
height: 20px;
background-color: #fff;
}
&::after {
content: "";
position: absolute;
@@ -79,28 +88,36 @@
background-color: #fff;
}
}
.is-left-top {
&::before,
&::after {
left: -$border-size;
top: -$border-size;
}
}
.is-left-bottom {
&::before,
&::after {
left: -$border-size;
bottom: -$border-size;
}
}
.is-right-top {
&::before,
&::after {
right: -$border-size;
top: -$border-size;
}
}
.is-right-bottom {
&::before,
&::after {
right: -$border-size;
@@ -118,8 +135,10 @@
top: 0;
display: flex;
}
.is-gridlines-x {
justify-content: center;
&::before {
content: "";
display: inline-block;
@@ -131,9 +150,11 @@
transform: scale(0.5) translate(0, -50%);
}
}
// 内部网格线 - y轴
.is-gridlines-y {
align-items: center;
&::after {
content: "";
flex-shrink: 0;
@@ -148,6 +169,7 @@
}
}
}
@include e(img) {
z-index: 2;
top: 0;
@@ -158,6 +180,7 @@
backface-visibility: hidden;
transform-origin: center;
}
@include e(canvas) {
position: fixed;
background: white;
@@ -167,6 +190,7 @@
top: -200%;
pointer-events: none;
}
@include e(footer) {
position: fixed;
z-index: 10;
@@ -174,6 +198,7 @@
width: 100%;
height: 15vh;
text-align: center;
@include m(button) {
position: relative;
text-align: left;
@@ -181,11 +206,13 @@
padding-top: 4vh;
// line-height: 32px;
box-sizing: border-box;
.is-cancel {
display: inline-block;
color: #fff;
font-size: 16px;
}
.is-confirm {
position: absolute;
right: 0;
@@ -196,4 +223,9 @@
}
}
}
}
@include edeep(rotate) {
font-size: $-img-cropper-icon-size;
color: $-img-cropper-icon-color;
}
}
@@ -1,4 +1,13 @@
import type { ExtractPropTypes } from 'vue'
/*
* @Author: weisheng
* @Date: 2024-06-03 23:43:43
* @LastEditTime: 2024-06-06 21:40:53
* @LastEditors: weisheng
* @Description:
* @FilePath: /wot-design-uni/src/uni_modules/wot-design-uni/components/wd-img-cropper/types.ts
*
*/
import type { ComponentPublicInstance, ExtractPropTypes } from 'vue'
import { baseProps, makeBooleanProp, makeNumberProp, makeNumericProp, makeStringProp } from '../common/props'
export const imgCropperProps = {
@@ -58,4 +67,15 @@ export type ImgCropperExpose = {
* 使
*/
revertIsAnimation: (animation: boolean) => void
/**
*
*/
resetImg: () => void
/**
*
* @param angle
*/
setRoate: (angle: number) => void
}
export type ImgCropperInstance = ComponentPublicInstance<ImgCropperProps, ImgCropperExpose>

Some files were not shown because too many files have changed in this diff Show More