mirror of
https://gitee.com/xiangheng/x_admin.git
synced 2026-04-22 22:57:15 +08:00
升级依赖
This commit is contained in:
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"cSpell.words": [
|
||||
"goreleaser"
|
||||
]
|
||||
}
|
||||
@@ -15,6 +15,7 @@ pnpm-lock.yaml
|
||||
*.njsproj
|
||||
*.sln
|
||||
stats.html
|
||||
.hbuilderx
|
||||
.vscode/*
|
||||
!/.vscode/settings.json
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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);
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -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": {
|
||||
|
||||
@@ -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.15(2024-06-14)
|
||||
1. 修复上次更改引出的BUG
|
||||
## 1.0.14(2024-05-31)
|
||||
1. 修复设置maxDate后存在选择不准确的BUG
|
||||
## 1.0.13(2024-03-22)
|
||||
|
||||
+1
-1
@@ -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.24(2024-06-04)
|
||||
### [1.2.24](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.2.23...v1.2.24) (2024-06-03)
|
||||
## 1.8.0(2025-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新增customInputClass,placeholderClass等属性 ([#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是视频链接则为true,否则为false。
|
||||
*/
|
||||
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是图片格式,则为true;否则为false。
|
||||
*/
|
||||
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 = {
|
||||
|
||||
+10
-5
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+18
-7
@@ -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) {
|
||||
|
||||
+60
-32
@@ -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)
|
||||
}
|
||||
|
||||
+45
-27
@@ -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
|
||||
}
|
||||
|
||||
+5
-1
@@ -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)) {
|
||||
|
||||
+1
@@ -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)
|
||||
|
||||
+30
-29
@@ -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
|
||||
|
||||
// 大于等于0且小于等于100
|
||||
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
|
||||
// 如果目前用户正在选择,需要在popup关闭时将数据重置回上次数据,popup 关闭时间 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-view滑动到selectItem的偏移量
|
||||
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-view滑动到selectItem的偏移量
|
||||
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>
|
||||
|
||||
+87
-70
@@ -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
|
||||
|
||||
+4
-2
@@ -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 // 判断startVal是否大于endVal
|
||||
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
|
||||
}
|
||||
}
|
||||
// 确保currentVal在startVal和endVal之间
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -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
|
||||
|
||||
+151
-146
@@ -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
|
||||
// 校准上下方picker的value值,与内部innerValue对应
|
||||
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 =
|
||||
|
||||
// 如果使用了自定义的的formatter,defaultDisplayFormat无效
|
||||
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 时间段类型 true:start | false:end
|
||||
* @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>
|
||||
|
||||
+74
-39
@@ -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>
|
||||
+140
@@ -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
|
||||
// 合并子组件的rules到父组件的rules
|
||||
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
Reference in New Issue
Block a user