forked from opentiny/tiny-vue
fix(build) 修复grid、pager组件bug
This commit is contained in:
parent
b17660f055
commit
31ff849040
|
@ -1,67 +0,0 @@
|
|||
# Change Log
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.0.6-mf.0](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/compare/@opentiny/vue-docs@1.0.5-mf.0...@opentiny/vue-docs@1.0.6-mf.0) (2023-02-08)
|
||||
|
||||
**Note:** Version bump only for package @opentiny/vue-docs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.0.5-mf.0](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/compare/@opentiny/vue-docs@1.0.4-mf.0...@opentiny/vue-docs@1.0.5-mf.0) (2023-02-08)
|
||||
|
||||
**Note:** Version bump only for package @opentiny/vue-docs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.0.4-mf.0](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/compare/@opentiny/vue-docs@1.0.3-mf.0...@opentiny/vue-docs@1.0.4-mf.0) (2023-02-08)
|
||||
|
||||
**Note:** Version bump only for package @opentiny/vue-docs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.0.3-mf.0](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/compare/@opentiny/vue-docs@1.0.2-mf.0...@opentiny/vue-docs@1.0.3-mf.0) (2023-02-08)
|
||||
|
||||
**Note:** Version bump only for package @opentiny/vue-docs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.0.2-mf.0](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/compare/@opentiny/vue-docs@1.0.1-beta.0...@opentiny/vue-docs@1.0.2-mf.0) (2023-02-08)
|
||||
|
||||
**Note:** Version bump only for package @opentiny/vue-docs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 1.0.1-beta.0 (2023-02-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 回退对tailwind的line-height的修改 ([8de2bb5](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/8de2bb50862e22a9810b5d2b8295d32f34710f4f))
|
||||
* 使用了按需导入插件,就不能用import default 导入 ([606b141](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/606b141690736753b20e12235e4e769187e044a5))
|
||||
* 修复 time-line 样例报错 ([502a0e6](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/502a0e635df59271ba6a1e56926c2e0d7f66adeb))
|
||||
* 修复工程样式问题,样式增加深度选择器 ([dd8d0c3](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/dd8d0c3c2cf02bf68303c33daa6d0301f7117e96))
|
||||
* 修正 DemoView 样式 ([e233e72](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/e233e72abdc56fbb4ac82f1ad22a872eb5a4ba35))
|
||||
* 修正 loading/custom-class.vue 的归属关系 ([480185f](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/480185fec93c863e25dfa6c4ed3e5e40cf839700))
|
||||
* 修正 md 路径问题以及全量引入 vue-icon ([3398881](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/3398881d1c986d398c88c2f2163598d4b48d9131))
|
||||
* 修正 md 文档中的表格样式 ([bbfaeb8](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/bbfaeb8d533f92a8d7010a67bd1fde7c7971dabb))
|
||||
* demo 链接一定要有后缀名;代码中不直接引用 common/adapter ([15341bd](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/15341bdb0195e545dfbc48c33b1c4e97722c6a96))
|
||||
* grid-basic-usage.md 文件放错了目录 ([649f932](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/649f932d93fbb118e1f86ef4ed102ed1cd0522ab))
|
||||
* tabs/lazy.vue 迁移回 pc 下 ([6c847d9](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/6c847d99c1f9233256879a93f1f5eca7556bbf4c))
|
||||
* tag-selectable.md 错误的同步到了 pc 目录下,重新 mv 到 mobile-first 下即可 ([47cdffa](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/47cdffa50e32a127558c83d0116cf76f30c99537))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* 搭建了基于 vitest 的单元测试和基于 playwright 的 E2E 测试 ([fdeddaf](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/fdeddaf6c753c737caf5434cea2c86cc4292a311))
|
|
@ -1,59 +0,0 @@
|
|||
# Change Log
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [0.1.6-mf.0](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/compare/vue2.7-example@0.1.5-mf.0...vue2.7-example@0.1.6-mf.0) (2023-02-08)
|
||||
|
||||
**Note:** Version bump only for package vue2.7-example
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.1.5-mf.0](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/compare/vue2.7-example@0.1.4-mf.0...vue2.7-example@0.1.5-mf.0) (2023-02-08)
|
||||
|
||||
**Note:** Version bump only for package vue2.7-example
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.1.4-mf.0](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/compare/vue2.7-example@0.1.3-mf.0...vue2.7-example@0.1.4-mf.0) (2023-02-08)
|
||||
|
||||
**Note:** Version bump only for package vue2.7-example
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.1.3-mf.0](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/compare/vue2.7-example@0.1.2-mf.0...vue2.7-example@0.1.3-mf.0) (2023-02-08)
|
||||
|
||||
**Note:** Version bump only for package vue2.7-example
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.1.2-mf.0](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/compare/vue2.7-example@0.1.1-beta.0...vue2.7-example@0.1.2-mf.0) (2023-02-08)
|
||||
|
||||
**Note:** Version bump only for package vue2.7-example
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 0.1.1-beta.0 (2023-02-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 尝试修复 vue2.7 启动包版本不匹配错误 ([d79b172](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/d79b17219a7dfdde9cd4621315264ec76b5306b2))
|
||||
* 使得针对不同版本Vue的类型扩展能正常工作 ([9fb7946](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/9fb79466ddc848385d4231bbee51c189a849868c))
|
||||
* 修正 tailwindcss-vite-plugin 根据 windows 斜杠路径找不到入口模块而报错的问题 ([4b37f4f](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/4b37f4f43f64588b223957fe362d29d59af98ba1))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* 搭建了基于 vitest 的单元测试和基于 playwright 的 E2E 测试 ([fdeddaf](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/fdeddaf6c753c737caf5434cea2c86cc4292a311))
|
||||
* 增加 vue2.7 的支持 ([ea71624](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/ea71624e33eef95536ad3adb66d5e646cf734cbe))
|
|
@ -1,66 +0,0 @@
|
|||
# Change Log
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [0.1.6-mf.0](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/compare/vue2-example@0.1.5-mf.0...vue2-example@0.1.6-mf.0) (2023-02-08)
|
||||
|
||||
**Note:** Version bump only for package vue2-example
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.1.5-mf.0](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/compare/vue2-example@0.1.4-mf.0...vue2-example@0.1.5-mf.0) (2023-02-08)
|
||||
|
||||
**Note:** Version bump only for package vue2-example
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.1.4-mf.0](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/compare/vue2-example@0.1.3-mf.0...vue2-example@0.1.4-mf.0) (2023-02-08)
|
||||
|
||||
**Note:** Version bump only for package vue2-example
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.1.3-mf.0](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/compare/vue2-example@0.1.2-mf.0...vue2-example@0.1.3-mf.0) (2023-02-08)
|
||||
|
||||
**Note:** Version bump only for package vue2-example
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.1.2-mf.0](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/compare/vue2-example@0.1.1-beta.0...vue2-example@0.1.2-mf.0) (2023-02-08)
|
||||
|
||||
**Note:** Version bump only for package vue2-example
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 0.1.1-beta.0 (2023-02-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 固定 npm3 版本,增加 @vue/babel jsx 插件 ([afe772c](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/afe772c1d779b9bae576e966bea9162bd6af4331))
|
||||
* 让 dev:vue2 正常运行 ([3dd1dd1](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/3dd1dd196dc0a7527860a4a04ca334ab8ebc27ac))
|
||||
* 使得针对不同版本Vue的类型扩展能正常工作 ([9fb7946](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/9fb79466ddc848385d4231bbee51c189a849868c))
|
||||
* 使用了按需导入插件,就不能用import default 导入 ([606b141](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/606b141690736753b20e12235e4e769187e044a5))
|
||||
* 缩小 tailwindcss content 的扫描返回,避免干扰 ([3012d46](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/3012d462c5adb29d3957d5f3b5c11f9adf71a55c))
|
||||
* 修复 loading 组件由于文件改名导致引用错误问题,同时删除无用文件 ([d63c084](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/d63c084595f3e9ba6845cf374bf4bee70949e90f))
|
||||
* 修正 inline-chunks 插件的逻辑,vite 插件改为从vue2/3工程加载 ([72b0926](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/72b0926998c5eefef4adbe01ecb881f888607145))
|
||||
* 修正 tailwindcss-vite-plugin 根据 windows 斜杠路径找不到入口模块而报错的问题 ([4b37f4f](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/4b37f4f43f64588b223957fe362d29d59af98ba1))
|
||||
* 修正 vue2 和 vue2.7 下扩展 ([ad71cc0](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/ad71cc096bdbb02b1070917e11bc5e48bab4ca19))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* 搭建了基于 vitest 的单元测试和基于 playwright 的 E2E 测试 ([fdeddaf](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/fdeddaf6c753c737caf5434cea2c86cc4292a311))
|
||||
* 使用 unocss 代替 tailwindcss 以获得更快的开发预览 ([585c7bc](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/585c7bc26b50203fdea7241f9e9b7f94cd785bac))
|
||||
* 增加 vue2.7 的支持 ([ea71624](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/ea71624e33eef95536ad3adb66d5e646cf734cbe))
|
|
@ -1,63 +0,0 @@
|
|||
# Change Log
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [0.1.6-mf.0](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/compare/vue3-example@0.1.5-mf.0...vue3-example@0.1.6-mf.0) (2023-02-08)
|
||||
|
||||
**Note:** Version bump only for package vue3-example
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.1.5-mf.0](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/compare/vue3-example@0.1.4-mf.0...vue3-example@0.1.5-mf.0) (2023-02-08)
|
||||
|
||||
**Note:** Version bump only for package vue3-example
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.1.4-mf.0](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/compare/vue3-example@0.1.3-mf.0...vue3-example@0.1.4-mf.0) (2023-02-08)
|
||||
|
||||
**Note:** Version bump only for package vue3-example
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.1.3-mf.0](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/compare/vue3-example@0.1.2-mf.0...vue3-example@0.1.3-mf.0) (2023-02-08)
|
||||
|
||||
**Note:** Version bump only for package vue3-example
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.1.2-mf.0](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/compare/vue3-example@0.1.1-beta.0...vue3-example@0.1.2-mf.0) (2023-02-08)
|
||||
|
||||
**Note:** Version bump only for package vue3-example
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 0.1.1-beta.0 (2023-02-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 让 dev:vue2 正常运行 ([3dd1dd1](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/3dd1dd196dc0a7527860a4a04ca334ab8ebc27ac))
|
||||
* 使得针对不同版本Vue的类型扩展能正常工作 ([9fb7946](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/9fb79466ddc848385d4231bbee51c189a849868c))
|
||||
* 使用了按需导入插件,就不能用import default 导入 ([606b141](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/606b141690736753b20e12235e4e769187e044a5))
|
||||
* 缩小 tailwindcss content 的扫描返回,避免干扰 ([3012d46](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/3012d462c5adb29d3957d5f3b5c11f9adf71a55c))
|
||||
* 修正 md 路径问题以及全量引入 vue-icon ([3398881](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/3398881d1c986d398c88c2f2163598d4b48d9131))
|
||||
* 修正 tailwindcss-vite-plugin 根据 windows 斜杠路径找不到入口模块而报错的问题 ([4b37f4f](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/4b37f4f43f64588b223957fe362d29d59af98ba1))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* 搭建了基于 vitest 的单元测试和基于 playwright 的 E2E 测试 ([fdeddaf](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/fdeddaf6c753c737caf5434cea2c86cc4292a311))
|
||||
* 使用 unocss 代替 tailwindcss 以获得更快的开发预览 ([585c7bc](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/585c7bc26b50203fdea7241f9e9b7f94cd785bac))
|
||||
* 增加 vue2.7 的支持 ([ea71624](https://codehub-dg-g.huawei.com/AIF/TINY/opentiny-vue/commits/ea71624e33eef95536ad3adb66d5e646cf734cbe))
|
|
@ -120,7 +120,7 @@ export const onPagerClick = ({ emit, props, vm }) => (event) => {
|
|||
|
||||
if (props.isBeforePageChange && newPage !== currentPage) {
|
||||
let params = { newPage, currentPage, callback }
|
||||
vm.$parent.beforePagerChangeHandler(params)
|
||||
vm.$parent.$parent.beforePagerChangeHandler(params)
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ import debounce from '../common/deps/debounce'
|
|||
import { toDateStr } from '../common/date'
|
||||
import { toJsonStr } from '../common/object'
|
||||
import { toJson } from '../common/string'
|
||||
import { log } from '../common'
|
||||
import { log } from '../common/xss'
|
||||
|
||||
const request = {
|
||||
timmer: null,
|
||||
|
|
|
@ -95,7 +95,6 @@
|
|||
}
|
||||
|
||||
&.is-popup {
|
||||
|
||||
svg {
|
||||
display: var(--ti-pager-dot-is-popup-display);
|
||||
}
|
||||
|
@ -248,9 +247,9 @@
|
|||
|
||||
&__selector {
|
||||
.component-css-vars-pager();
|
||||
|
||||
|
||||
&.@{popover-prefix-cls}.@{popper-prefix-cls} {
|
||||
width: var(--ti-pager-body-width);
|
||||
width: var(--ti-pager-sizes-input-width);
|
||||
padding: 0;
|
||||
border-radius: var(--ti-pager-pop-body-border-radius);
|
||||
|
||||
|
@ -414,7 +413,8 @@
|
|||
font-size: 12px;
|
||||
}
|
||||
|
||||
.@{pager-prefix-cls}__btn-prev svg, .@{pager-prefix-cls}__btn-next svg {
|
||||
.@{pager-prefix-cls}__btn-prev svg,
|
||||
.@{pager-prefix-cls}__btn-next svg {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
|
@ -428,34 +428,35 @@
|
|||
line-height: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
&.is-disabled {
|
||||
.@{pager-prefix-cls}__total {
|
||||
color: #C2C2C2;
|
||||
color: #c2c2c2;
|
||||
}
|
||||
|
||||
ul li {
|
||||
cursor: not-allowed;
|
||||
color: #C2C2C2;
|
||||
color: #c2c2c2;
|
||||
background-color: transparent;
|
||||
|
||||
&.is-active, &:not(.dot):not(.is-active):hover {
|
||||
color: #C2C2C2;
|
||||
&.is-active,
|
||||
&:not(.dot):not(.is-active):hover {
|
||||
color: #c2c2c2;
|
||||
font-weight: normal;
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.@{pager-prefix-cls}__input input {
|
||||
color: #C2C2C2;
|
||||
color: #c2c2c2;
|
||||
cursor: not-allowed;
|
||||
border-color: #dbdbdb;
|
||||
background-color: #0000000D;
|
||||
background-color: #0000000d;
|
||||
}
|
||||
|
||||
.@{pager-prefix-cls}__input-btn svg {
|
||||
fill: #C2C2C2;
|
||||
color: #C2C2C2;
|
||||
fill: #c2c2c2;
|
||||
color: #c2c2c2;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@ export const tinyPagerSmbTheme = {
|
|||
'ti-pager-prev-next-hover-bg-color': 'transparent',
|
||||
'ti-pager-group-sizes-margin-right': '0px',
|
||||
'ti-pager-sizes-input-width': '78px',
|
||||
'ti-pager-body-width': '78px',
|
||||
'ti-pager-sizes-input-hover-text-color': '#595959',
|
||||
'ti-pager-input-btn-width': '16px',
|
||||
'ti-pager-input-btn-right': '12px',
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
// 分页输入框 光源的色
|
||||
--ti-pager-input-lighting-color: var(--ti-common-color-line-active);
|
||||
// 分页输入框圆角
|
||||
--ti-pager-input-border-radius: var(--ti-common-border-radius-normal);
|
||||
--ti-pager-input-border-radius: var(--ti-common-border-radius-normal);
|
||||
// 分页选择框|输入框|前往按钮高度
|
||||
--ti-pager-input-height: var(--ti-common-size-height-mini);
|
||||
// 分页输入框纵向内边距
|
||||
|
@ -63,13 +63,12 @@
|
|||
--ti-pager-poplist-item-unchecked-box-shadow: none;
|
||||
|
||||
// 分页项圆角
|
||||
--ti-pager-li-border-radius:var(--ti-common-border-radius-normal);
|
||||
--ti-pager-li-border-radius: var(--ti-common-border-radius-normal);
|
||||
// 分页项悬浮颜色
|
||||
--ti-pager-li-item-hover-text-color: var(--ti-common-color-text-highlight);
|
||||
// 分页项悬浮字重
|
||||
--ti-pager-li-item-hover-font-weight: var(--ti-common-font-weight-normal);
|
||||
|
||||
|
||||
// 分页项默认悬浮背景色
|
||||
--ti-pager-poplist-item-hover-bg-color: var(--ti-common-color-hover-background);
|
||||
// 分页下拉框项|列表项悬浮文本色
|
||||
|
@ -77,15 +76,13 @@
|
|||
// 分页下拉框选中项默认背景色
|
||||
--ti-pager-poplist-item-selected-bg-color: var(--ti-common-color-selected-background);
|
||||
// 分页下拉框项选中字体颜色
|
||||
--ti-pager-poplist-item-selected-text-color:var(--ti-common-color-selected-text-color);
|
||||
--ti-pager-poplist-item-selected-text-color: var(--ti-common-color-selected-text-color);
|
||||
// 分页页码项默认悬浮边框色
|
||||
--ti-pager-poplist-item-hover-border-color: var(--ti-common-color-transparent);
|
||||
// 分页下拉框圆角
|
||||
--ti-pager-pop-body-border-radius:var(--ti-common-border-radius-normal);
|
||||
--ti-pager-pop-body-border-radius: var(--ti-common-border-radius-normal);
|
||||
// 分页下拉框顶部外边距
|
||||
--ti-pager-pop-body-margin-top: 4px;
|
||||
// 分页下拉框宽度
|
||||
--ti-pager-body-width: 78px;
|
||||
// 分页下拉项最小高度
|
||||
--ti-pager-poplist-item-min-height: 30px;
|
||||
|
||||
|
@ -133,7 +130,7 @@
|
|||
// 分页页码项右侧外边距
|
||||
--ti-pager-group-sizes-margin-right: 16px;
|
||||
// 分页页码选项框宽度
|
||||
--ti-pager-sizes-input-width: 60px;
|
||||
--ti-pager-sizes-input-width: 78px;
|
||||
// 分页选择框悬浮文本色
|
||||
--ti-pager-sizes-input-hover-text-color: var(--ti-pager-normal-text-color);
|
||||
// 分页选择框右侧下拉按钮
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
// 弹框标题字号
|
||||
--ti-popover-title-font-size: var(--ti-common-font-size-2);
|
||||
// 弹出框小箭头边框厚度
|
||||
--ti-popover-arrow-border-width: calc(var(--ti-common-border-weight-2) * 3);
|
||||
--ti-popover-arrow-border-width: calc(var(--ti-common-border-weight-2) * 2);
|
||||
// 弹出框小箭头高度
|
||||
--ti-popover-arrow-height: var(--ti-popover-arrow-border-width);
|
||||
// 弹出框垂直外边距
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
<template>
|
||||
<div class="tiny-action-menu">
|
||||
<ul class="tiny-action-menu__wrap">
|
||||
<li
|
||||
v-for="(visableItem, index) in state.visibleOptions"
|
||||
:key="index"
|
||||
:class="['tiny-action-menu__item', 'tiny-action-menu__item-visable', { 'is-disabled': visableItem.disabled }]"
|
||||
>
|
||||
<tiny-dropdown-item :itemData="visableItem" :label="visableItem[textField]" :textField="textField" @item-click="handleItemClick">
|
||||
<template #default="{ itemData }">
|
||||
<slot name="item" :data="itemData"></slot>
|
||||
</template>
|
||||
</tiny-dropdown-item>
|
||||
<span class="tiny-action-menu__item-line" :style="{ margin: '0 ' + state.spacing }"></span>
|
||||
</li>
|
||||
|
||||
<li v-if="state.moreOptions.length" class="tiny-action-menu__item">
|
||||
<tiny-dropdown :title="moreText" :trigger="trigger" @item-click="handleItemClick" @handle-click="handleMoreClick" @visible-change="visibleChange">
|
||||
<template #dropdown>
|
||||
<tiny-dropdown-menu :textField="textField" :popperClass="popperClass">
|
||||
<tiny-dropdown-item v-for="(item, index) in state.moreOptions" :key="index" :itemData="item" :label="item[textField]">
|
||||
<template #default="{ itemData }">
|
||||
<slot name="item" :data="itemData"></slot>
|
||||
</template>
|
||||
</tiny-dropdown-item>
|
||||
</tiny-dropdown-menu>
|
||||
</template>
|
||||
</tiny-dropdown>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { setup, $prefix, defineComponent } from '@opentiny/vue-common'
|
||||
import { renderless, api } from '@opentiny/vue-renderless/action-menu/vue'
|
||||
import '@opentiny/vue-theme/action-menu/index.less'
|
||||
import Dropdown from '@opentiny/vue-dropdown'
|
||||
import DropdownMenu from '@opentiny/vue-dropdown-menu'
|
||||
import DropdownItem from '@opentiny/vue-dropdown-item'
|
||||
import { t } from '@opentiny/vue-locale'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'ActionMenu',
|
||||
components: {
|
||||
TinyDropdown: Dropdown,
|
||||
TinyDropdownMenu: DropdownMenu,
|
||||
TinyDropdownItem: DropdownItem
|
||||
},
|
||||
emits: ['more-click', 'item-click', 'visible-change'],
|
||||
props: {
|
||||
options: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
maxShowNum: {
|
||||
type: Number,
|
||||
default: 2
|
||||
},
|
||||
moreText: {
|
||||
type: String,
|
||||
default: t('ui.actionMenu.moreText')
|
||||
},
|
||||
spacing: {
|
||||
type: [String, Number],
|
||||
default: '5px'
|
||||
},
|
||||
textField: {
|
||||
type: String,
|
||||
default: 'label'
|
||||
},
|
||||
popperClass: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
popperAppendToBody: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
trigger: {
|
||||
type: String,
|
||||
default: 'hover'
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,86 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<div class="tiny-mobile-action-sheet" v-show="visible" @click="visibleHandle">
|
||||
<div class="tiny-mobile-action-sheet__mask" :style="state.sheetMaskStyle" v-if="!contentPosition"></div>
|
||||
<div
|
||||
:class="[
|
||||
'tiny-mobile-action-sheet__content',
|
||||
state.toggle ? 'is-toggle' : '',
|
||||
contentPosition ? '' : 'is-not-content'
|
||||
]"
|
||||
:style="[state.sheetContentStyle]"
|
||||
ref="scrollMenu"
|
||||
>
|
||||
<div :class="['tiny-mobile-action-sheet__menu', ellipsis ? 'is-ellipsis' : '']">
|
||||
<div
|
||||
:class="[
|
||||
'tiny-mobile-action-sheet__item',
|
||||
item.warn ? 'is-warn' : '',
|
||||
item.id === modelValue || item.id === state.active ? 'is-active' : ''
|
||||
]"
|
||||
v-for="(item, index) in menus"
|
||||
:key="index"
|
||||
@click="menuHandle(item, index)"
|
||||
>
|
||||
<slot name="item" :item="item">
|
||||
{{ item.label }}
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tiny-mobile-action-sheet__action" v-if="contentPosition">
|
||||
<slot name="action">
|
||||
<div class="tiny-mobile-action-sheet__cancel" @click="visibleHandle">
|
||||
{{ t('ui.actionSheet.cancel') }}
|
||||
</div>
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { renderless, api } from '@opentiny/vue-renderless/action-sheet/vue'
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
import '@opentiny/vue-theme-mobile/action-sheet/index.less'
|
||||
import BScroll from '@better-scroll/core'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'ActionSheet',
|
||||
props: {
|
||||
menus: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
modelValue: [Number, String],
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
ellipsis: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: '200px'
|
||||
},
|
||||
contentPosition: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true, extendOptions: { BScroll } })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,163 +0,0 @@
|
|||
<template>
|
||||
<div ref="root" class="tiny-amount" v-bind="a($attrs, ['^on[A-Z]'])">
|
||||
<tiny-popover
|
||||
v-model="state.visible"
|
||||
placement="bottom-start"
|
||||
:popper-class="'tiny-amount-popper' + (popperClass ? ' ' + popperClass : '')"
|
||||
trigger="manual"
|
||||
:append-to-body="popperAppendToBody"
|
||||
>
|
||||
<template #reference>
|
||||
<tiny-input
|
||||
:tabindex="tabindex"
|
||||
:size="size"
|
||||
:modelValue="getAmountText()"
|
||||
:maxlength="maxLen"
|
||||
:placeholder="placeholder"
|
||||
:disabled="disabled"
|
||||
@focus="inputFocus"
|
||||
@blur="inputBlur"
|
||||
@update:modelValue="onInput"
|
||||
>
|
||||
<template #suffix>
|
||||
<div @click="toggleVisible" class="tiny-amount-input-icon">
|
||||
<icon-coin class="tiny-svg-size" />
|
||||
</div>
|
||||
</template>
|
||||
</tiny-input>
|
||||
</template>
|
||||
<div class="popover-con" ref="popover">
|
||||
<div class="module" v-if="popUp">
|
||||
<div class="popover-left">{{ t('ui.amount.currency') }}</div>
|
||||
<tiny-currency
|
||||
class="popover-right"
|
||||
v-model="editorState.currency"
|
||||
:clearable="false"
|
||||
:fields="fields"
|
||||
:fetch-currency="fetchCurrency"
|
||||
:popper-class="popperClass"
|
||||
:popper-append-to-body="popperAppendToBody"
|
||||
:currency="currency"
|
||||
></tiny-currency>
|
||||
</div>
|
||||
<div v-if="date || dateAllowEmpty" class="module">
|
||||
<div class="popover-left">{{ t('ui.amount.date') }}</div>
|
||||
<tiny-date-picker
|
||||
class="popover-right"
|
||||
v-model="editorState.date"
|
||||
:popper-class="'tiny-amount-popper' + (popperClass ? ' ' + popperClass : '')"
|
||||
:popper-append-to-body="popperAppendToBody"
|
||||
></tiny-date-picker>
|
||||
</div>
|
||||
<div class="module">
|
||||
<div class="popover-left">{{ t('ui.amount.amount') }}</div>
|
||||
<tiny-input class="popover-right" v-model="editorState.amount" @update:modelValue="popInput" :maxlength="maxLen"></tiny-input>
|
||||
</div>
|
||||
<div class="module">
|
||||
<tiny-button type="primary" @click="save">{{ t('ui.base.confirm') }}</tiny-button>
|
||||
<tiny-button @click="reset">{{ t('ui.base.reset') }}</tiny-button>
|
||||
</div>
|
||||
</div>
|
||||
</tiny-popover>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import Popover from '@opentiny/vue-popover'
|
||||
import Input from '@opentiny/vue-input'
|
||||
import Currency from '@opentiny/vue-currency'
|
||||
import Button from '@opentiny/vue-button'
|
||||
import DatePicker from '@opentiny/vue-date-picker'
|
||||
import { IconCoin } from '@opentiny/vue-icon'
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
import { renderless, api } from '@opentiny/vue-renderless/amount/vue'
|
||||
|
||||
export default defineComponent({
|
||||
inheritAttrs: false,
|
||||
name: $prefix + 'Amount',
|
||||
components: {
|
||||
TinyPopover: Popover,
|
||||
TinyInput: Input,
|
||||
TinyButton: Button,
|
||||
TinyCurrency: Currency,
|
||||
TinyDatePicker: DatePicker,
|
||||
IconCoin: IconCoin()
|
||||
},
|
||||
props: {
|
||||
modelValue: {
|
||||
type: [Number, String]
|
||||
},
|
||||
tabindex: { type: String, default: '1' },
|
||||
size: String,
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
currency: {
|
||||
type: String,
|
||||
default: 'CNY'
|
||||
},
|
||||
date: [String, Date],
|
||||
dateAllowEmpty: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
digits: {
|
||||
type: Number,
|
||||
default: 2
|
||||
},
|
||||
rounding: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
maxLen: {
|
||||
type: Number,
|
||||
default: 15
|
||||
},
|
||||
negative: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
fetchCurrency: Function,
|
||||
fields: Object,
|
||||
popperClass: String,
|
||||
popperAppendToBody: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
format: Object,
|
||||
type: {
|
||||
type: String,
|
||||
default: 'amount'
|
||||
},
|
||||
holdZero: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
modelTruncation: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
strictInput: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
plugin: Function,
|
||||
popUp: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
hideCurrency: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,69 +0,0 @@
|
|||
<script lang="tsx">
|
||||
import { setup, $prefix, defineComponent } from '@opentiny/vue-common'
|
||||
import { renderless, api } from '@opentiny/vue-renderless/anchor/vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'Anchor',
|
||||
props: {
|
||||
isAffix: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
links: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
containerId: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
markClass: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
emits: ['linkClick', 'onChange'],
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api })
|
||||
},
|
||||
render() {
|
||||
const {
|
||||
isAffix,
|
||||
links,
|
||||
linkClick,
|
||||
state: { currentLink }
|
||||
} = this
|
||||
const anchorClass = 'tiny-anchor'
|
||||
|
||||
const renderLinks = (links) =>
|
||||
Array.isArray(links)
|
||||
? links.map((item) => (
|
||||
<div class={`${anchorClass}-link`} key={item.key}>
|
||||
<a
|
||||
href={item.link}
|
||||
class={[`${anchorClass}-link-title`, currentLink === item.link && `${anchorClass}-link-title--active`]}
|
||||
title={item.title}
|
||||
onClick={(e) => linkClick(e, item)}
|
||||
ref={item.link}
|
||||
>
|
||||
{item.title}
|
||||
</a>
|
||||
{item.children ? renderLinks(item.children) : null}
|
||||
</div>
|
||||
))
|
||||
: null
|
||||
|
||||
return (
|
||||
<div class={[isAffix ? `${anchorClass}__affix` : '', `${anchorClass}__wrapper`]} ref={isAffix ? 'fixRef' : ''}>
|
||||
<div class={anchorClass} ref="anchorRef">
|
||||
<div class={`${anchorClass}-link-mask`} ref="maskRef"></div>
|
||||
<div class={`${anchorClass}-orbit`}>
|
||||
<div class={`${anchorClass}-orbit-skid`} ref="skidRef"></div>
|
||||
</div>
|
||||
{links && renderLinks(links)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,115 +0,0 @@
|
|||
<template>
|
||||
<div class="tiny-area">
|
||||
<tiny-select
|
||||
:popper-class="'tiny-area-jcr' + (popperClass ? ' ' + popperClass : '')"
|
||||
:popper-append-to-body="popperAppendToBody"
|
||||
:size="size"
|
||||
v-model="state.jcr"
|
||||
:placeholder="placeholder"
|
||||
@change="getRegion"
|
||||
:disabled="disabled"
|
||||
ref="refInstance"
|
||||
v-bind="a($attrs, ['^on[A-Z]'])"
|
||||
@clear="$emit('clear')"
|
||||
@visible-change="$emit('visible-change', $event)"
|
||||
>
|
||||
<tiny-option v-for="item in state.jcrData" :key="item[props.value]" :label="item[props.label]" :value="item[props.value]"> </tiny-option>
|
||||
</tiny-select>
|
||||
<tiny-select
|
||||
:popper-class="'tiny-area-region' + (popperClass ? ' ' + popperClass : '')"
|
||||
:popper-append-to-body="popperAppendToBody"
|
||||
:size="size"
|
||||
v-model="state.region"
|
||||
:placeholder="placeholder"
|
||||
@change="getRep"
|
||||
:disabled="disabled"
|
||||
v-bind="a($attrs, ['^on[A-Z]'])"
|
||||
@clear="$emit('clear')"
|
||||
@visible-change="$emit('visible-change', $event)"
|
||||
>
|
||||
<tiny-option v-for="item in state.regionData" :key="item[props.value]" :label="item[props.label]" :value="item[props.value]"> </tiny-option>
|
||||
</tiny-select>
|
||||
<tiny-select
|
||||
:popper-class="'tiny-area-rep' + (popperClass ? ' ' + popperClass : '')"
|
||||
:popper-append-to-body="popperAppendToBody"
|
||||
:size="size"
|
||||
v-model="state.rep"
|
||||
:placeholder="placeholder"
|
||||
@change="getOffice"
|
||||
:disabled="disabled"
|
||||
v-bind="a($attrs, ['^on[A-Z]'])"
|
||||
@clear="$emit('clear')"
|
||||
@visible-change="$emit('visible-change', $event)"
|
||||
>
|
||||
<tiny-option v-for="item in state.repData" :key="item[props.value]" :label="item[props.label]" :value="item[props.value]"> </tiny-option>
|
||||
</tiny-select>
|
||||
<tiny-select
|
||||
:popper-class="'tiny-area-office' + (popperClass ? ' ' + popperClass : '')"
|
||||
:popper-append-to-body="popperAppendToBody"
|
||||
:size="size"
|
||||
v-model="state.office"
|
||||
:placeholder="placeholder"
|
||||
:disabled="disabled"
|
||||
@change="changeOffice"
|
||||
v-bind="a($attrs, ['^on[A-Z]'])"
|
||||
@clear="$emit('clear')"
|
||||
@visible-change="$emit('visible-change', $event)"
|
||||
>
|
||||
<tiny-option v-for="item in state.officeData" :key="item[props.value]" :label="item[props.label]" :value="item[props.value]"> </tiny-option>
|
||||
</tiny-select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
import { renderless, api } from '@opentiny/vue-renderless/area/vue'
|
||||
import Select from '@opentiny/vue-select'
|
||||
import Option from '@opentiny/vue-option'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'Area',
|
||||
components: {
|
||||
TinySelect: Select,
|
||||
TinyOption: Option
|
||||
},
|
||||
props: {
|
||||
modelValue: {},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
size: String,
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
props: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
label: 'name_cn',
|
||||
value: 'org_id'
|
||||
})
|
||||
},
|
||||
fetchJcr: {
|
||||
type: Function
|
||||
},
|
||||
fetchRegion: {
|
||||
type: Function
|
||||
},
|
||||
fetchRep: {
|
||||
type: Function
|
||||
},
|
||||
fetchOffice: {
|
||||
type: Function
|
||||
},
|
||||
popperClass: String,
|
||||
popperAppendToBody: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,95 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<script lang="tsx">
|
||||
import { $prefix, setup, h, defineComponent } from '@opentiny/vue-common'
|
||||
import { renderless, api } from '@opentiny/vue-renderless/avatar/vue'
|
||||
|
||||
const $constants = {
|
||||
COMPONENT_PREFIX: 'tiny-mobile-avatar',
|
||||
ICON: 'icon'
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'Avatar',
|
||||
props: {
|
||||
_constants: {
|
||||
type: Object,
|
||||
default: () => $constants
|
||||
},
|
||||
alt: String,
|
||||
error: Function,
|
||||
fit: {
|
||||
type: String,
|
||||
default: 'cover'
|
||||
},
|
||||
icon: Object,
|
||||
shape: {
|
||||
type: String,
|
||||
default: 'circle',
|
||||
validator(val) {
|
||||
return ~['circle', 'square'].indexOf(val)
|
||||
}
|
||||
},
|
||||
size: {
|
||||
type: [Number, String],
|
||||
validator(val) {
|
||||
return typeof val === 'string' ? ~['large', 'medium', 'small'].indexOf(val) : typeof val === 'number'
|
||||
}
|
||||
},
|
||||
src: String,
|
||||
srcSet: String
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true, h })
|
||||
},
|
||||
render() {
|
||||
const {
|
||||
alt,
|
||||
fit,
|
||||
icon: Icon,
|
||||
size,
|
||||
src,
|
||||
srcSet,
|
||||
state: { isImageExist, avatarClass }
|
||||
} = this
|
||||
|
||||
const hasImageSrc = isImageExist && src
|
||||
let sizeStyle = {}
|
||||
|
||||
if (typeof size === 'number') {
|
||||
sizeStyle = {
|
||||
height: `${size}px`,
|
||||
width: `${size}px`,
|
||||
lineHeight: `${size}px`
|
||||
}
|
||||
}
|
||||
|
||||
const renderAvatar = () => {
|
||||
if (hasImageSrc) {
|
||||
return <img src={src} alt={alt} srcSet={srcSet} style={{ 'object-fit': fit }} onError={this.handleError} />
|
||||
}
|
||||
|
||||
if (Icon) {
|
||||
return <Icon />
|
||||
}
|
||||
|
||||
return this.$slots.default && this.$slots.default()
|
||||
}
|
||||
|
||||
return (
|
||||
<span class={avatarClass} style={sizeStyle}>
|
||||
{renderAvatar()}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,159 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<script lang="tsx">
|
||||
import { renderless, api } from '@opentiny/vue-renderless/cascader-node/vue'
|
||||
import { $prefix, setup, h, defineComponent } from '@opentiny/vue-common'
|
||||
import Checkbox from '@opentiny/vue-checkbox'
|
||||
import Radio from '@opentiny/vue-radio'
|
||||
import { isEqual } from '@opentiny/vue-renderless/common/object'
|
||||
import { iconLoading, iconChevronRight, iconYes } from '@opentiny/vue-icon'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'CascaderNode',
|
||||
components: {
|
||||
TinyCheckbox: Checkbox,
|
||||
TinyRadio: Radio,
|
||||
IconYes: iconYes(),
|
||||
IconLoading: iconLoading(),
|
||||
IconChevronRight: iconChevronRight()
|
||||
},
|
||||
inheritAttrs: false,
|
||||
emits: ['expand', 'update:modelValue', 'expand-change', 'active-item-change', 'change'],
|
||||
inject: ['panel'],
|
||||
props: {
|
||||
node: {
|
||||
required: true
|
||||
},
|
||||
nodeId: String
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
},
|
||||
render() {
|
||||
const renderPrefix = (h) => {
|
||||
const { isLeaf, isChecked, config } = this.state
|
||||
const { checkStrictly, multiple } = config
|
||||
|
||||
if (multiple) {
|
||||
return renderCheckbox(h)
|
||||
} else if (checkStrictly) {
|
||||
return renderRadio(h)
|
||||
} else if (isLeaf && isChecked) {
|
||||
return renderCheckIcon(h)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
const renderPostfix = (h) => {
|
||||
const { node, state } = this
|
||||
|
||||
if (node.loading) {
|
||||
return renderLoadingIcon(h)
|
||||
} else if (!state.isLeaf) {
|
||||
return renderExpandIcon(h)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
const stopPropagation = (e) => e.stopPropagation()
|
||||
|
||||
const renderCheckbox = () => {
|
||||
const { state, node } = this
|
||||
|
||||
return (
|
||||
<tiny-checkbox
|
||||
modelValue={node.checked}
|
||||
indeterminate={node.indeterminate}
|
||||
disabled={state.isDisabled}
|
||||
onChange={this.handleMultiCheckChange}
|
||||
nativeOnClick={stopPropagation}
|
||||
></tiny-checkbox>
|
||||
)
|
||||
}
|
||||
|
||||
const renderRadio = () => {
|
||||
let { checkedValue, value, isDisabled } = this.state
|
||||
|
||||
if (isEqual(value, checkedValue)) {
|
||||
value = checkedValue
|
||||
}
|
||||
|
||||
return (
|
||||
<tiny-radio v-model={checkedValue} disabled={isDisabled} label={value} nativeOnClick={stopPropagation} onChange={this.handleCheckChange}>
|
||||
<span></span>
|
||||
</tiny-radio>
|
||||
)
|
||||
}
|
||||
|
||||
const renderCheckIcon = () => <icon-yes class="tiny-cascader-node__prefix"></icon-yes>
|
||||
|
||||
const renderLoadingIcon = () => <icon-loading class="tiny-cascader-node__postfix"></icon-loading>
|
||||
|
||||
const renderExpandIcon = () => <icon-chevron-right class="tiny-cascader-node__postfix"></icon-chevron-right>
|
||||
|
||||
const renderContent = () => {
|
||||
const { panel, node } = this
|
||||
const render = panel.state.renderLabelFn
|
||||
const vnode = render ? render({ node, data: node.data }) : null
|
||||
|
||||
return <span class="tiny-cascader-node__label">{vnode || node.label}</span>
|
||||
}
|
||||
|
||||
const { state } = this
|
||||
const { checkStrictly, expandTrigger, multiple } = state.config
|
||||
const disabled = !checkStrictly && state.isDisabled
|
||||
const events = {}
|
||||
|
||||
events.on = {}
|
||||
|
||||
if (expandTrigger === 'click') {
|
||||
events.on.click = this.handleExpand
|
||||
} else {
|
||||
const handler = (e) => {
|
||||
this.handleExpand()
|
||||
this.$emit('expand', e)
|
||||
}
|
||||
|
||||
events.on.mouseenter = handler
|
||||
events.on.focus = handler
|
||||
}
|
||||
|
||||
if (state.isLeaf && !(state.isDisabled || checkStrictly || multiple)) {
|
||||
events.on.click = this.handleCheckChange
|
||||
}
|
||||
|
||||
return h(
|
||||
'li',
|
||||
{
|
||||
attrs: {
|
||||
role: 'menuitem',
|
||||
id: this.nodeId,
|
||||
tabindex: disabled ? null : -1,
|
||||
'aria-expanded': state.inActivePath
|
||||
},
|
||||
class: {
|
||||
'tiny-cascader-node': true,
|
||||
'is-selectable': checkStrictly,
|
||||
'in-active-path': state.inActivePath,
|
||||
'in-checked-path': state.inCheckedPath,
|
||||
'is-active': state.isChecked,
|
||||
'is-disabled': disabled
|
||||
},
|
||||
...events
|
||||
},
|
||||
[renderPrefix(h), renderContent(h), renderPostfix(h)]
|
||||
)
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,49 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<div :class="['tiny-cascader-panel', border && 'is-bordered']" @keydown="handleKeyDown">
|
||||
<cascader-menu v-for="(menu, index) in state.menus" :index="index" :key="index" :nodes="menu"></cascader-menu>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
import { renderless, api } from '@opentiny/vue-renderless/cascader-panel/vue'
|
||||
import CascaderMenu from '@opentiny/vue-cascader-menu'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'CascaderPanel',
|
||||
componentName: $prefix + 'CascaderPanel',
|
||||
components: {
|
||||
CascaderMenu
|
||||
},
|
||||
props: {
|
||||
modelValue: {},
|
||||
options: Array,
|
||||
props: Object,
|
||||
border: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
renderLabel: Function
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
panel: this
|
||||
}
|
||||
},
|
||||
emits: ['update:modelValue', 'change', 'close', 'active-item-change', 'expand-change'],
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,96 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<transition v-on="on">
|
||||
<!-- default slot -->
|
||||
<slot></slot>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { addClass as addCls, removeClass as rmvCls } from '@opentiny/vue-renderless/common/deps/dom'
|
||||
import { $prefix, defineComponent } from '@opentiny/vue-common'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'CollapseTransition',
|
||||
setup() {
|
||||
return {
|
||||
on: {
|
||||
beforeEnter(elem) {
|
||||
addCls(elem, 'collapse-transition')
|
||||
|
||||
if (!elem.dataset) elem.dataset = {}
|
||||
|
||||
elem.dataset.oldPaddingBottom = elem.style.paddingBottom
|
||||
elem.dataset.oldPaddingTop = elem.style.paddingTop
|
||||
elem.style.height = '0'
|
||||
elem.style.paddingTop = 0
|
||||
elem.style.paddingBottom = 0
|
||||
},
|
||||
|
||||
enter(elem) {
|
||||
elem.dataset.oldOverflow = elem.style.overflow
|
||||
|
||||
if (elem.scrollHeight === 0) {
|
||||
elem.style.height = ''
|
||||
elem.style.paddingBottom = elem.dataset.oldPaddingBottom
|
||||
elem.style.paddingTop = elem.dataset.oldPaddingTop
|
||||
} else {
|
||||
elem.style.height = elem.scrollHeight + 'px'
|
||||
elem.style.paddingBottom = elem.dataset.oldPaddingBottom
|
||||
elem.style.paddingTop = elem.dataset.oldPaddingTop
|
||||
}
|
||||
|
||||
elem.style.overflow = 'hidden'
|
||||
},
|
||||
|
||||
afterEnter(elem) {
|
||||
rmvCls(elem, 'collapse-transition')
|
||||
|
||||
elem.style.height = ''
|
||||
elem.style.overflow = elem.dataset.oldOverflow
|
||||
},
|
||||
|
||||
beforeLeave(elem) {
|
||||
if (!elem.dataset) elem.dataset = {}
|
||||
|
||||
elem.dataset.oldOverflow = elem.style.overflow
|
||||
elem.dataset.oldPaddingBottom = elem.style.paddingBottom
|
||||
elem.dataset.oldPaddingTop = elem.style.paddingTop
|
||||
elem.style.height = elem.scrollHeight + 'px'
|
||||
elem.style.overflow = 'hidden'
|
||||
},
|
||||
|
||||
leave(elem) {
|
||||
if (elem.scrollHeight === 0) return
|
||||
|
||||
addCls(elem, 'collapse-transition')
|
||||
|
||||
elem.style.transitionProperty = 'height'
|
||||
elem.style.height = 0
|
||||
elem.style.paddingTop = 0
|
||||
elem.style.paddingBottom = 0
|
||||
},
|
||||
|
||||
afterLeave(elem) {
|
||||
rmvCls(elem, 'collapse-transition')
|
||||
|
||||
elem.style.height = ''
|
||||
elem.style.overflow = elem.dataset.oldOverflow
|
||||
elem.style.paddingBottom = elem.dataset.oldPaddingBottom
|
||||
elem.style.paddingTop = elem.dataset.oldPaddingTop
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,205 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<div class="tiny-crop__wrapper">
|
||||
<div class="tiny-croppreview" :style="{ opacity: state.cropvisible ? 1 : 0 }" v-if="preview">
|
||||
<div class="croppreviewb">
|
||||
<div class="croppreview"></div>
|
||||
</div>
|
||||
<div class="croppreviewm">
|
||||
<div class="croppreview"></div>
|
||||
</div>
|
||||
<div class="croppreviews">
|
||||
<div class="croppreview"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tiny-crop" v-show="state.cropvisible">
|
||||
<div class="tiny-crop__dialog">
|
||||
<input ref="cropInput" type="file" name="image" accept="image/*" @change="setImage" />
|
||||
<div class="tiny-crop__dialog-cropper">
|
||||
<img :src="state.src" ref="cropImage" id="crops" :alt="state.alt" />
|
||||
</div>
|
||||
<div class="tiny-crop__dialog-content__handle">
|
||||
<div class="tiny-crop__dialog-content__handle__button">
|
||||
<div v-for="(item, index) in state.renderIcon" class="iconButton" @click.prevent="item.method" :key="index">
|
||||
<component :is="item.icon" class="iconButtonset"></component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tiny-crop__dialog-content">
|
||||
<div class="tiny-crop__dialog-content__crop">
|
||||
<img v-if="state.cropImg" :src="state.cropImg" alt="post-crop" />
|
||||
<h1 v-else>
|
||||
{{ t('ui.crop.croppedImage') }}
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
import { renderless, api } from '@opentiny/vue-renderless/crop/vue'
|
||||
import {
|
||||
iconConmentRefresh,
|
||||
iconNew,
|
||||
iconZoomIn,
|
||||
iconZoomOut,
|
||||
iconRepeat,
|
||||
iconRefres,
|
||||
iconClose,
|
||||
iconYes,
|
||||
iconCrop
|
||||
} from '@opentiny/vue-icon'
|
||||
import Cropper from 'cropperjs'
|
||||
import 'cropperjs/dist/cropper.css'
|
||||
|
||||
const $constants = {
|
||||
CROP_IMAGE: 'ui.crop.cropImage'
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'Crop',
|
||||
components: {
|
||||
IconConmentRefresh: iconConmentRefresh(),
|
||||
IconNew: iconNew(),
|
||||
IconZoomIn: iconZoomIn(),
|
||||
IconZoomOut: iconZoomOut(),
|
||||
IconRepeat: iconRepeat(),
|
||||
IconRefres: iconRefres(),
|
||||
IconClose: iconClose(),
|
||||
IconYes: iconYes(),
|
||||
IconCrop: iconCrop()
|
||||
},
|
||||
props: {
|
||||
_constants: {
|
||||
type: Object,
|
||||
default: () => $constants
|
||||
},
|
||||
alt: {
|
||||
type: String,
|
||||
default: 'image'
|
||||
},
|
||||
aspectRatio: {
|
||||
type: Number,
|
||||
default: 16 / 9
|
||||
},
|
||||
autoCrop: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
autoCropArea: {
|
||||
type: Number,
|
||||
default: 0.8
|
||||
},
|
||||
background: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
center: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
cropType: {
|
||||
type: String,
|
||||
default: 'base64'
|
||||
},
|
||||
cropvisible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
dragMode: {
|
||||
type: String,
|
||||
default: 'crop'
|
||||
},
|
||||
guides: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
maxSize: {
|
||||
type: String,
|
||||
default: '1M'
|
||||
},
|
||||
minContainerHeight: {
|
||||
type: Number,
|
||||
default: 300
|
||||
},
|
||||
minContainerWidth: {
|
||||
type: Number,
|
||||
default: 652
|
||||
},
|
||||
minCropBoxHeight: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
minCropBoxWidth: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
modal: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
movable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
plugin: {
|
||||
type: [Object, Function],
|
||||
default: () => Cropper
|
||||
},
|
||||
preview: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
previewShow: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
quality: {
|
||||
type: Number,
|
||||
default: 0.92,
|
||||
validator: (value: number) => value <= 1 && value > 0
|
||||
},
|
||||
rotatable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
src: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
viewMode: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
wheelZoomRatio: {
|
||||
type: Number,
|
||||
default: 0.1
|
||||
},
|
||||
zoomOnWheel: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
zoomable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
emits: ['update:cropvisible', 'update:visible', 'ready', 'cropstart', 'cropmove', 'cropend', 'crop', 'cropdata'],
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,243 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<transition name="tiny-zoom-in-top" @after-enter="handleEnter" @after-leave="handleLeave">
|
||||
<div
|
||||
v-show="state.visible"
|
||||
class="tiny-picker-panel tiny-date-picker tiny-popper"
|
||||
:class="[
|
||||
{
|
||||
'has-sidebar': slots.sidebar || state.shortcuts,
|
||||
'has-time': state.showTime
|
||||
},
|
||||
state.popperClass
|
||||
]"
|
||||
>
|
||||
<div class="tiny-picker-panel__body-wrapper">
|
||||
<slot name="sidebar" class="tiny-picker-panel__sidebar"></slot>
|
||||
<div class="tiny-picker-panel__sidebar" v-if="state.shortcuts">
|
||||
<button
|
||||
type="button"
|
||||
class="tiny-picker-panel__shortcut"
|
||||
v-for="(shortcut, key) in state.shortcuts"
|
||||
:key="key"
|
||||
@click="handleShortcutClick(shortcut)"
|
||||
>
|
||||
{{ shortcut.text }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="tiny-picker-panel__body">
|
||||
<div class="tiny-date-picker__time-header" v-if="state.showTime">
|
||||
<span class="tiny-date-picker__editor-wrap">
|
||||
<tiny-input
|
||||
:placeholder="t('ui.datepicker.selectDate')"
|
||||
:modelValue="state.visibleDate"
|
||||
size="small"
|
||||
@update:modelValue="(val) => (state.userInputDate = val)"
|
||||
@change="handleVisibleDateChange"
|
||||
/>
|
||||
</span>
|
||||
<span class="tiny-date-picker__editor-wrap" v-clickoutside="handleTimePickClose">
|
||||
<tiny-input
|
||||
ref="input"
|
||||
@focus="state.timePickerVisible = true"
|
||||
:placeholder="t('ui.datepicker.selectTime')"
|
||||
:modelValue="state.visibleTime"
|
||||
size="small"
|
||||
@update:modelValue="(val) => (state.userInputTime = val)"
|
||||
@change="handleVisibleTimeChange"
|
||||
/>
|
||||
<time-picker
|
||||
ref="timepicker"
|
||||
:time-arrow-control="state.arrowControl"
|
||||
:show="state.timePickerVisible"
|
||||
v-if="state.timePickerVisible"
|
||||
:value="state.date"
|
||||
@pick="handleTimePick"
|
||||
>
|
||||
</time-picker>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="tiny-date-picker__header"
|
||||
:class="{
|
||||
'tiny-date-picker__header--bordered': state.currentView === 'year' || state.currentView === 'month'
|
||||
}"
|
||||
v-show="state.currentView !== 'time'"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
@click="cusPrevYear"
|
||||
:aria-label="t(`ui.datepicker.prevYear`)"
|
||||
class="tiny-picker-panel__icon-btn tiny-date-picker__prev-btn tiny-icon-d-arrow-left"
|
||||
>
|
||||
<icon-double-left></icon-double-left>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
@click="cusPrevMonth"
|
||||
v-show="state.currentView === 'date'"
|
||||
:aria-label="t(`ui.datepicker.prevMonth`)"
|
||||
class="tiny-picker-panel__icon-btn tiny-date-picker__prev-btn tiny-icon-arrow-left"
|
||||
>
|
||||
<icon-chevron-left></icon-chevron-left>
|
||||
</button>
|
||||
<span @click="showYearPicker" role="button" class="tiny-date-picker__header-label">{{ state.yearLabel }}</span>
|
||||
<span
|
||||
@click="showMonthPicker"
|
||||
v-show="state.currentView === 'date'"
|
||||
role="button"
|
||||
class="tiny-date-picker__header-label"
|
||||
:class="{ active: state.currentView === 'month' }"
|
||||
>{{ t(`ui.datepicker.month${state.month + 1}`) }}</span
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
@click="cusNextYear"
|
||||
:aria-label="t(`ui.datepicker.nextYear`)"
|
||||
class="tiny-picker-panel__icon-btn tiny-date-picker__next-btn tiny-icon-d-arrow-right"
|
||||
>
|
||||
<icon-double-right></icon-double-right>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
@click="cusNextMonth"
|
||||
v-show="state.currentView === 'date'"
|
||||
:aria-label="t(`ui.datepicker.nextMonth`)"
|
||||
class="tiny-picker-panel__icon-btn tiny-date-picker__next-btn tiny-icon-arrow-right"
|
||||
>
|
||||
<icon-chevron-right></icon-chevron-right>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="tiny-picker-panel__content">
|
||||
<date-table
|
||||
v-show="state.currentView === 'date'"
|
||||
@pick="handleDatePick"
|
||||
:selection-mode="state.selectionMode"
|
||||
:first-day-of-week="state.firstDayOfWeek"
|
||||
:value="state.value"
|
||||
:default-value="state.defaultValue ? new Date(state.defaultValue) : null"
|
||||
:date="state.date"
|
||||
:cell-class-name="state.cellClassName"
|
||||
:disabled-date="state.disabledDate"
|
||||
>
|
||||
</date-table>
|
||||
<year-table
|
||||
v-show="state.currentView === 'year'"
|
||||
@pick="handleYearPick"
|
||||
:value="state.value"
|
||||
:default-value="state.defaultValue ? new Date(state.defaultValue) : null"
|
||||
:date="state.date"
|
||||
:disabled-date="state.disabledDate"
|
||||
>
|
||||
</year-table>
|
||||
<month-table
|
||||
v-show="state.currentView === 'month'"
|
||||
@pick="handleMonthPick"
|
||||
:value="state.value"
|
||||
:default-value="state.defaultValue ? new Date(state.defaultValue) : null"
|
||||
:date="state.date"
|
||||
:disabled-date="state.disabledDate"
|
||||
>
|
||||
</month-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tiny-picker-panel__timezone" v-if="state.isShowTz || state.timezone.isServiceTimezone" v-clickoutside="handleTzPickClose">
|
||||
<tiny-input v-model="state.tz" :disabled="state.timezone.isServiceTimezone" @update:modelValue="searchTz" :placeholder="t('ui.datepicker.timezone')">
|
||||
<template #suffix>
|
||||
<component fill="#ccc" :is="state.showpopup ? 'IconChevronDown' : 'IconChevronUp'" @click="toggleTz" />
|
||||
</template>
|
||||
</tiny-input>
|
||||
<div class="tiny-picker-panel__tzlist">
|
||||
<tiny-popup v-model="state.showpopup" :overlay="false" position="up" :duration="0.2" :closeable="false">
|
||||
<div class="tzlist">
|
||||
<ul>
|
||||
<li
|
||||
class="tiny-picker-panel__tzlist-li"
|
||||
:title="tz.name"
|
||||
v-show="!tz.visible"
|
||||
v-for="(tz, index) in state.renderTzdata"
|
||||
:key="index"
|
||||
@click="selectTz(tz)"
|
||||
>
|
||||
{{ tz.name }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</tiny-popup>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tiny-picker-panel__footer" v-show="state.isShowFooter">
|
||||
<tiny-button size="mini" type="text" class="tiny-picker-panel__link-btn" @click="changeToNow" v-show="state.selectionMode !== 'dates'">
|
||||
{{ t('ui.datepicker.now') }}
|
||||
</tiny-button>
|
||||
<tiny-button type="primary" size="mini" class="tiny-picker-panel__link-btn" @click="confirm">
|
||||
{{ t('ui.datepicker.confirm') }}
|
||||
</tiny-button>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { renderless, api } from '@opentiny/vue-renderless/date-panel/vue'
|
||||
import { $prefix, setup, directive, defineComponent } from '@opentiny/vue-common'
|
||||
import { language } from '@opentiny/vue-locale'
|
||||
import Clickoutside from '@opentiny/vue-renderless/common/deps/clickoutside'
|
||||
import TimePicker from '@opentiny/vue-time'
|
||||
import DateTable from '@opentiny/vue-date-table'
|
||||
import YearTable from '@opentiny/vue-year-table'
|
||||
import MonthTable from '@opentiny/vue-month-table'
|
||||
import Input from '@opentiny/vue-input'
|
||||
import Button from '@opentiny/vue-button'
|
||||
import { iconDoubleRight, iconDoubleLeft, iconChevronLeft, iconChevronRight, iconChevronDown, iconChevronUp } from '@opentiny/vue-icon'
|
||||
import Popup from '@opentiny/vue-popup'
|
||||
import '@opentiny/vue-theme/input/index.less'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'DatePanel',
|
||||
directives: directive({ Clickoutside }),
|
||||
components: {
|
||||
TimePicker,
|
||||
YearTable,
|
||||
MonthTable,
|
||||
DateTable,
|
||||
TinyInput: Input,
|
||||
TinyButton: Button,
|
||||
TinyPopup: Popup,
|
||||
IconDoubleRight: iconDoubleRight(),
|
||||
IconDoubleLeft: iconDoubleLeft(),
|
||||
IconChevronLeft: iconChevronLeft(),
|
||||
IconChevronRight: iconChevronRight(),
|
||||
IconChevronDown: iconChevronDown(),
|
||||
IconChevronUp: iconChevronUp()
|
||||
},
|
||||
props: {
|
||||
emitter: Object
|
||||
},
|
||||
emits: ['pick', 'select-change', 'dodestroy'],
|
||||
setup(props, context) {
|
||||
return setup({
|
||||
props,
|
||||
context,
|
||||
renderless,
|
||||
api,
|
||||
mono: true,
|
||||
extendOptions: { language }
|
||||
})
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,247 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<transition name="tiny-zoom-in-top" @after-leave="$emit('dodestroy')">
|
||||
<div
|
||||
v-show="state.visible"
|
||||
class="tiny-picker-panel tiny-date-range-picker tiny-popper"
|
||||
:class="[
|
||||
{
|
||||
'has-sidebar': slots.sidebar || state.shortcuts,
|
||||
'has-time': state.showTime
|
||||
},
|
||||
state.popperClass
|
||||
]"
|
||||
ref="refDateRange"
|
||||
>
|
||||
<div class="tiny-picker-panel__body-wrapper">
|
||||
<slot name="sidebar" class="tiny-picker-panel__sidebar"></slot>
|
||||
<div class="tiny-picker-panel__sidebar" v-if="state.shortcuts">
|
||||
<button
|
||||
type="button"
|
||||
class="tiny-picker-panel__shortcut"
|
||||
v-for="(shortcut, key) in state.shortcuts"
|
||||
:key="key"
|
||||
@click="handleShortcutClick(shortcut)"
|
||||
>
|
||||
{{ shortcut.text }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="tiny-picker-panel__body">
|
||||
<div class="tiny-date-range-picker__time-header" v-if="state.showTime">
|
||||
<span class="tiny-date-range-picker__editors-wrap">
|
||||
<span class="tiny-date-range-picker__time-picker-wrap">
|
||||
<tiny-input
|
||||
size="small"
|
||||
:disabled="state.rangeState.selecting"
|
||||
ref="minInput"
|
||||
:placeholder="t('ui.datepicker.startDate')"
|
||||
class="tiny-date-range-picker__editor"
|
||||
:modelValue="state.minVisibleDate"
|
||||
@update:modelValue="(val) => handleDateInput(val, 'min')"
|
||||
@change="(val) => handleDateChange(val, 'min')"
|
||||
/>
|
||||
</span>
|
||||
<span class="tiny-date-range-picker__time-picker-wrap" v-clickoutside="handleMinTimeClose">
|
||||
<tiny-input
|
||||
size="small"
|
||||
class="tiny-date-range-picker__editor"
|
||||
:disabled="state.rangeState.selecting"
|
||||
:placeholder="t('ui.datepicker.startTime')"
|
||||
:modelValue="state.minVisibleTime"
|
||||
@focus="state.minTimePickerVisible = true"
|
||||
@update:modelValue="(val) => handleTimeInput(val, 'min')"
|
||||
@change="(val) => handleTimeChange(val, 'min')"
|
||||
/>
|
||||
<time-picker
|
||||
ref="minTimePicker"
|
||||
:time-arrow-control="state.arrowControl"
|
||||
:show="state.minTimePickerVisible"
|
||||
:value="state.minDate"
|
||||
@pick="handleMinTimePick"
|
||||
>
|
||||
</time-picker>
|
||||
</span>
|
||||
</span>
|
||||
<span class="tiny-icon-arrow-right"></span>
|
||||
<span class="tiny-date-range-picker__editors-wrap is-right">
|
||||
<span class="tiny-date-range-picker__time-picker-wrap">
|
||||
<tiny-input
|
||||
size="small"
|
||||
class="tiny-date-range-picker__editor"
|
||||
:disabled="state.rangeState.selecting"
|
||||
:placeholder="t('ui.datepicker.endDate')"
|
||||
:modelValue="state.maxVisibleDate"
|
||||
:readonly="!state.minDate"
|
||||
@update:modelValue="(val) => handleDateInput(val, 'max')"
|
||||
@change="(val) => handleDateChange(val, 'max')"
|
||||
/>
|
||||
</span>
|
||||
<span class="tiny-date-range-picker__time-picker-wrap" v-clickoutside="handleMaxTimeClose">
|
||||
<tiny-input
|
||||
size="small"
|
||||
class="tiny-date-range-picker__editor"
|
||||
:disabled="state.rangeState.selecting"
|
||||
:placeholder="t('ui.datepicker.endTime')"
|
||||
:modelValue="state.maxVisibleTime"
|
||||
:readonly="!state.minDate"
|
||||
@focus="state.minDate && (state.maxTimePickerVisible = true)"
|
||||
@update:modelValue="(val) => handleTimeInput(val, 'max')"
|
||||
@change="(val) => handleTimeChange(val, 'max')"
|
||||
/>
|
||||
<time-picker
|
||||
ref="maxTimePicker"
|
||||
:time-arrow-control="state.arrowControl"
|
||||
:show="state.maxTimePickerVisible"
|
||||
:value="state.maxDate"
|
||||
@pick="handleMaxTimePick"
|
||||
>
|
||||
</time-picker>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="tiny-picker-panel__content tiny-date-range-picker__content is-left">
|
||||
<div class="tiny-date-range-picker__header">
|
||||
<button type="button" @click="leftPrevYear" class="tiny-picker-panel__icon-btn tiny-icon-d-arrow-left">
|
||||
<icon-pager-first></icon-pager-first>
|
||||
</button>
|
||||
<button type="button" @click="leftPrevMonth" class="tiny-picker-panel__icon-btn tiny-icon-arrow-left">
|
||||
<icon-pager-prev></icon-pager-prev>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
@click="leftNextYear"
|
||||
v-if="state.unlinkPanels"
|
||||
:disabled="!state.enableYearArrow"
|
||||
:class="{ 'is-disabled': !state.enableYearArrow }"
|
||||
class="tiny-picker-panel__icon-btn tiny-icon-d-arrow-right"
|
||||
>
|
||||
<icon-pager-last></icon-pager-last>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
@click="leftNextMonth"
|
||||
v-if="state.unlinkPanels"
|
||||
:disabled="!state.enableMonthArrow"
|
||||
:class="{ 'is-disabled': !state.enableMonthArrow }"
|
||||
class="tiny-picker-panel__icon-btn tiny-icon-arrow-right"
|
||||
>
|
||||
<icon-pager-next></icon-pager-next>
|
||||
</button>
|
||||
<div>{{ state.leftLabel }}</div>
|
||||
</div>
|
||||
<date-table
|
||||
selection-mode="range"
|
||||
:date="state.leftDate"
|
||||
:default-value="state.defaultValue"
|
||||
:min-date="state.minDate"
|
||||
:max-date="state.maxDate"
|
||||
:range-state="state.rangeState"
|
||||
:disabled-date="state.disabledDate"
|
||||
:cell-class-name="state.cellClassName"
|
||||
@changerange="handleChangeRange"
|
||||
:first-day-of-week="state.firstDayOfWeek"
|
||||
@pick="handleRangePick"
|
||||
>
|
||||
</date-table>
|
||||
</div>
|
||||
<div class="tiny-picker-panel__content tiny-date-range-picker__content is-right">
|
||||
<div class="tiny-date-range-picker__header">
|
||||
<button
|
||||
type="button"
|
||||
@click="rightPrevYear"
|
||||
v-if="state.unlinkPanels"
|
||||
:disabled="!state.enableYearArrow"
|
||||
:class="{ 'is-disabled': !state.enableYearArrow }"
|
||||
class="tiny-picker-panel__icon-btn tiny-icon-d-arrow-left"
|
||||
>
|
||||
<icon-pager-first></icon-pager-first>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
@click="rightPrevMonth"
|
||||
v-if="state.unlinkPanels"
|
||||
:disabled="!state.enableMonthArrow"
|
||||
:class="{ 'is-disabled': !state.enableMonthArrow }"
|
||||
class="tiny-picker-panel__icon-btn tiny-icon-arrow-left"
|
||||
>
|
||||
<icon-pager-prev></icon-pager-prev>
|
||||
</button>
|
||||
<button type="button" @click="rightNextYear" class="tiny-picker-panel__icon-btn tiny-icon-d-arrow-right">
|
||||
<icon-pager-last></icon-pager-last>
|
||||
</button>
|
||||
<button type="button" @click="rightNextMonth" class="tiny-picker-panel__icon-btn tiny-icon-arrow-right">
|
||||
<icon-pager-next></icon-pager-next>
|
||||
</button>
|
||||
<div>{{ state.rightLabel }}</div>
|
||||
</div>
|
||||
<date-table
|
||||
selection-mode="range"
|
||||
:date="state.rightDate"
|
||||
:default-value="state.defaultValue"
|
||||
:min-date="state.minDate"
|
||||
:max-date="state.maxDate"
|
||||
:range-state="state.rangeState"
|
||||
:disabled-date="state.disabledDate"
|
||||
:cell-class-name="state.cellClassName"
|
||||
@changerange="handleChangeRange"
|
||||
:first-day-of-week="state.firstDayOfWeek"
|
||||
@pick="handleRangePick"
|
||||
>
|
||||
</date-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tiny-picker-panel__footer" v-if="state.showTime">
|
||||
<tiny-button size="mini" type="text" class="tiny-picker-panel__link-btn" @click="handleClear">
|
||||
{{ t('ui.datepicker.clear') }}
|
||||
</tiny-button>
|
||||
<tiny-button plain size="mini" class="tiny-picker-panel__link-btn" :disabled="state.btnDisabled" @click="handleConfirm(false)">
|
||||
{{ t('ui.datepicker.confirm') }}
|
||||
</tiny-button>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { renderless, api } from '@opentiny/vue-renderless/date-range/vue'
|
||||
import { $prefix, setup, directive, defineComponent } from '@opentiny/vue-common'
|
||||
import Clickoutside from '@opentiny/vue-renderless/common/deps/clickoutside'
|
||||
import TimePicker from '@opentiny/vue-time'
|
||||
import DateTable from '@opentiny/vue-date-table'
|
||||
import Input from '@opentiny/vue-input'
|
||||
import Button from '@opentiny/vue-button'
|
||||
import { iconPagerLast, iconPagerFirst, iconPagerPrev, iconPagerNext } from '@opentiny/vue-icon'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'DateRange',
|
||||
directives: directive({ Clickoutside }),
|
||||
components: {
|
||||
TimePicker,
|
||||
DateTable,
|
||||
TinyInput: Input,
|
||||
TinyButton: Button,
|
||||
IconPagerLast: iconPagerLast(),
|
||||
IconPagerFirst: iconPagerFirst(),
|
||||
IconPagerPrev: iconPagerPrev(),
|
||||
IconPagerNext: iconPagerNext()
|
||||
},
|
||||
props: {
|
||||
emitter: Object
|
||||
},
|
||||
emits: ['dodestroy', 'pick'],
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,91 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<table
|
||||
:class="['tiny-date-table', { 'is-week-mode': selectionMode === 'week' }]"
|
||||
cellspacing="0"
|
||||
@mousemove.stop="handleMouseMove"
|
||||
cellpadding="0"
|
||||
@click.stop="handleClick"
|
||||
>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th v-if="showWeekNumber">
|
||||
{{ t('ui.datepicker.week') }}
|
||||
</th>
|
||||
<th v-for="(weekDay, key) in state.weeks" :key="key">
|
||||
{{ t(`ui.datepicker.weeks.${weekDay}`) }}
|
||||
</th>
|
||||
</tr>
|
||||
<tr
|
||||
v-for="(row, key) in state.rows"
|
||||
:class="['tiny-date-table__row', { current: isWeekActive(row[1]) }]"
|
||||
:key="key"
|
||||
>
|
||||
<td v-for="(cellValue, key) in row" :key="key" :class="getCellClasses(cellValue)">
|
||||
<div>
|
||||
<span>
|
||||
{{ cellValue.text }}
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { renderless, api } from '@opentiny/vue-renderless/date-table/vue'
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
import { isDate } from '@opentiny/vue-renderless/common/deps/date-util'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'DateTable',
|
||||
emits: ['changerange', 'pick'],
|
||||
props: {
|
||||
value: {},
|
||||
defaultValue: {
|
||||
validator(value) {
|
||||
return value === null || isDate(value) || (Array.isArray(value) && value.every(isDate))
|
||||
}
|
||||
},
|
||||
firstDayOfWeek: {
|
||||
default: 7,
|
||||
type: Number,
|
||||
validator: (value: number) => value >= 1 && value <= 7
|
||||
},
|
||||
date: {},
|
||||
selectionMode: {
|
||||
default: 'day'
|
||||
},
|
||||
disabledDate: {},
|
||||
cellClassName: {},
|
||||
maxDate: {},
|
||||
minDate: {},
|
||||
showWeekNumber: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
rangeState: {
|
||||
default() {
|
||||
return {
|
||||
endDate: null,
|
||||
selecting: false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,129 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<div
|
||||
ref="wrapper"
|
||||
v-show="state.showWrapper"
|
||||
:class="'tiny-mobile-dropdown-item--' + state.direction"
|
||||
class="tiny-mobile-dropdown-item"
|
||||
@click="clickWrapper"
|
||||
:style="state.itemStyle"
|
||||
>
|
||||
<tiny-popup
|
||||
v-model="state.showPopup"
|
||||
popupClass="tiny-mobile-dropdown-item__content"
|
||||
:overlay="state.overlay"
|
||||
:close-on-click-overlay="state.closeOnClickOverlay"
|
||||
:closeable="false"
|
||||
:position="state.direction === 'down' ? 'top' : 'bottom'"
|
||||
:duration="state.transition ? state.duration : 0"
|
||||
@open="open"
|
||||
@close="close"
|
||||
@opened="opened"
|
||||
@closed="closed"
|
||||
>
|
||||
<slot>
|
||||
<div class="tiny-mobile-dropdown-item__options" v-if="type === 'selection'">
|
||||
<div
|
||||
v-for="(item, index) in options"
|
||||
class="tiny-mobile-dropdown-item__cell tiny-mobile-dropdown-item__option"
|
||||
:key="index"
|
||||
:class="item.value === modelValue ? 'is-active' : ''"
|
||||
tabindex="0"
|
||||
@click="clickItem(item.value)"
|
||||
>
|
||||
<div class="tiny-mobile-dropdown-item__option-icon">
|
||||
<slot name="icon">
|
||||
<component :is="icon"></component>
|
||||
</slot>
|
||||
</div>
|
||||
<div class="tiny-mobile-dropdown-item__option-title">
|
||||
<slot name="title" :titleData="item">
|
||||
<span
|
||||
:style="{
|
||||
color: item.value === modelValue && state.activeColor ? state.activeColor : ''
|
||||
}"
|
||||
>{{ item.text }}</span
|
||||
>
|
||||
</slot>
|
||||
</div>
|
||||
<div class="tiny-mobile-dropdown-item__option-value">
|
||||
<icon-yes v-if="item.value === modelValue" :fill="state.activeColor ? state.activeColor : '#f36f64'"></icon-yes>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tiny-mobile-dropdown-item__filter" v-if="type === 'filter'" v-clickoutside="clickOutside">
|
||||
<div class="tiny-mobile-dropdown-item__filter-wrap">
|
||||
<div v-for="(item, key) in options" :key="key" class="tiny-mobile-dropdown-item__cell tiny-mobile-dropdown-item__filter-item">
|
||||
<span class="tiny-mobile-dropdown-item__filter-title">{{ item.title }}</span>
|
||||
<ul>
|
||||
<li
|
||||
v-for="(tag, tagkey) in options.length === 0 ? (item.data = []) : item.data"
|
||||
class="tiny-mobile-dropdown-item__filter-li"
|
||||
:style="getOptionStyle(tag, modelValue[key])"
|
||||
@click="tagClick(key, tag, $event)"
|
||||
:key="tagkey"
|
||||
:class="[modelValue[key].indexOf(tag.value) > -1 ? 'checked' : '']"
|
||||
>
|
||||
{{ tag.text }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tiny-mobile-dropdown-item__filter-operate">
|
||||
<tiny-button @click="reset">Reset</tiny-button>
|
||||
<tiny-button type="primary" @click="confirm">OK</tiny-button>
|
||||
</div>
|
||||
</div>
|
||||
</slot>
|
||||
</tiny-popup>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { renderless, api } from '@opentiny/vue-renderless/dropdown-item/vue'
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
import { iconYes } from '@opentiny/vue-icon'
|
||||
import Popup from '@opentiny/vue-popup'
|
||||
import Button from '@opentiny/vue-button'
|
||||
import Clickoutside from '@opentiny/vue-renderless/common/deps/clickoutside'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'DropdownItem',
|
||||
componentName: 'DropdownItem',
|
||||
directives: { Clickoutside },
|
||||
props: {
|
||||
modelValue: null,
|
||||
title: String,
|
||||
disabled: Boolean,
|
||||
titleClass: String,
|
||||
options: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
icon: Object,
|
||||
type: {
|
||||
type: String,
|
||||
default: 'selection'
|
||||
}
|
||||
},
|
||||
components: {
|
||||
IconYes: iconYes(),
|
||||
TinyPopup: Popup,
|
||||
TinyButton: Button
|
||||
},
|
||||
emits: ['update:modelValue', 'open', 'opened', 'click', 'change', 'closed', 'close', 'reset', 'confirm', 'item-click'],
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,102 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<div ref="menu" class="tiny-mobile-dropdown-menu">
|
||||
<div class="tiny-mobile-dropdown-menu__bar tiny-mobile-dropdown-menu__bar--opened">
|
||||
<div
|
||||
v-for="(item, index) in state.children"
|
||||
:key="index"
|
||||
role="button"
|
||||
v-clickoutside="clickOutside"
|
||||
:tabindex="item.disabled ? -1 : 0"
|
||||
class="tiny-mobile-dropdown-menu__item"
|
||||
:class="[item.disabled ? 'is-disabled' : '', item.titleClass]"
|
||||
@click="toggleItem(index, item)"
|
||||
>
|
||||
<div
|
||||
class="tiny-mobile-dropdown-menu__title"
|
||||
:style="{ color: item.state.showPopup ? activeColor : '' }"
|
||||
:class="{
|
||||
'is-active': item.state.showPopup,
|
||||
'is-down': item.state.showPopup === (direction === 'down')
|
||||
}"
|
||||
>
|
||||
<div class="tiny-mobile-dropdown-menu__title-wrap">
|
||||
<span v-if="!slots.title">
|
||||
<span class="tiny-mobile-dropdown-menu__title-text">{{ item.state.displayTitle }}</span>
|
||||
<span class="tiny-mobile-dropdown-menu__title-icon" v-if="item.type === 'sort'">
|
||||
<icon-delta-up class="up" :fill="item.state.sort === 'asc' ? (activeColor ? activeColor : '#f36f64') : '#ccc'"></icon-delta-up>
|
||||
<icon-delta-down class="down" :fill="item.state.sort === 'desc' ? (activeColor ? activeColor : '#f36f64') : '#ccc'"></icon-delta-down>
|
||||
</span>
|
||||
<component
|
||||
v-else
|
||||
:fill="item.state.showPopup ? (activeColor ? activeColor : '#f36f64') : '#ccc'"
|
||||
:is="item.type === 'filter' ? 'IconUnfilter' : item.type === 'selection' && item.state.showPopup ? 'IconUp' : 'IconDown'"
|
||||
:class="[item.type === 'filter' ? 'filter-icon' : '']"
|
||||
/>
|
||||
</span>
|
||||
<slot v-else name="title"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { renderless, api } from '@opentiny/vue-renderless/dropdown-menu/vue'
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
import { iconUp, iconDown, iconUnfilter, iconSort, iconDeltaDown, iconDeltaUp } from '@opentiny/vue-icon'
|
||||
import Clickoutside from '@opentiny/vue-renderless/common/deps/clickoutside'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'DropdownMenu',
|
||||
components: {
|
||||
IconUp: iconUp(),
|
||||
IconDown: iconDown(),
|
||||
IconUnfilter: iconUnfilter(),
|
||||
IconSort: iconSort(),
|
||||
IconDeltaDown: iconDeltaDown(),
|
||||
IconDeltaUp: iconDeltaUp()
|
||||
},
|
||||
directives: { Clickoutside },
|
||||
props: {
|
||||
zIndex: [Number, String],
|
||||
activeColor: String,
|
||||
overlay: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
duration: {
|
||||
type: [Number, String],
|
||||
default: 0.2
|
||||
},
|
||||
direction: {
|
||||
type: String,
|
||||
default: 'down'
|
||||
},
|
||||
closeOnClickOverlay: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
closeOnClickOutside: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
emits: ['open'],
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,142 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
|
||||
<script lang="tsx">
|
||||
import { renderless, api } from '@opentiny/vue-renderless/dropdown/vue'
|
||||
import { setup, $prefix, directive, defineComponent } from '@opentiny/vue-common'
|
||||
import Button from '@opentiny/vue-button'
|
||||
import ButtonGroup from '@opentiny/vue-button-group'
|
||||
import Clickoutside from '@opentiny/vue-renderless/common/deps/clickoutside'
|
||||
import DropdownMenu from '@opentiny/vue-dropdown-menu'
|
||||
import { iconChevronDown, iconChevronUp } from '@opentiny/vue-icon'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'Dropdown',
|
||||
componentName: 'TinyDropdown',
|
||||
components: {
|
||||
TinyButton: Button,
|
||||
TinyButtonGroup: ButtonGroup,
|
||||
IconChevronDown: iconChevronDown(),
|
||||
IconChevronUp: iconChevronUp(),
|
||||
TinyDropdownMenu: DropdownMenu
|
||||
},
|
||||
directives: directive({ Clickoutside }),
|
||||
props: {
|
||||
type: String,
|
||||
trigger: {
|
||||
type: String,
|
||||
default: 'hover'
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
splitButton: Boolean,
|
||||
showTimeout: {
|
||||
type: Number,
|
||||
default: 250
|
||||
},
|
||||
hideTimeout: {
|
||||
type: Number,
|
||||
default: 150
|
||||
},
|
||||
hideOnClick: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
tabindex: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
menuOptions: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
options: [],
|
||||
textField: 'label',
|
||||
popperClass: '',
|
||||
placement: 'bottom-end'
|
||||
})
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: '下拉菜单'
|
||||
}
|
||||
},
|
||||
emits: ['visible-change', 'item-click', 'button-click', 'menu-item-click', 'handle-click'],
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
},
|
||||
render() {
|
||||
const { hide, splitButton, type, disabled, handleMainButtonClick, slots, size, state, menuOptions, title } = this
|
||||
let triggerElm = null
|
||||
const triggerClass = 'tiny-dropdown-trigger'
|
||||
const visibleClass = state.visible ? 'tiny-dropdown-visible' : ''
|
||||
|
||||
if (splitButton) {
|
||||
triggerElm = (
|
||||
<tiny-button-group>
|
||||
<tiny-button type={type} size={size} onClick={handleMainButtonClick} disabled={disabled}>
|
||||
{slots.default && slots.default()}
|
||||
</tiny-button>
|
||||
<tiny-button ref="trigger" type={type} size={size} class={`tiny-dropdown__caret-button ${triggerClass}`} disabled={disabled} reset-time={0}>
|
||||
<icon-chevron-down class={visibleClass}></icon-chevron-down>
|
||||
</tiny-button>
|
||||
</tiny-button-group>
|
||||
)
|
||||
} else {
|
||||
const defaultTriggerElm = (
|
||||
<span>
|
||||
<span>{title}</span>
|
||||
<icon-chevron-down class={visibleClass}></icon-chevron-down>
|
||||
</span>
|
||||
)
|
||||
|
||||
triggerElm = (slots.default && slots.default()) || [defaultTriggerElm]
|
||||
|
||||
// 增加一层,vue3 环境中无法使用 slots.default 的方式获取原生 DOM 元素
|
||||
triggerElm = disabled
|
||||
? (
|
||||
<span ref="trigger" disabled class={triggerClass}>
|
||||
{triggerElm}
|
||||
</span>
|
||||
)
|
||||
: (
|
||||
<span ref="trigger" class={triggerClass}>
|
||||
{triggerElm}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
const defaulMenuElm = (
|
||||
<tiny-dropdown-menu
|
||||
options={menuOptions.options}
|
||||
text-field={menuOptions.textField || menuOptions['text-field']}
|
||||
popper-class={menuOptions.popperClass || menuOptions['popper-class']}
|
||||
placement={menuOptions.placement}
|
||||
></tiny-dropdown-menu>
|
||||
)
|
||||
|
||||
const menuElm = disabled ? null : (slots.dropdown && slots.dropdown()) || defaulMenuElm
|
||||
|
||||
return (
|
||||
<div class="tiny-dropdown" v-clickoutside={hide} aria-disabled={disabled}>
|
||||
{triggerElm}
|
||||
{menuElm}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,64 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<div class="tiny-mobile-exception" :class="exceptionClass">
|
||||
<div class="tiny-mobile-exception__content">
|
||||
<img v-if="imageUrl" :src="imageUrl" class="tiny-mobile-exception__image" />
|
||||
<div v-else class="tiny-mobile-exception__content-view" :class="['tiny-mobile-exception__content-' + type]"></div>
|
||||
<slot name="content">
|
||||
<div class="tiny-mobile-exception__content-message">
|
||||
<div class="main-message">
|
||||
{{ state.message }}
|
||||
</div>
|
||||
<div v-if="subMessage" class="sub-message">
|
||||
{{ subMessage }}
|
||||
</div>
|
||||
<slot v-if="type === 'nodata'">
|
||||
<tiny-button @click="create" type="primary" size="medium" round>
|
||||
{{ buttonText ? buttonText : t('ui.exception.create') }}
|
||||
</tiny-button>
|
||||
</slot>
|
||||
</div>
|
||||
</slot>
|
||||
</div>
|
||||
<div class="tiny-mobile-exception__footer">
|
||||
<slot name="footer"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { renderless, api } from '@opentiny/vue-renderless/exception/vue'
|
||||
import { setup, $prefix, defineComponent } from '@opentiny/vue-common'
|
||||
import Button from '@opentiny/vue-button'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'Exception',
|
||||
components: {
|
||||
TinyButton: Button
|
||||
},
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
default: 'nodata'
|
||||
},
|
||||
message: String,
|
||||
subMessage: String,
|
||||
exceptionClass: String,
|
||||
buttonText: String,
|
||||
imageUrl: String
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,286 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<script lang="tsx">
|
||||
import { $prefix, setup, parseVnode, h, defineComponent } from '@opentiny/vue-common'
|
||||
import { renderless, api } from '@opentiny/vue-renderless/form-item/vue'
|
||||
import LabelWrap from './label-wrap.js'
|
||||
import Tooltip from '@opentiny/vue-tooltip'
|
||||
|
||||
const $constants = {
|
||||
FORM_NAME: 'Form',
|
||||
FORM_ITEM_NAME: 'FormItem'
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'FormItem',
|
||||
componentName: 'FormItem',
|
||||
components: {
|
||||
LabelWrap,
|
||||
Tooltip
|
||||
},
|
||||
props: {
|
||||
_constants: {
|
||||
type: Object,
|
||||
default: () => $constants
|
||||
},
|
||||
appendToBody: {
|
||||
type: Boolean,
|
||||
default: undefined
|
||||
},
|
||||
error: String,
|
||||
for: String,
|
||||
inlineMessage: {
|
||||
type: [String, Boolean],
|
||||
default: ''
|
||||
},
|
||||
label: String,
|
||||
labelWidth: String,
|
||||
manual: Boolean,
|
||||
popperOptions: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
prop: String,
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: undefined
|
||||
},
|
||||
rules: [Object, Array],
|
||||
showMessage: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
size: String,
|
||||
validateDebounce: Boolean,
|
||||
validatePosition: String,
|
||||
validateStatus: String,
|
||||
validateType: String,
|
||||
validateIcon: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
ellipsis: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
vertical: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
},
|
||||
// eslint-disable-next-line complexity
|
||||
render() {
|
||||
const { state, required, slots, label, scopedSlots, showMessage, inlineMessage, validateIcon, ellipsis, vertical } = this
|
||||
const isMobile = state.mode === 'mobile'
|
||||
const classPrefix = isMobile ? 'tiny-mobile-' : 'tiny-'
|
||||
const labelSlot = slots.label ? slots.label() : null
|
||||
const defaultSlots = slots.default ? slots.default() : null
|
||||
const errorSlot = scopedSlots.error && scopedSlots.error(state.validateMessage)
|
||||
const formItemClass = `${classPrefix}form-item--${state.sizeClass ? state.sizeClass : ''}`
|
||||
const isShowError = state.validateState === 'error' && showMessage && state.form.showMessage
|
||||
const isErrorInline = typeof inlineMessage === 'boolean' ? inlineMessage : (state.formInstance && state.formInstance.inlineMessage) || false
|
||||
let validateMessage = null
|
||||
|
||||
const FormContent = defaultSlots
|
||||
? defaultSlots.map((vnode) => {
|
||||
const item = parseVnode(vnode)
|
||||
item.props = item.props || {}
|
||||
const { type, props, data = {} } = item
|
||||
if ((props && props['novalid-tip'] !== undefined) || (data.attrs && data.attrs['novalid-tip'] !== undefined)) {
|
||||
return item
|
||||
}
|
||||
|
||||
Object.assign(item.props, {
|
||||
size: state.formItemSize,
|
||||
mini: state.formItemSize === 'mini'
|
||||
})
|
||||
|
||||
if (type && type.name && type.name.toLowerCase().endsWith('button')) {
|
||||
return item
|
||||
}
|
||||
|
||||
const propsData = item.props
|
||||
|
||||
if (propsData) {
|
||||
if (!state.isRequired) {
|
||||
// 兼容 2.0 组件 validation 是否有 required
|
||||
state.validationRequired = propsData.validation && !!propsData.validation.required
|
||||
}
|
||||
// 如果为 2.0 的验证 不会使用 toolltip 组件
|
||||
if (propsData.validation) {
|
||||
return item
|
||||
}
|
||||
}
|
||||
|
||||
const formAppendToBody = state.formInstance && state.formInstance.appendToBody
|
||||
const appendToBody = typeof this.appendToBody === 'boolean' ? this.appendToBody : typeof formAppendToBody === 'boolean' ? formAppendToBody : true
|
||||
const validatePosition = this.validatePosition || (state.formInstance && state.formInstance.validatePosition) || 'top-end'
|
||||
const popperOptions = {
|
||||
...state.formInstance.popperOptions,
|
||||
...this.popperOptions,
|
||||
forceAbsolute: !appendToBody,
|
||||
onUpdate: (options) => {
|
||||
const popper = options.instance._popper
|
||||
const translate3d = popper.style.transform
|
||||
const matchTranslate = translate3d.match(/translate3d\((\w+)px, (\w+)px, (\w+)px\)/)
|
||||
|
||||
if (!Array.isArray(matchTranslate)) {
|
||||
return
|
||||
}
|
||||
|
||||
const [x, y, z] = matchTranslate.slice(1)
|
||||
|
||||
popper.style.transform = `translate3d(${x}px, ${parseInt(y, 10)}px, ${z}px)`
|
||||
}
|
||||
}
|
||||
if (isMobile) {
|
||||
const validatePosition = this.validatePosition || state.formInstance.validatePosition || 'right'
|
||||
validateMessage = state.validateMessage
|
||||
? (
|
||||
validatePosition === 'right'
|
||||
? (
|
||||
<div class="tiny-mobile-input-form__error align-right">{state.validateMessage}</div>
|
||||
)
|
||||
: (
|
||||
<div class="tiny-mobile-input-form__error align-left">{state.validateMessage}</div>
|
||||
)
|
||||
)
|
||||
: null
|
||||
return h(
|
||||
'div',
|
||||
{
|
||||
class: `${classPrefix}form-item__value`,
|
||||
style: state.valueStyle
|
||||
},
|
||||
[item]
|
||||
)
|
||||
}
|
||||
const validateIconNode = validateIcon ? h(validateIcon, { class: 'tooltip-validate-icon' }) : null
|
||||
return h(
|
||||
'tooltip',
|
||||
{
|
||||
props: {
|
||||
popperClass: `${classPrefix}form__valid`,
|
||||
arrowOffset: Number.POSITIVE_INFINITY,
|
||||
adjustArrow: true,
|
||||
type: 'error',
|
||||
disabled: state.getValidateType !== 'tip',
|
||||
placement: validatePosition,
|
||||
manual: true,
|
||||
appendToBody,
|
||||
popperOptions,
|
||||
modelValue: isShowError ? state.canShowTip : false,
|
||||
zIndex: 'relative',
|
||||
renderContent() {
|
||||
return [validateIconNode, state.validateMessage]
|
||||
}
|
||||
},
|
||||
on: {
|
||||
'update:modelValue': (value) => {
|
||||
state.canShowTip = value
|
||||
}
|
||||
},
|
||||
ref: 'tooltip'
|
||||
},
|
||||
[item]
|
||||
)
|
||||
})
|
||||
: null
|
||||
const ErrorContent =
|
||||
isShowError && state.getValidateType === 'text'
|
||||
? errorSlot || h(
|
||||
'div',
|
||||
{
|
||||
class: {
|
||||
[`${classPrefix}form-item__error`]: true,
|
||||
[`${classPrefix}form-item__error--inline`]: isErrorInline
|
||||
}
|
||||
},
|
||||
[validateIcon ? h(validateIcon, { class: 'validate-icon' }) : null, state.validateMessage]
|
||||
)
|
||||
: null
|
||||
const LabelContent = h(
|
||||
'label-wrap',
|
||||
{
|
||||
props: {
|
||||
isAutoWidth: state.labelStyle && state.labelStyle.width === 'auto',
|
||||
updateAll: state.form.labelWidth === 'auto',
|
||||
isMobile: state.mode === 'mobile'
|
||||
}
|
||||
},
|
||||
[
|
||||
labelSlot || label
|
||||
? h(
|
||||
'label',
|
||||
{
|
||||
class: {
|
||||
[`${classPrefix}form-item__label`]: true,
|
||||
'is-ellipsis': isMobile && ellipsis
|
||||
},
|
||||
style: state.labelStyle,
|
||||
attrs: {
|
||||
for: state.labelFor
|
||||
}
|
||||
},
|
||||
labelSlot || label + state.form.labelSuffix
|
||||
)
|
||||
: null
|
||||
]
|
||||
)
|
||||
return h(
|
||||
'div',
|
||||
{
|
||||
class: {
|
||||
[`${classPrefix}form-item`]: true,
|
||||
[`${classPrefix}form-item--feedback`]: state.formInstance && state.formInstance.statusIcon,
|
||||
'is-error': state.validateState === 'error',
|
||||
'is-validating': state.validateState === 'validating',
|
||||
'is-success': state.validateState === 'success',
|
||||
'is-required': state.isRequired || required,
|
||||
'is-no-asterisk': state.formInstance && state.formInstance.hideRequiredAsterisk,
|
||||
[formItemClass]: true
|
||||
}
|
||||
},
|
||||
[
|
||||
!isMobile ? LabelContent : null,
|
||||
h(
|
||||
'div',
|
||||
{
|
||||
class: {
|
||||
[`${classPrefix}form-item__content`]: true,
|
||||
'is-vertical': isMobile && vertical
|
||||
},
|
||||
style: !isMobile && state.contentStyle
|
||||
},
|
||||
[
|
||||
isMobile ? LabelContent : null,
|
||||
FormContent,
|
||||
isMobile ? validateMessage : null,
|
||||
h(
|
||||
'transition',
|
||||
{
|
||||
attrs: {
|
||||
name: `${classPrefix}zoom-in-top`
|
||||
}
|
||||
},
|
||||
[ErrorContent]
|
||||
)
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,63 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<div
|
||||
ref="wrapper"
|
||||
class="tiny-fullscreen"
|
||||
v-bind="$attrs"
|
||||
:style="state.wrapperStyle"
|
||||
:class="{ [fullscreenClass]: state.isFullscreen }"
|
||||
@click="shadeClick($event)"
|
||||
@keyup="exit"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
import { renderless, api } from '@opentiny/vue-renderless/fullscreen/vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'Fullscreen',
|
||||
props: {
|
||||
fullscreen: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
exitOnClickWrapper: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
fullscreenClass: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
pageOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
teleport: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
zIndex: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
beforeChange: Function
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -435,7 +435,6 @@ export const Cell = {
|
|||
let {
|
||||
$table,
|
||||
column: { slots },
|
||||
isHidden,
|
||||
row
|
||||
} = params
|
||||
let { radioConfig = {}, selectRow, vSize } = $table
|
||||
|
@ -449,15 +448,13 @@ export const Cell = {
|
|||
name: `tiny-grid-radio__${$table.id}`,
|
||||
type: 'radio'
|
||||
}
|
||||
if (!isHidden && checkMethod) {
|
||||
if (checkMethod) {
|
||||
options.attrs.disabled = disabled = !checkMethod(params)
|
||||
}
|
||||
if (!isHidden) {
|
||||
options.domProps = { checked: row === selectRow }
|
||||
options.on = {
|
||||
change(event) {
|
||||
$table.triggerRadioRowEvent(event, params)
|
||||
}
|
||||
options.domProps = { checked: row === selectRow }
|
||||
options.on = {
|
||||
change(event) {
|
||||
$table.triggerRadioRowEvent(event, params)
|
||||
}
|
||||
}
|
||||
const map = {
|
||||
|
@ -481,7 +478,7 @@ export const Cell = {
|
|||
return Cell.renderTreeIcon(h, params).concat(Cell.renderRadioCell(h, params))
|
||||
},
|
||||
renderSelectionHeader(h, params) {
|
||||
let { $table, column, isHidden } = params
|
||||
let { $table, column } = params
|
||||
let { slots, own } = column
|
||||
let { headerCheckDisabled, isAllSelected, isIndeterminate, selectConfig, vSize } = $table
|
||||
let headerTitle = own.title || own.label
|
||||
|
@ -492,16 +489,14 @@ export const Cell = {
|
|||
if (isCheckStrictly(selectConfig)) {
|
||||
return []
|
||||
}
|
||||
if (!isHidden) {
|
||||
options.domProps = {
|
||||
disabled: headerCheckDisabled,
|
||||
checked: isAllSelected && !headerCheckDisabled
|
||||
}
|
||||
options.on = {
|
||||
change(event) {
|
||||
$table.triggerCheckAllEvent(event, event.target.checked)
|
||||
$table.showSelectToolbar()
|
||||
}
|
||||
options.domProps = {
|
||||
disabled: headerCheckDisabled,
|
||||
checked: isAllSelected && !headerCheckDisabled
|
||||
}
|
||||
options.on = {
|
||||
change(event) {
|
||||
$table.triggerCheckAllEvent(event, event.target.checked)
|
||||
$table.showSelectToolbar()
|
||||
}
|
||||
}
|
||||
let vnode = getSelectVnodes({
|
||||
|
@ -516,7 +511,7 @@ export const Cell = {
|
|||
return [vnode]
|
||||
},
|
||||
renderSelectionCell(h, params) {
|
||||
let { $table, column, isHidden, row } = params
|
||||
let { $table, column, row } = params
|
||||
let { slots } = column
|
||||
let { selectConfig = {}, treeConfig, treeIndeterminates, vSize } = $table
|
||||
let { labelField, checkMethod } = selectConfig
|
||||
|
@ -525,15 +520,13 @@ export const Cell = {
|
|||
if (slots && slots.default) {
|
||||
return slots.default(params, h)
|
||||
}
|
||||
if (!isHidden) {
|
||||
checkMethod && (options.attrs.disabled = isDisabled = !checkMethod(params))
|
||||
treeConfig && (indeterminate = ~treeIndeterminates.indexOf(row))
|
||||
options.domProps = { checked: ~$table.selection.indexOf(row) }
|
||||
options.on = {
|
||||
change(event) {
|
||||
$table.triggerCheckRowEvent(event, params, event.target.checked)
|
||||
$table.showSelectToolbar()
|
||||
}
|
||||
checkMethod && (options.attrs.disabled = isDisabled = !checkMethod(params))
|
||||
treeConfig && (indeterminate = ~treeIndeterminates.indexOf(row))
|
||||
options.domProps = { checked: ~$table.selection.indexOf(row) }
|
||||
options.on = {
|
||||
change(event) {
|
||||
$table.triggerCheckRowEvent(event, params, event.target.checked)
|
||||
$table.showSelectToolbar()
|
||||
}
|
||||
}
|
||||
let vnode = getSelectCellVnodes({
|
||||
|
@ -551,7 +544,7 @@ export const Cell = {
|
|||
return Cell.renderTreeIcon(h, params).concat(Cell.renderSelectionCell(h, params))
|
||||
},
|
||||
renderSelectionCellByProp(h, params) {
|
||||
let { $table, column, isHidden, row } = params
|
||||
let { $table, column, row } = params
|
||||
let { slots } = column
|
||||
let { selectConfig = {}, treeConfig, treeIndeterminates, vSize } = $table
|
||||
let { checkField: property, checkMethod, labelField } = selectConfig
|
||||
|
@ -562,14 +555,12 @@ export const Cell = {
|
|||
return slots.default(params, h)
|
||||
}
|
||||
|
||||
if (!isHidden) {
|
||||
checkMethod && (options.attrs.disabled = isDisabled = !checkMethod(params))
|
||||
treeConfig && (indeterminate = ~treeIndeterminates.indexOf(row))
|
||||
options.domProps = { checked: get(row, property) }
|
||||
options.on = {
|
||||
change(event) {
|
||||
$table.triggerCheckRowEvent(event, params, event.target.checked)
|
||||
}
|
||||
checkMethod && (options.attrs.disabled = isDisabled = !checkMethod(params))
|
||||
treeConfig && (indeterminate = ~treeIndeterminates.indexOf(row))
|
||||
options.domProps = { checked: get(row, property) }
|
||||
options.on = {
|
||||
change(event) {
|
||||
$table.triggerCheckRowEvent(event, params, event.target.checked)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -582,15 +573,13 @@ export const Cell = {
|
|||
},
|
||||
// 展开行
|
||||
renderExpandCell(h, params) {
|
||||
let { $table, isHidden, row } = params
|
||||
let { $table, row } = params
|
||||
let { expandConfig = {} } = $table
|
||||
let expandMethod = expandConfig.activeMethod
|
||||
let hideExpand = typeof expandMethod === 'function' ? expandMethod(row) : true
|
||||
let expandActive = false
|
||||
|
||||
if (!isHidden) {
|
||||
expandActive = $table.expandeds.includes(params.row)
|
||||
}
|
||||
expandActive = $table.expandeds.includes(params.row)
|
||||
|
||||
const map = {
|
||||
expandActive: 'expand__active'
|
||||
|
@ -653,37 +642,37 @@ export const Cell = {
|
|||
isColGroup
|
||||
? []
|
||||
: [
|
||||
column.order === 'asc' ?
|
||||
h(icon.sortDesc, {
|
||||
class: [
|
||||
'tiny-svg-size tiny-grid-sort__asc-btn',
|
||||
{
|
||||
'sort__active': column.order === 'asc'
|
||||
}
|
||||
],
|
||||
on: { click(event) { $table.triggerSortEvent(event, column, 'desc') } }
|
||||
})
|
||||
: '',
|
||||
column.order === 'desc' ?
|
||||
h(icon.sortAsc, {
|
||||
class: [
|
||||
'tiny-svg-size tiny-grid-sort__desc-btn',
|
||||
{
|
||||
'sort__active': column.order === 'desc'
|
||||
}
|
||||
],
|
||||
on: { click(event) { $table.triggerSortEvent(event, column, '') } }
|
||||
})
|
||||
: '',
|
||||
column.order
|
||||
? ''
|
||||
: h(icon.sortDefault, {
|
||||
class: [
|
||||
'tiny-svg-size tiny-grid-sort__desc-btn'
|
||||
],
|
||||
on: { click(event) { $table.triggerSortEvent(event, column, 'asc') } }
|
||||
})
|
||||
]
|
||||
column.order === 'asc' ?
|
||||
h(icon.sortDesc, {
|
||||
class: [
|
||||
'tiny-svg-size tiny-grid-sort__asc-btn',
|
||||
{
|
||||
'sort__active': column.order === 'asc'
|
||||
}
|
||||
],
|
||||
on: { click(event) { $table.triggerSortEvent(event, column, 'desc') } }
|
||||
})
|
||||
: '',
|
||||
column.order === 'desc' ?
|
||||
h(icon.sortAsc, {
|
||||
class: [
|
||||
'tiny-svg-size tiny-grid-sort__desc-btn',
|
||||
{
|
||||
'sort__active': column.order === 'desc'
|
||||
}
|
||||
],
|
||||
on: { click(event) { $table.triggerSortEvent(event, column, '') } }
|
||||
})
|
||||
: '',
|
||||
column.order
|
||||
? ''
|
||||
: h(icon.sortDefault, {
|
||||
class: [
|
||||
'tiny-svg-size tiny-grid-sort__desc-btn'
|
||||
],
|
||||
on: { click(event) { $table.triggerSortEvent(event, column, 'asc') } }
|
||||
})
|
||||
]
|
||||
)
|
||||
]
|
||||
},
|
||||
|
|
|
@ -238,7 +238,7 @@ const sliceVisibleColumn = (args) => {
|
|||
}
|
||||
|
||||
// x轴虚拟滚动时,需要一直保持冻结列显示
|
||||
tableColumn2 = [...new Set([...leftList, ...tableColumn2, ...rightList])]
|
||||
tableColumn2 = Array.from(new Set([...leftList, ...tableColumn2, ...rightList]))
|
||||
|
||||
return {
|
||||
tableColumn: tableColumn2,
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<div :class="{ 'is-show-prefix': slots.prefix, 'is-padding': list }" class="tiny-mobile-list" @click="clickList">
|
||||
<div class="tiny-mobile-list__prefix" v-if="slots.prefix">
|
||||
<slot name="prefix"></slot>
|
||||
</div>
|
||||
<div class="tiny-mobile-list__content">
|
||||
<div class="tiny-mobile-list__content-text">
|
||||
<slot>
|
||||
<span class="tiny-mobile-list__main-text">{{ content }}</span>
|
||||
</slot>
|
||||
<span v-if="subText" class="tiny-mobile-list__sub-text">{{ subText }}</span>
|
||||
</div>
|
||||
<div v-if="slots.description" class="tiny-mobile-list__content-des">
|
||||
<slot name="description"></slot>
|
||||
</div>
|
||||
<p v-if="contentDes" class="tiny-mobile-list__content-des">
|
||||
{{ contentDes }}
|
||||
</p>
|
||||
</div>
|
||||
<div v-if="slots.suffix" class="tiny-mobile-list__suffix">
|
||||
<slot name="suffix"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
import { renderless, api } from '@opentiny/vue-renderless/list/vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'List',
|
||||
props: {
|
||||
content: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
subText: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
contentDes: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
list: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
id: {
|
||||
type: [Number, String],
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,78 +0,0 @@
|
|||
<template>
|
||||
<div class="tiny-locales">
|
||||
<span v-if="state.locales.length === 1">{{ state.text && t(state.text) }}</span>
|
||||
<span v-else-if="state.locales.length === 2" @click="switchLanguage">{{ state.text && t(state.text) }}</span>
|
||||
<tiny-popover
|
||||
v-else
|
||||
trigger="hover"
|
||||
:visible-arrow="false"
|
||||
@show="state.visible = true"
|
||||
@hide="state.visible = false"
|
||||
placement="bottom-start"
|
||||
:popper-class="'tiny-locales__popper' + (popperClass ? ' ' + popperClass : '')"
|
||||
:append-to-body="popperAppendToBody"
|
||||
>
|
||||
<template #reference>
|
||||
<span
|
||||
>{{ state.text && t(state.text)
|
||||
}}<span>
|
||||
<IconChevronDown v-show="!state.visible" />
|
||||
<IconChevronUp v-show="state.visible" /> </span
|
||||
></span>
|
||||
</template>
|
||||
<div class="poplist">
|
||||
<li v-for="lang in state.locales" :key="lang" :class="{ selected: state.current === lang }" @click="switchLanguage(lang)">
|
||||
{{ t(lang) }}
|
||||
</li>
|
||||
</div>
|
||||
</tiny-popover>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
import { renderless, api } from '@opentiny/vue-renderless/locales/vue'
|
||||
import { use, enUS, zhCN } from '@opentiny/vue-locale'
|
||||
import TinyPopover from '@opentiny/vue-popover'
|
||||
import { IconChevronUp, IconChevronDown } from '@opentiny/vue-icon'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'Locales',
|
||||
components: {
|
||||
TinyPopover,
|
||||
IconChevronUp: IconChevronUp(),
|
||||
IconChevronDown: IconChevronDown()
|
||||
},
|
||||
props: {
|
||||
local: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
changeLang: Function,
|
||||
getLocale: Function,
|
||||
getDomain: Function,
|
||||
getCurrentLocale: Function,
|
||||
getChangeLocaleUrl: Function,
|
||||
fetchSsoUpdate: Function,
|
||||
popperClass: String,
|
||||
popperAppendToBody: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
const constants = {
|
||||
GLOBAL: 'global'
|
||||
}
|
||||
|
||||
return setup({
|
||||
props,
|
||||
context,
|
||||
renderless,
|
||||
api,
|
||||
mono: true,
|
||||
extendOptions: { use, zhCN, enUS, constants }
|
||||
})
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,18 +0,0 @@
|
|||
<template>
|
||||
<div class="tiny-logon-user">{{ state.userName }}</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
import { renderless, api } from '@opentiny/vue-renderless/logon-user/vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'LogonUser',
|
||||
props: {
|
||||
getUserInfo: Function
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,110 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<div class="tiny-mobile-mini-picker" v-show="visible" @click="visibleHandle">
|
||||
<div class="tiny-mobile-mini-picker__mask"></div>
|
||||
<div :class="['tiny-mobile-mini-picker__content', state.toggle ? 'is-toggle' : '']">
|
||||
<div class="tiny-mobile-mini-picker__toolbar">
|
||||
<slot name="toolbar">
|
||||
<div class="picker_action picker_cancel" @click="cancel">
|
||||
{{ cancelButtonText }}
|
||||
</div>
|
||||
<div class="picker_action picker_title">{{ title }}</div>
|
||||
<div class="picker_action picker_confirm" @click="confirm">
|
||||
{{ confirmButtonText }}
|
||||
</div>
|
||||
</slot>
|
||||
</div>
|
||||
<div class="tiny-mobile-mini-picker__columns" :style="{ height: state.clumnsWrapHeight + 'px' }">
|
||||
<picker-column
|
||||
:columns-item="item"
|
||||
v-for="(item, index) in state.formattedColumns"
|
||||
:ref="'childrenPicker' + index"
|
||||
:key="index"
|
||||
:default-index="item.defaultIndex || +state.defaultIndex"
|
||||
:item-height="itemHeight"
|
||||
:swipe-duration="swipeDuration"
|
||||
:value-key="valueKey"
|
||||
@change="change(index)"
|
||||
:visible-item-count="visibleItemCount"
|
||||
></picker-column>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { t } from '@opentiny/vue-locale'
|
||||
import { renderless, api } from '@opentiny/vue-renderless/mini-picker/vue'
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
import PickerColumn from '@opentiny/vue-picker-column'
|
||||
|
||||
const $constants = {
|
||||
CHILDREN_PICKER: 'childrenPicker'
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'MiniPicker',
|
||||
components: {
|
||||
PickerColumn
|
||||
},
|
||||
props: {
|
||||
_constants: {
|
||||
type: Object,
|
||||
default: () => $constants
|
||||
},
|
||||
columns: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
confirmButtonText: {
|
||||
type: String,
|
||||
default: () => t('ui.miniPicker.confirm')
|
||||
},
|
||||
cancelButtonText: {
|
||||
type: String,
|
||||
default: () => t('ui.miniPicker.cancel')
|
||||
},
|
||||
defaultIndex: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
valueKey: {
|
||||
type: String,
|
||||
default: 'text'
|
||||
},
|
||||
itemHeight: {
|
||||
type: Number,
|
||||
default: 34
|
||||
},
|
||||
visibleItemCount: {
|
||||
type: Number,
|
||||
default: 5
|
||||
},
|
||||
swipeDuration: {
|
||||
type: Number,
|
||||
default: 1000
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,127 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<transition name="tiny-zoom-in-top" @after-leave="$emit('dodestroy')">
|
||||
<div
|
||||
v-show="state.visible"
|
||||
class="tiny-picker-panel tiny-date-range-picker tiny-popper"
|
||||
:class="[
|
||||
{
|
||||
'has-sidebar': slots.sidebar || state.shortcuts
|
||||
},
|
||||
state.popperClass
|
||||
]"
|
||||
>
|
||||
<div class="tiny-picker-panel__body-wrapper">
|
||||
<slot name="sidebar" class="tiny-picker-panel__sidebar"></slot>
|
||||
<div class="tiny-picker-panel__sidebar" v-if="state.shortcuts">
|
||||
<button
|
||||
type="button"
|
||||
class="tiny-picker-panel__shortcut"
|
||||
v-for="(shortcut, key) in state.shortcuts"
|
||||
:key="key"
|
||||
@click="handleShortcutClick(shortcut)"
|
||||
>
|
||||
{{ shortcut.text }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="tiny-picker-panel__body">
|
||||
<div class="tiny-picker-panel__content tiny-date-range-picker__content is-left">
|
||||
<div class="tiny-date-range-picker__header">
|
||||
<button type="button" @click="leftPrevYear" class="tiny-picker-panel__icon-btn tiny-icon-d-arrow-left">
|
||||
<icon-double-left></icon-double-left>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
v-if="state.unlinkPanels"
|
||||
@click="leftNextYear"
|
||||
:disabled="!state.enableYearArrow"
|
||||
:class="{ 'is-disabled': !state.enableYearArrow }"
|
||||
class="tiny-picker-panel__icon-btn tiny-icon-d-arrow-right"
|
||||
>
|
||||
<icon-double-right></icon-double-right>
|
||||
</button>
|
||||
<div>{{ state.leftLabel }}</div>
|
||||
</div>
|
||||
<month-table
|
||||
selection-mode="range"
|
||||
:date="state.leftDate"
|
||||
:default-value="state.defaultValue"
|
||||
:min-date="state.minDate"
|
||||
:max-date="state.maxDate"
|
||||
:range-state="state.rangeState"
|
||||
:disabled-date="state.disabledDate"
|
||||
@changerange="handleChangeRange"
|
||||
@pick="handleRangePick"
|
||||
>
|
||||
</month-table>
|
||||
</div>
|
||||
<div class="tiny-picker-panel__content tiny-date-range-picker__content is-right">
|
||||
<div class="tiny-date-range-picker__header">
|
||||
<button
|
||||
type="button"
|
||||
v-if="state.unlinkPanels"
|
||||
@click="rightPrevYear"
|
||||
:disabled="!state.enableYearArrow"
|
||||
:class="{ 'is-disabled': !state.enableYearArrow }"
|
||||
class="tiny-picker-panel__icon-btn tiny-icon-d-arrow-left"
|
||||
>
|
||||
<icon-double-left></icon-double-left>
|
||||
</button>
|
||||
<button type="button" @click="rightNextYear" class="tiny-picker-panel__icon-btn tiny-icon-d-arrow-right">
|
||||
<icon-double-right></icon-double-right>
|
||||
</button>
|
||||
<div>{{ state.rightLabel }}</div>
|
||||
</div>
|
||||
<month-table
|
||||
selection-mode="range"
|
||||
:date="state.rightDate"
|
||||
:default-value="state.defaultValue"
|
||||
:min-date="state.minDate"
|
||||
:max-date="state.maxDate"
|
||||
:range-state="state.rangeState"
|
||||
:disabled-date="state.disabledDate"
|
||||
@changerange="handleChangeRange"
|
||||
@pick="handleRangePick"
|
||||
>
|
||||
</month-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { renderless, api } from '@opentiny/vue-renderless/month-range/vue'
|
||||
import { $prefix, setup, directive, defineComponent } from '@opentiny/vue-common'
|
||||
import Clickoutside from '@opentiny/vue-renderless/common/deps/clickoutside'
|
||||
import MonthTable from '@opentiny/vue-month-table'
|
||||
import { iconDoubleRight, iconDoubleLeft } from '@opentiny/vue-icon'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'MonthRange',
|
||||
directives: directive({ Clickoutside }),
|
||||
components: {
|
||||
MonthTable,
|
||||
IconDoubleRight: iconDoubleRight(),
|
||||
IconDoubleLeft: iconDoubleLeft()
|
||||
},
|
||||
props: {
|
||||
emitter: Object
|
||||
},
|
||||
emits: ['dodestroy', 'pick'],
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,55 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<table class="tiny-month-table" @mousemove="handleMouseMove" @click="handleMonthTableClick">
|
||||
<tbody>
|
||||
<tr v-for="(row, key) in state.rows" :key="key">
|
||||
<td v-for="(cell, key) in row" :class="getCellStyle(cell)" :key="key">
|
||||
<div>
|
||||
<a class="cell" v-text="t('ui.datepicker.months.' + state.months[cell.text])"></a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { renderless, api } from '@opentiny/vue-renderless/month-table/vue'
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
import { isDate } from '@opentiny/vue-renderless/common/deps/date-util'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'MonthTable',
|
||||
emits: ['changerange', 'pick'],
|
||||
props: {
|
||||
date: {},
|
||||
defaultValue: {
|
||||
validator: (val) => val === null || isDate(val) || (Array.isArray(val) && val.every(isDate))
|
||||
},
|
||||
disabledDate: {},
|
||||
maxDate: {},
|
||||
minDate: {},
|
||||
rangeState: {
|
||||
default: () => ({ endDate: null, selecting: false })
|
||||
},
|
||||
selectionMode: {
|
||||
default: 'month'
|
||||
},
|
||||
|
||||
value: {}
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,90 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<script lang="tsx">
|
||||
import { $prefix, h, defineComponent } from '@opentiny/vue-common' // 此处引入 h 是为了防止打包后 h 被重命名导致组件报错的问题
|
||||
import { iconChevronLeft, iconPlus } from '@opentiny/vue-icon'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'NavBar',
|
||||
props: {
|
||||
tiny_renderless: Function,
|
||||
title: String,
|
||||
subTitle: String,
|
||||
fixed: Boolean,
|
||||
zIndex: [Number, String],
|
||||
leftText: String,
|
||||
rightText: String,
|
||||
leftArrow: Boolean,
|
||||
rightArrow: Boolean
|
||||
},
|
||||
components: {
|
||||
LeftIcon: iconChevronLeft(),
|
||||
RightIcon: iconPlus()
|
||||
},
|
||||
render() {
|
||||
const { leftArrow, rightArrow, leftText, rightText, $listeners, $attrs, title, zIndex, fixed, subTitle } = this
|
||||
const $slots = '$scopedSlots' in this ? this.$slots : this.$slots
|
||||
|
||||
function noop() {}
|
||||
|
||||
function LeftPart() {
|
||||
if ($slots.left) return $slots.left()
|
||||
|
||||
return [
|
||||
leftArrow && <left-icon class="tiny-mobile-nav-bar__icon left-icon" />,
|
||||
leftText && h('span', { class: 'tiny-mobile-nav-bar__text left-text' }, leftText)
|
||||
]
|
||||
}
|
||||
|
||||
function RightPart() {
|
||||
if ($slots.right) return $slots.right()
|
||||
|
||||
return [
|
||||
rightArrow && <right-icon class="tiny-mobile-nav-bar__icon right-icon" />,
|
||||
rightText && <span class="tiny-mobile-nav-bar__text right-text">{rightText}</span>
|
||||
]
|
||||
}
|
||||
|
||||
let clickLeftListener = $attrs && $attrs.onClickLeft
|
||||
let clickRightListener = $attrs && $attrs.onClickRight
|
||||
|
||||
if (!clickLeftListener) {
|
||||
clickLeftListener = ($listeners && $listeners['click-left']) || noop
|
||||
}
|
||||
|
||||
if (!clickRightListener) {
|
||||
clickRightListener = ($listeners && $listeners['click-right']) || noop
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{ zIndex }}
|
||||
class={{
|
||||
'tiny-mobile-nav-bar': true,
|
||||
'tiny-mobile-nav-bar__fixed': fixed
|
||||
}}
|
||||
>
|
||||
<div class="tiny-mobile-nav-bar__left" onClick={clickLeftListener}>
|
||||
{LeftPart()}
|
||||
</div>
|
||||
<div class="tiny-mobile-nav-bar__title">
|
||||
<p class="main-title">{$slots.default ? $slots.default() : title}</p>
|
||||
<p class={{ 'is-show-subtitle': subTitle, 'sub-title': true }}>{subTitle}</p>
|
||||
</div>
|
||||
<div class="tiny-mobile-nav-bar__right" onClick={clickRightListener}>
|
||||
{RightPart()}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,119 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<script lang="tsx">
|
||||
import { $prefix, setup, h, defineComponent } from '@opentiny/vue-common'
|
||||
import { renderless, api } from '@opentiny/vue-renderless/notify/vue'
|
||||
import { iconClose } from '@opentiny/vue-icon'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'Notify',
|
||||
props: {
|
||||
beforeClose: Function,
|
||||
closeIcon: {
|
||||
type: Object,
|
||||
default: () => iconClose()
|
||||
},
|
||||
customClass: [String, Object],
|
||||
duration: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
message: [String, Function],
|
||||
onClose: Function,
|
||||
position: {
|
||||
type: String,
|
||||
default: 'bottom-right'
|
||||
},
|
||||
showClose: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
showIcon: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
statusIcon: Object,
|
||||
title: [String, Function],
|
||||
type: String
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
},
|
||||
render() {
|
||||
let { clearTimer, click, close, closeIcon, message, showClose } = this
|
||||
let { showIcon, startTimer, state, statusIcon, title, type } = this
|
||||
let { closeVNode = null, iconVNode = null, notifyContent = null, notifyTitle = null } = {}
|
||||
// Type Icon
|
||||
if (showIcon && statusIcon) {
|
||||
iconVNode = (
|
||||
<div class="tiny-notify__icon-zone">
|
||||
<span class="tiny-notify__icon-status">
|
||||
<statusIcon class="tiny-svg-size"></statusIcon>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
// Close Button
|
||||
if (showClose) {
|
||||
closeVNode = (
|
||||
<div class="tiny-notify__close-zone">
|
||||
<span class="tiny-notify__icon-close">
|
||||
<closeIcon class="tiny-svg-size" onClick={close}></closeIcon>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
// Msg Title
|
||||
if (title && typeof title === 'string') {
|
||||
notifyTitle = h('div', { class: 'tiny-notify__title' }, title)
|
||||
} else if (typeof title === 'function') {
|
||||
notifyTitle = title(h, { vm: this, titleClass: 'tiny-notify__title' })
|
||||
}
|
||||
// Msg Content
|
||||
if (typeof message === 'string') {
|
||||
notifyContent = h('p', { class: 'tiny-notify__content' }, message)
|
||||
} else if (typeof message === 'function') {
|
||||
notifyContent = message(h, {
|
||||
vm: this,
|
||||
messageClass: 'tiny-notify__content'
|
||||
})
|
||||
}
|
||||
// Main Msg Area
|
||||
let msgVNode = (
|
||||
<div class="tiny-notify__message-zone">
|
||||
{notifyTitle ? <div class="tiny-notify__title-wrapper">{notifyTitle}</div> : null}
|
||||
<div class="tiny-notify__content-wrapper">{notifyContent}</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
return (
|
||||
<div
|
||||
class={[
|
||||
'tiny-notify',
|
||||
'tiny-notify--' + type,
|
||||
showIcon ? '' : 'tiny-notify--no-icon',
|
||||
showClose ? '' : 'tiny-notify--no-close',
|
||||
state.position,
|
||||
state.customClass
|
||||
]}
|
||||
style={state.positionStyle}
|
||||
v-show="state.visible"
|
||||
onMouseenter={clearTimer}
|
||||
onMouseleave={startTimer}
|
||||
onClick={click}
|
||||
>
|
||||
{[iconVNode, msgVNode, closeVNode]}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,41 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<ul class="tiny-select-group__wrap" v-show="state.visible">
|
||||
<li class="tiny-select-group__title">{{ label }}</li>
|
||||
<li>
|
||||
<ul class="tiny-select-group">
|
||||
<slot></slot>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { renderless, api } from '@opentiny/vue-renderless/option-group/vue'
|
||||
import { setup, $prefix, defineComponent } from '@opentiny/vue-common'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'OptionGroup',
|
||||
componentName: 'OptionGroup',
|
||||
props: {
|
||||
label: String,
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,74 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<li
|
||||
ref="option"
|
||||
@mouseenter="hoverItem"
|
||||
@click.stop="selectOptionClick"
|
||||
@mousedown.stop=""
|
||||
class="tiny-select-dropdown__item"
|
||||
v-show="visible && state.visible"
|
||||
:class="[
|
||||
{
|
||||
selected: state.itemSelected,
|
||||
'is-disabled': disabled || state.groupDisabled || state.limitReached,
|
||||
hover: state.hover
|
||||
},
|
||||
highlightClass
|
||||
]"
|
||||
>
|
||||
<span v-if="state.select.multiple && !state.select.state.multipleLimit">
|
||||
<component :is="`icon-${state.selectCls}`" class="tiny-svg-size" />
|
||||
</span>
|
||||
<slot>
|
||||
<span>{{ state.currentLabel }}</span>
|
||||
</slot>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { renderless, api } from '@opentiny/vue-renderless/option/vue'
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
import { iconCheck, iconCheckedSur } from '@opentiny/vue-icon'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'Option',
|
||||
componentName: 'Option',
|
||||
components: {
|
||||
IconCheck: iconCheck(),
|
||||
IconCheckedSur: iconCheckedSur()
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
required: true
|
||||
},
|
||||
label: [String, Number],
|
||||
created: Boolean,
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
events: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
highlightClass: String
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,66 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<div class="tiny-pager__group tiny-unselect">
|
||||
<ul class="tiny-pager__pages" @click="onPagerClick">
|
||||
<li :class="{ 'is-active': currentPage === 1 }" v-if="pageCount > 0" v-text="'1'"></li>
|
||||
<li class="dot quickprev" v-if="state.showPrevMore" @mouseenter="onMouseenter('left')" @mouseleave="state.quickprevIconClass = popupIcon">
|
||||
<component :is="state.quickprevIconClass" />
|
||||
</li>
|
||||
<li v-for="pager in state.pagers" :key="pager" :class="{ 'is-active': currentPage === pager }" v-text="`${pager}`"></li>
|
||||
<li class="dot quicknext" v-if="state.showNextMore" @mouseenter="onMouseenter('right')" @mouseleave="state.quicknextIconClass = popupIcon">
|
||||
<component :is="state.quicknextIconClass" />
|
||||
</li>
|
||||
<li :class="{ 'is-active': pageCount === currentPage }" v-if="pageCount > 1" v-text="`${pageCount}`"></li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { setup, $prefix, defineComponent } from '@opentiny/vue-common'
|
||||
import { renderless, api } from '@opentiny/vue-renderless/pager-item/vue'
|
||||
import { iconPopup, iconDoubleLeft, iconDoubleRight } from '@opentiny/vue-icon'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'PagerItem',
|
||||
components: {
|
||||
IconPopup: iconPopup(),
|
||||
IconDoubleLeft: iconDoubleLeft(),
|
||||
IconDoubleRight: iconDoubleRight()
|
||||
},
|
||||
props: {
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
currentPage: Number,
|
||||
pageCount: Number,
|
||||
pagerCount: Number,
|
||||
popupIcon: {
|
||||
type: Object,
|
||||
default: () => iconPopup()
|
||||
},
|
||||
doubleLeftIcon: {
|
||||
type: Object,
|
||||
default: () => iconDoubleLeft()
|
||||
},
|
||||
doubleRightIcon: {
|
||||
type: Object,
|
||||
default: () => iconDoubleRight()
|
||||
},
|
||||
isBeforePageChange: Boolean
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,651 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<script lang="tsx">
|
||||
import Pager from '@opentiny/vue-pager-item'
|
||||
import Popover from '@opentiny/vue-popover'
|
||||
import { t } from '@opentiny/vue-locale'
|
||||
import { $prefix, h, defineComponent } from '@opentiny/vue-common'
|
||||
import { iconDeltaDown, iconDeltaUp, iconChevronLeft, iconChevronRight } from '@opentiny/vue-icon'
|
||||
import { emitEvent } from '@opentiny/vue-renderless/common/event'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'Pager',
|
||||
props: {
|
||||
pageSize: {
|
||||
type: Number,
|
||||
default: 10
|
||||
},
|
||||
total: Number,
|
||||
pageCount: Number,
|
||||
pagerCount: {
|
||||
type: Number,
|
||||
validator(value) {
|
||||
return (value | 0) === value && value > 2 && value < 22 && value % 2 === 1
|
||||
},
|
||||
default: 7
|
||||
},
|
||||
currentPage: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
layout: String,
|
||||
pageSizes: {
|
||||
type: Array,
|
||||
default() {
|
||||
return [10, 20, 30, 40, 50, 100]
|
||||
}
|
||||
},
|
||||
prevText: String,
|
||||
nextText: String,
|
||||
hideOnSinglePage: Boolean,
|
||||
mode: String,
|
||||
appendToBody: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
isBeforePageChange: Boolean,
|
||||
popperClass: String,
|
||||
popperAppendToBody: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
internalCurrentPage: 1,
|
||||
internalPageSize: 0,
|
||||
lastEmittedPage: -1,
|
||||
userChangePageSize: false,
|
||||
internalTotal: this.total
|
||||
}
|
||||
},
|
||||
render() {
|
||||
const layout = this.internalLayout
|
||||
|
||||
if (!layout) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (this.hideOnSinglePage && (!this.internalPageCount || this.internalPageCount === 1)) {
|
||||
return null
|
||||
}
|
||||
|
||||
const TEMPLATE_MAP = {
|
||||
prev: <prev></prev>,
|
||||
jumper: <jumper isBeforePageChange={this.isBeforePageChange} onBeforePageChange={this.beforeJumperChangeHandler} max={this.internalPageCount}></jumper>,
|
||||
current: <current></current>,
|
||||
pager: (
|
||||
<pager
|
||||
isBeforePageChange={this.isBeforePageChange}
|
||||
onBeforePageChange={this.beforePagerChangeHandler}
|
||||
currentPage={this.internalCurrentPage}
|
||||
pageCount={this.internalPageCount}
|
||||
pagerCount={this.pagerCount}
|
||||
onChange={this.handleCurrentChange}
|
||||
disabled={this.disabled}
|
||||
></pager>
|
||||
),
|
||||
next: <next></next>,
|
||||
sizes: (
|
||||
<sizes
|
||||
ref="sizes"
|
||||
isBeforePageChange={this.isBeforePageChange}
|
||||
onBeforePageChange={this.beforeSizeChangeHandler}
|
||||
popperAppendToBody={this.popperAppendToBody === false ? false : this.appendToBody}
|
||||
popperClass={this.popperClass}
|
||||
pageSizes={this.pageSizes}
|
||||
></sizes>
|
||||
),
|
||||
slot: <slot>{typeof this.$slots.default === 'function' ? this.$slots.default() : this.$slots.default}</slot>,
|
||||
total: <total></total>
|
||||
}
|
||||
|
||||
const components = layout.split(',').map((item) => item.trim())
|
||||
|
||||
const templateChildren = []
|
||||
|
||||
components.forEach((compo) => {
|
||||
templateChildren.push(TEMPLATE_MAP[compo])
|
||||
})
|
||||
|
||||
return <div class={['tiny-pager tiny-pager__number']}>{templateChildren}</div>
|
||||
},
|
||||
components: {
|
||||
Prev: {
|
||||
render() {
|
||||
const ChevronLeft = iconChevronLeft()
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
class="tiny-pager__btn-prev"
|
||||
disabled={this.$parent.disabled || this.$parent.internalCurrentPage <= 1}
|
||||
onClick={this.$parent.prev}
|
||||
>
|
||||
{this.$parent.prevText ? <span>{this.$parent.prevText}</span> : <ChevronLeft class="tiny-svg-size" />}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
},
|
||||
Next: {
|
||||
render() {
|
||||
const ChevronRight = iconChevronRight()
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
class="tiny-pager__btn-next"
|
||||
disabled={this.$parent.disabled || this.$parent.internalCurrentPage === this.$parent.internalPageCount || this.$parent.internalPageCount === 0}
|
||||
onClick={this.$parent.next}
|
||||
>
|
||||
{this.$parent.nextText ? <span>{this.$parent.nextText}</span> : <ChevronRight class="tiny-svg-size" />}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
},
|
||||
Current: {
|
||||
render() {
|
||||
const { internalCurrentPage } = this.$parent
|
||||
|
||||
return (
|
||||
<div class="tiny-pager__group tiny-unselect">
|
||||
<ul class="tiny-pager__pages">
|
||||
<li class="is-active" v-text={internalCurrentPage}></li>
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},
|
||||
Sizes: {
|
||||
props: {
|
||||
pageSizes: Array,
|
||||
appendToBody: Boolean,
|
||||
isBeforePageChange: Boolean,
|
||||
popperClass: String,
|
||||
popperAppendToBody: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showSizes: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
pageSizes: {
|
||||
immediate: true,
|
||||
handler(newVal) {
|
||||
if (Array.isArray(newVal)) {
|
||||
this.$parent.internalPageSize = newVal.includes(this.$parent.pageSize) ? this.$parent.pageSize : this.pageSizes[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
render() {
|
||||
const ChevronUp = iconDeltaUp()
|
||||
const ChevronDown = iconDeltaDown()
|
||||
|
||||
const scopedSlots = {
|
||||
reference: () => (
|
||||
<div slot="reference" class="tiny-pager__popover">
|
||||
<div class="tiny-pager__input">
|
||||
<input type="text" readonly="readonly" value={this.$parent.internalPageSize} />
|
||||
<div class="tiny-pager__input-btn">{this.showSizes ? <ChevronUp class="tiny-svg-size" /> : <ChevronDown class="tiny-svg-size" />}</div>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
default: () => (
|
||||
<div class="tiny-pager tiny-pager__selector-body">
|
||||
<ul class="tiny-pager__selector-poplist">
|
||||
{this.pageSizes.map((item) => (
|
||||
<li
|
||||
class={['list-item', item === this.$parent.internalPageSize ? 'is-selected select-pre' : '']}
|
||||
val={item}
|
||||
title={item}
|
||||
onClick={() => this.handleChange(item)}
|
||||
>
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div class={['tiny-pager__group', 'tiny-pager__sizes']}>
|
||||
{h(Popover, {
|
||||
props: {
|
||||
placement: 'bottom-start',
|
||||
appendToBody: this.popperAppendToBody,
|
||||
trigger: 'click',
|
||||
popperClass: 'tiny-pager__selector' + (this.popperClass ? ' ' + this.popperClass : ''),
|
||||
visibleArrow: false
|
||||
},
|
||||
scopedSlots,
|
||||
ref: 'sizesList'
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
},
|
||||
methods: {
|
||||
handleChange(val) {
|
||||
if (val !== this.$parent.internalPageSize) {
|
||||
const callback = () => {
|
||||
if (!this.$parent.beforeChangeHandler()) {
|
||||
return false
|
||||
}
|
||||
|
||||
this.$parent.internalPageSize = val = parseInt(val, 10)
|
||||
this.$parent.userChangePageSize = true
|
||||
this.showSizes = false
|
||||
this.$parent.$emit('update:pageSize', val)
|
||||
this.$parent.$emit('size-change', val)
|
||||
this.$parent.$emit('page-change', {
|
||||
currentPage: this.$parent.internalCurrentPage,
|
||||
pageSize: val,
|
||||
total: this.$parent.internalTotal
|
||||
})
|
||||
this.$refs.sizesList.state.showPopper = false
|
||||
}
|
||||
|
||||
if (this.isBeforePageChange) {
|
||||
let newPageSize = val
|
||||
let currentPageSize = this.$parent.internalPageSize
|
||||
let params = { newPageSize, currentPageSize, callback }
|
||||
|
||||
this.$parent.beforePagerChangeHandler(params)
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Jumper: {
|
||||
props: {
|
||||
isBeforePageChange: Boolean,
|
||||
disabled: Boolean,
|
||||
min: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
max: {
|
||||
type: Number,
|
||||
default: 10
|
||||
},
|
||||
initValue: {
|
||||
type: Number,
|
||||
default: 1
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
backupValue: String(this.initValue),
|
||||
value: String(this.initValue)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'$parent.internalCurrentPage': function (currentPage) {
|
||||
const value = String(currentPage)
|
||||
|
||||
if (this.value !== value) {
|
||||
this.value = value
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleFocus(e) {
|
||||
this.backupValue = e.target.value
|
||||
},
|
||||
handleInput(e) {
|
||||
if (!e.target.value) {
|
||||
this.value = ''
|
||||
} else if (/^\d+$/.test(e.target.value)) {
|
||||
this.value = Number(e.target.value) || 1
|
||||
}
|
||||
e.target.value = this.value
|
||||
},
|
||||
handleChange() {
|
||||
this.parseValueNumber()
|
||||
|
||||
const callback = () => {
|
||||
this.handleClick()
|
||||
}
|
||||
const rollback = () => {
|
||||
this.value = String(this.backupValue)
|
||||
}
|
||||
const newPage = this.value
|
||||
const currentPage = this.backupValue
|
||||
|
||||
if (this.isBeforePageChange && newPage !== currentPage) {
|
||||
const params = { newPage, currentPage, callback, rollback }
|
||||
|
||||
this.$parent.beforePagerChangeHandler(params)
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
handleClick() {
|
||||
this.$parent.internalCurrentPage = this.$parent.getValidCurrentPage(this.value)
|
||||
this.$parent.emitChange()
|
||||
},
|
||||
isValueNumber() {
|
||||
return !isNaN(Number(this.value))
|
||||
},
|
||||
parseValueNumber() {
|
||||
let value = Number(
|
||||
String(this.value)
|
||||
.split(/[^0-9-+.]/)
|
||||
.join('')
|
||||
)
|
||||
|
||||
if (isNaN(value)) {
|
||||
value = this.min
|
||||
}
|
||||
|
||||
value = value.toFixed(0)
|
||||
|
||||
const min = this.min
|
||||
const max = this.max
|
||||
|
||||
if (value >= max) {
|
||||
this.value = String(max)
|
||||
} else if (value <= min) {
|
||||
this.value = String(min)
|
||||
} else {
|
||||
this.value = String(value)
|
||||
}
|
||||
}
|
||||
},
|
||||
render() {
|
||||
return h(
|
||||
'div',
|
||||
{
|
||||
class: ['tiny-pager__group']
|
||||
},
|
||||
[
|
||||
h('div', { class: ['tiny-pager__goto'] }, [
|
||||
h('input', {
|
||||
domProps: {
|
||||
value: this.value
|
||||
},
|
||||
attrs: {
|
||||
type: 'text',
|
||||
disabled: this.disabled
|
||||
},
|
||||
on: {
|
||||
focus: this.handleFocus,
|
||||
input: this.handleInput,
|
||||
change: this.handleChange
|
||||
},
|
||||
ref: 'input'
|
||||
}),
|
||||
h(
|
||||
'button',
|
||||
{
|
||||
class: ['tiny-btn'],
|
||||
attrs: { type: 'button' },
|
||||
on: { click: this.handleClick }
|
||||
},
|
||||
[t('ui.page.goto')]
|
||||
)
|
||||
])
|
||||
]
|
||||
)
|
||||
}
|
||||
},
|
||||
Total: {
|
||||
render() {
|
||||
return typeof this.$parent.internalTotal === 'number'
|
||||
? (
|
||||
<div class={['tiny-pager__group']}>
|
||||
{' '}
|
||||
<div class="tiny-pager__total">
|
||||
<span>{t('ui.page.total')}:</span>
|
||||
<span class="tiny-pager__total-allpage">{this.$parent.internalTotal}</span>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
: (
|
||||
''
|
||||
)
|
||||
}
|
||||
},
|
||||
Pager
|
||||
},
|
||||
methods: {
|
||||
beforeSizeChangeHandler(params) {
|
||||
const { newPageSize, currentPageSize, callback } = params
|
||||
const newPage = 1
|
||||
const currentPage = this.internalCurrentPage
|
||||
const temp = {
|
||||
newPage,
|
||||
newPageSize,
|
||||
currentPage,
|
||||
currentPageSize,
|
||||
callback
|
||||
}
|
||||
|
||||
this.$emit('before-page-change', temp)
|
||||
},
|
||||
beforePagerChangeHandler(params) {
|
||||
const { newPage, currentPage, callback } = params
|
||||
const newPageSize = this.internalPageSize
|
||||
const currentPageSize = this.internalPageSize
|
||||
const temp = {
|
||||
newPage,
|
||||
newPageSize,
|
||||
currentPage,
|
||||
currentPageSize,
|
||||
callback
|
||||
}
|
||||
|
||||
this.$emit('before-page-change', temp)
|
||||
},
|
||||
beforeJumperChangeHandler(params) {
|
||||
const { newPage, currentPage, callback, rollback } = params
|
||||
const newPageSize = this.internalPageSize
|
||||
const currentPageSize = this.internalPageSize
|
||||
const temp = {
|
||||
newPage,
|
||||
newPageSize,
|
||||
currentPage,
|
||||
currentPageSize,
|
||||
callback,
|
||||
rollback
|
||||
}
|
||||
|
||||
this.$emit('before-page-change', temp)
|
||||
},
|
||||
copyEmit(...args) {
|
||||
this.$emit.apply(this, args)
|
||||
},
|
||||
beforeChangeHandler(val = -1) {
|
||||
return emitEvent(this.copyEmit, 'before-change', this.internalCurrentPage, this, val)
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
if (!this.beforeChangeHandler(val)) {
|
||||
return false
|
||||
}
|
||||
|
||||
this.internalCurrentPage = this.getValidCurrentPage(val)
|
||||
this.userChangePageSize = true
|
||||
this.emitChange()
|
||||
},
|
||||
prev() {
|
||||
const callback = () => {
|
||||
if (this.disabled || !this.beforeChangeHandler(this.internalCurrentPage - 1)) {
|
||||
return false
|
||||
}
|
||||
|
||||
const newVal = this.internalCurrentPage - 1
|
||||
|
||||
this.internalCurrentPage = this.getValidCurrentPage(newVal)
|
||||
this.$emit('prev-click', this.internalCurrentPage)
|
||||
this.emitChange()
|
||||
}
|
||||
|
||||
if (this.isBeforePageChange) {
|
||||
const newPage = this.internalCurrentPage - 1
|
||||
const temp = this.buildBeforePageChangeParam({ newPage, callback })
|
||||
|
||||
this.$emit('before-page-change', temp)
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
next() {
|
||||
const callback = () => {
|
||||
if (this.disabled || !this.beforeChangeHandler(this.internalCurrentPage + 1)) {
|
||||
return false
|
||||
}
|
||||
|
||||
const newVal = this.internalCurrentPage + 1
|
||||
|
||||
this.internalCurrentPage = this.getValidCurrentPage(newVal)
|
||||
this.$emit('next-click', this.internalCurrentPage)
|
||||
this.emitChange()
|
||||
}
|
||||
|
||||
if (this.isBeforePageChange) {
|
||||
const newPage = this.internalCurrentPage + 1
|
||||
const temp = this.buildBeforePageChangeParam({ newPage, callback })
|
||||
|
||||
this.$emit('before-page-change', temp)
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
buildBeforePageChangeParam(param) {
|
||||
const currentPage = this.internalCurrentPage
|
||||
const newPageSize = this.internalPageSize
|
||||
const currentPageSize = this.internalPageSize
|
||||
|
||||
return { currentPage, newPageSize, currentPageSize, ...param }
|
||||
},
|
||||
getValidCurrentPage(val) {
|
||||
val = parseInt(val, 10)
|
||||
|
||||
const hasPageCount = typeof this.internalPageCount === 'number'
|
||||
let resetVal
|
||||
|
||||
if (hasPageCount) {
|
||||
if (val < 1) {
|
||||
resetVal = 1
|
||||
} else if (val > this.internalPageCount) {
|
||||
resetVal = this.internalPageCount
|
||||
}
|
||||
} else {
|
||||
if (isNaN(val) || val < 1) {
|
||||
resetVal = 1
|
||||
}
|
||||
}
|
||||
|
||||
if (resetVal === undefined && isNaN(val)) {
|
||||
resetVal = 1
|
||||
} else if (resetVal === 0) {
|
||||
resetVal = 1
|
||||
}
|
||||
|
||||
return resetVal === undefined ? val : resetVal
|
||||
},
|
||||
emitChange() {
|
||||
this.$nextTick(() => {
|
||||
if (this.internalCurrentPage !== this.lastEmittedPage || this.userChangePageSize) {
|
||||
this.$emit('current-change', this.internalCurrentPage)
|
||||
this.$emit('update:current-page', this.internalCurrentPage)
|
||||
this.$emit('page-change', {
|
||||
currentPage: this.internalCurrentPage,
|
||||
pageSize: this.internalPageSize,
|
||||
total: this.internalTotal
|
||||
})
|
||||
this.lastEmittedPage = this.internalCurrentPage
|
||||
this.userChangePageSize = false
|
||||
}
|
||||
})
|
||||
},
|
||||
setTotal(val) {
|
||||
this.internalTotal = val
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
internalPageCount() {
|
||||
if (typeof this.internalTotal === 'number') {
|
||||
return Math.max(1, Math.ceil(this.internalTotal / this.internalPageSize))
|
||||
} else if (typeof this.pageCount === 'number') {
|
||||
return Math.max(1, this.pageCount)
|
||||
}
|
||||
|
||||
return null
|
||||
},
|
||||
internalLayout() {
|
||||
let layout = ''
|
||||
|
||||
if (this.mode && !this.layout) {
|
||||
this.mode === 'number' && (layout = 'total, sizes, prev, pager, next, jumper')
|
||||
this.mode === 'simple' && (layout = 'sizes, total, prev, current, next')
|
||||
this.mode === 'complete' && (layout = 'sizes, total, prev, pager, next, jumper')
|
||||
this.mode === 'fixed' && (layout = 'prev,pager,next')
|
||||
} else if ((!this.mode && this.layout) || (this.mode && this.layout)) {
|
||||
layout = this.layout
|
||||
} else {
|
||||
layout = 'total, prev, pager, next, jumper'
|
||||
}
|
||||
|
||||
return layout
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
currentPage: {
|
||||
immediate: true,
|
||||
handler(val) {
|
||||
this.internalCurrentPage = this.getValidCurrentPage(val)
|
||||
}
|
||||
},
|
||||
pageSize: {
|
||||
immediate: true,
|
||||
handler(val) {
|
||||
this.internalPageSize = isNaN(val) ? 10 : val
|
||||
}
|
||||
},
|
||||
internalCurrentPage: {
|
||||
immediate: true,
|
||||
handler(newVal) {
|
||||
this.$emit('update:currentPage', newVal)
|
||||
this.lastEmittedPage = -1
|
||||
}
|
||||
},
|
||||
internalPageCount(newVal) {
|
||||
/* istanbul ignore if */
|
||||
const oldPage = this.internalCurrentPage
|
||||
|
||||
if (newVal > 0 && oldPage === 0) {
|
||||
this.internalCurrentPage = 1
|
||||
} else if (oldPage > newVal) {
|
||||
this.internalCurrentPage = newVal === 0 ? 1 : newVal
|
||||
this.userChangePageSize && this.emitChange()
|
||||
}
|
||||
|
||||
this.userChangePageSize = false
|
||||
},
|
||||
total(val) {
|
||||
this.internalTotal = val
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,56 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<div class="tiny-mobile-picker-column">
|
||||
<div class="tiny-mobile-picker-column__mask" :style="state.maskStyle"></div>
|
||||
<div class="tiny-mobile-picker-column__indicator" :style="{ height: itemHeight + 'px' }"></div>
|
||||
<ul class="tiny-mobile-picker-column__wrapper" ref="track" :style="state.wrapperStyle" @click="onClickItem(1)">
|
||||
<li
|
||||
:class="{
|
||||
'tiny-mobile-picker-column__item': true,
|
||||
'is-select': index === state.currentIndex
|
||||
}"
|
||||
v-for="(item, index) in state.columnsItem.values"
|
||||
:key="index"
|
||||
@click.stop="onClickItem(index)"
|
||||
:style="{ height: itemHeight + 'px', lineHeight: itemHeight + 'px' }"
|
||||
@transitionend="onTransitionEnd"
|
||||
>
|
||||
{{ item }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { renderless, api } from '@opentiny/vue-renderless/picker-column/vue'
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'PickerColumn',
|
||||
emits: ['change'],
|
||||
props: {
|
||||
columnsItem: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
defaultIndex: Number,
|
||||
itemHeight: Number,
|
||||
visibleItemCount: Number,
|
||||
swipeDuration: Number,
|
||||
valueKey: String
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,257 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<tiny-input
|
||||
:tabindex="tabindex"
|
||||
v-if="!state.ranged"
|
||||
class="tiny-date-editor"
|
||||
:class="'tiny-date-editor--' + state.type"
|
||||
:readonly="!editable || readonly || state.type === 'dates' || state.type === 'week'"
|
||||
:disabled="state.pickerDisabled"
|
||||
:size="state.pickerSize"
|
||||
:name="name"
|
||||
v-bind="state.firstInputId"
|
||||
v-clickoutside="handleClose"
|
||||
:placeholder="placeholder"
|
||||
@focus="handleFocus"
|
||||
@keydown="handleKeydown"
|
||||
:modelValue="state.displayValue"
|
||||
:title="state.displayValue"
|
||||
@update:modelValue="(value) => (state.userInput = value)"
|
||||
@change="handleChange"
|
||||
@mouseenter="handleMouseEnter"
|
||||
@mouseleave="state.showClose = false"
|
||||
:validateEvent="false"
|
||||
ref="reference"
|
||||
>
|
||||
<template #suffix>
|
||||
<i class="tiny-input__icon">
|
||||
<transition name="tiny-transition-icon-scale-in">
|
||||
<component
|
||||
:is="state.showClose ? clearIcon : null"
|
||||
@click="handleClickIcon"
|
||||
@mouseenter="state.showClose = true"
|
||||
@mouseleave="state.showClose = false"
|
||||
v-if="state.haveTrigger"
|
||||
class="baseClearicon"
|
||||
/>
|
||||
</transition>
|
||||
<component :is="state.triggerClass" @click="handleFocus" class="tiny-svg-size" />
|
||||
</i>
|
||||
</template>
|
||||
<template #panel>
|
||||
<component
|
||||
:is="state.panel"
|
||||
ref="picker"
|
||||
:visible="state.pickerVisible"
|
||||
@pick="handlePick"
|
||||
@select-range="handleSelectRange"
|
||||
@select-change="handleSelectChange"
|
||||
></component>
|
||||
</template>
|
||||
</tiny-input>
|
||||
<div
|
||||
class="tiny-date-editor tiny-range-editor tiny-input tiny-input__inner"
|
||||
:class="[
|
||||
'tiny-date-editor--' + state.type,
|
||||
state.pickerSize ? `tiny-range-editor--${state.pickerSize}` : '',
|
||||
state.pickerDisabled ? 'is-disabled' : '',
|
||||
state.pickerVisible ? 'is-active' : ''
|
||||
]"
|
||||
@click="handleFocus"
|
||||
@mouseenter="handleMouseEnter"
|
||||
@mouseleave="state.showClose = false"
|
||||
@keydown="handleKeydown"
|
||||
ref="reference"
|
||||
v-clickoutside="handleClose"
|
||||
v-else
|
||||
>
|
||||
<input
|
||||
autocomplete="off"
|
||||
:placeholder="startPlaceholder"
|
||||
:value="state.displayValue && state.displayValue[0]"
|
||||
:disabled="state.pickerDisabled"
|
||||
v-bind="state.firstInputId"
|
||||
:readonly="!editable || readonly"
|
||||
:name="name && name[0]"
|
||||
@input="handleStartInput"
|
||||
@change="handleStartChange"
|
||||
@focus="handleFocus"
|
||||
class="tiny-range-input"
|
||||
/>
|
||||
<slot name="range-separator">
|
||||
<span v-if="typeof rangeSeparator === 'string'" class="tiny-range-separator">{{ rangeSeparator }}</span>
|
||||
<component v-else :is="rangeSeparator" />
|
||||
</slot>
|
||||
<input
|
||||
autocomplete="off"
|
||||
:placeholder="endPlaceholder"
|
||||
:value="state.displayValue && state.displayValue[1]"
|
||||
:disabled="state.pickerDisabled"
|
||||
v-bind="state.secondInputId"
|
||||
:readonly="!editable || readonly"
|
||||
:name="name && name[1]"
|
||||
@input="handleEndInput"
|
||||
@change="handleEndChange"
|
||||
@focus="handleFocus"
|
||||
class="tiny-range-input"
|
||||
/>
|
||||
<i @click="handleClickIcon" v-if="state.haveTrigger" class="tiny-input__icon tiny-range__close-icon">
|
||||
<transition name="tiny-transition-icon-scale-in">
|
||||
<component :is="state.showClose ? clearIcon : null" />
|
||||
</transition>
|
||||
</i>
|
||||
<i class="tiny-input__icon tiny-range__icon tiny-input__suffix">
|
||||
<component :is="state.triggerClass" />
|
||||
</i>
|
||||
<component :is="state.panel" ref="picker" :visible="state.pickerVisible" @pick="handlePick" @select-range="handleSelectRange"></component>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { renderless, api } from '@opentiny/vue-renderless/picker/vue'
|
||||
import { $prefix, setup, directive, defineComponent } from '@opentiny/vue-common'
|
||||
import Input from '@opentiny/vue-input'
|
||||
import Clickoutside from '@opentiny/vue-renderless/common/deps/clickoutside'
|
||||
import DatePanel from '@opentiny/vue-date-panel'
|
||||
import DateRangePanel from '@opentiny/vue-date-range'
|
||||
import MonthRangePanel from '@opentiny/vue-month-range'
|
||||
import TimePanel from '@opentiny/vue-time'
|
||||
import TimeRangePanel from '@opentiny/vue-time-range'
|
||||
import TimeSelect from '@opentiny/vue-time-panel'
|
||||
import { iconCalendar, iconTime, iconClose } from '@opentiny/vue-icon'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'Picker',
|
||||
components: {
|
||||
TinyInput: Input,
|
||||
IconCalendar: iconCalendar(),
|
||||
IconTime: iconTime(),
|
||||
IconClose: iconClose()
|
||||
},
|
||||
emits: ['created', 'select-change', 'update:modelValue', 'blur', 'focus', 'change'],
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
default: 'date'
|
||||
},
|
||||
tabindex: {
|
||||
type: String,
|
||||
default: '1'
|
||||
},
|
||||
timeArrowControl: Boolean,
|
||||
size: String,
|
||||
format: String,
|
||||
valueFormat: String,
|
||||
timeFormat: String,
|
||||
readonly: Boolean,
|
||||
placeholder: String,
|
||||
startPlaceholder: String,
|
||||
endPlaceholder: String,
|
||||
prefixIcon: Object,
|
||||
suffixIcon: Object,
|
||||
clearIcon: {
|
||||
type: Object,
|
||||
default() {
|
||||
return iconClose()
|
||||
}
|
||||
},
|
||||
name: {
|
||||
default: '',
|
||||
validator(value) {
|
||||
return (
|
||||
value === null ||
|
||||
value === undefined ||
|
||||
typeof value === 'string' ||
|
||||
value instanceof String ||
|
||||
(Array.isArray(value) && value.length === 2 && value.every((item) => typeof item === 'string' || item instanceof String))
|
||||
)
|
||||
}
|
||||
},
|
||||
disabled: Boolean,
|
||||
clearable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
id: {
|
||||
default: '',
|
||||
validator(value) {
|
||||
return (
|
||||
value === null ||
|
||||
value === undefined ||
|
||||
typeof value === 'string' ||
|
||||
value instanceof String ||
|
||||
(Array.isArray(value) && value.length === 2 && value.every((item) => typeof item === 'string' || item instanceof String))
|
||||
)
|
||||
}
|
||||
},
|
||||
popperClass: String,
|
||||
popperAppendToBody: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
editable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
align: {
|
||||
type: String,
|
||||
default: 'left'
|
||||
},
|
||||
modelValue: {},
|
||||
defaultValue: {},
|
||||
defaultTime: {},
|
||||
rangeSeparator: {
|
||||
type: [Object, String],
|
||||
default: '-'
|
||||
},
|
||||
pickerOptions: {},
|
||||
unlinkPanels: Boolean,
|
||||
validateEvent: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
isRange: Boolean,
|
||||
arrowControl: Boolean,
|
||||
timezoneData: {},
|
||||
showTimezone: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
defaultTimezone: String,
|
||||
isutc8: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
dbTimezone: Number,
|
||||
timezone: Number,
|
||||
iso8601: Boolean
|
||||
},
|
||||
directives: directive({ Clickoutside }),
|
||||
setup(props, context) {
|
||||
return setup({
|
||||
props,
|
||||
context,
|
||||
renderless,
|
||||
api,
|
||||
extendOptions: {
|
||||
DatePanel,
|
||||
DateRangePanel,
|
||||
MonthRangePanel,
|
||||
TimePanel,
|
||||
TimeRangePanel,
|
||||
TimeSelect
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,113 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<span ref="root">
|
||||
<transition :name="transition" @after-enter="handleAfterEnter" @after-leave="handleAfterLeave">
|
||||
<div
|
||||
class="tiny-popover tiny-popper"
|
||||
:class="[popperClass, content && 'tiny-popover__plain', { 'no-arrow': !visibleArrow }]"
|
||||
ref="popper"
|
||||
v-show="!disabled && state.showPopper"
|
||||
:style="{ width: width === 'auto' ? width : width + 'px', height: height === 'auto' ? height : height + 'px' }"
|
||||
role="tooltip"
|
||||
:id="state.tooltipId"
|
||||
:aria-hidden="disabled || !state.showPopper ? 'true' : 'false'"
|
||||
>
|
||||
<div class="tiny-popover__title" v-if="title" v-text="title"></div>
|
||||
<slot>{{ content }}</slot>
|
||||
</div>
|
||||
</transition>
|
||||
<span ref="wrapper" class="reference-wrapper" :class="{ 'reference-wrapper-show': !disabled && state.showPopper }">
|
||||
<slot name="reference"></slot>
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { setup, $prefix, defineComponent } from '@opentiny/vue-common'
|
||||
import { renderless, api } from '@opentiny/vue-renderless/popover/vue'
|
||||
|
||||
export default defineComponent({
|
||||
inheritAttrs: false,
|
||||
name: $prefix + 'Popover',
|
||||
emits: ['update:modelValue', 'hide', 'show', 'after-enter', 'after-leave', 'created'],
|
||||
props: {
|
||||
appendToBody: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
arrowOffset: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
boundariesPadding: {
|
||||
type: Number,
|
||||
default: 5
|
||||
},
|
||||
closeDelay: {
|
||||
type: Number,
|
||||
default: 200
|
||||
},
|
||||
content: String,
|
||||
disabled: Boolean,
|
||||
modelValue: Boolean,
|
||||
offset: {
|
||||
default: 0
|
||||
},
|
||||
openDelay: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
placement: {
|
||||
type: String,
|
||||
default: 'bottom'
|
||||
},
|
||||
popper: {},
|
||||
popperClass: String,
|
||||
popperOptions: {
|
||||
type: Object,
|
||||
default: () => ({ gpuAcceleration: false })
|
||||
},
|
||||
reference: {},
|
||||
tabindex: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
title: String,
|
||||
transformOrigin: {
|
||||
type: [Boolean, String],
|
||||
default: true
|
||||
},
|
||||
transition: {
|
||||
type: String,
|
||||
default: 'fade-in-linear'
|
||||
},
|
||||
trigger: {
|
||||
type: String,
|
||||
default: 'click',
|
||||
validator: (value: string) => Boolean(~['click', 'focus', 'hover', 'manual'].indexOf(value))
|
||||
},
|
||||
visibleArrow: {
|
||||
default: true
|
||||
},
|
||||
width: {
|
||||
type: [String, Number]
|
||||
},
|
||||
height: {
|
||||
type: [String, Number]
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,102 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<div>
|
||||
<transition :name="state.transitionName" @after-enter="opened" @after-leave="closed">
|
||||
<div
|
||||
v-show="modelValue"
|
||||
ref="popup"
|
||||
class="tiny-popup"
|
||||
:style="state.style"
|
||||
@click="$emit('click')"
|
||||
:class="[round ? 'tiny-popup--round' : '', position ? 'tiny-popup--' + position : '', popupClass]"
|
||||
>
|
||||
<slot></slot>
|
||||
<icon-close class="tiny-popup__close-icon tiny-popup__close-icon--top-right" v-if="closeable" fill="#c8c9cc" tabindex="0" @click="close"></icon-close>
|
||||
</div>
|
||||
</transition>
|
||||
<transition name="tiny-fade">
|
||||
<div v-show="state.opened && overlay" :style="state.overlayStyle" :class="overlayClass" class="tiny-overlay" @click="clickOverlay">
|
||||
<slot name="overlay"></slot>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { setup, $prefix, defineComponent } from '@opentiny/vue-common'
|
||||
import { renderless, api } from '@opentiny/vue-renderless/popup/vue'
|
||||
import { iconClose } from '@opentiny/vue-icon'
|
||||
|
||||
const $constants = {
|
||||
OVERFLOWHIDDEN: 'tiny-overflow-hidde'
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'Popup',
|
||||
emits: ['open', 'close', 'update:modelValue', 'click-overlay', 'closed', 'opened', 'click'],
|
||||
components: {
|
||||
IconClose: iconClose()
|
||||
},
|
||||
props: {
|
||||
_constants: {
|
||||
type: Object,
|
||||
default: () => $constants
|
||||
},
|
||||
closeIcon: {
|
||||
type: String,
|
||||
default: 'cross'
|
||||
},
|
||||
closeIconPosition: {
|
||||
type: String,
|
||||
default: 'top-right'
|
||||
},
|
||||
closeOnClickOverlay: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
closeable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
duration: [Number, String],
|
||||
lazyRender: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
lockScroll: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
modelValue: Boolean,
|
||||
overlay: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
overlayClass: String,
|
||||
overlayStyle: Object,
|
||||
popupClass: String,
|
||||
popupStyle: Object,
|
||||
position: {
|
||||
type: String,
|
||||
default: 'center'
|
||||
},
|
||||
round: Boolean,
|
||||
safeAreaInsetBottom: Boolean,
|
||||
transition: String,
|
||||
zIndex: [Number, String]
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,84 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<div class="tiny-mobile-pull-refresh" :style="state.refreshStyle">
|
||||
<div class="tiny-mobile-pull-refresh__track" ref="track" :style="{
|
||||
'transition-duration': state.animationDuration + 'ms',
|
||||
transform: 'translate3d(0px,' + state.translate3d + 'px,0px)'
|
||||
}">
|
||||
<div class="tiny-mobile-pull-refresh__tips tiny-mobile-pull-refresh__head" :style="{ height: state.pullDown.headHeight + 'px' }" v-if="state.pullDownLoading || state.pullDownReplaces">
|
||||
<span v-if="!state.pullDownLoading">{{ state.pullDownReplaces }}</span>
|
||||
<slot name="loading" v-if="state.pullDownLoading">
|
||||
<ul v-if="state.pullDownLoading" class="tiny-mobile-pull-refresh__loading">
|
||||
<i></i>
|
||||
<i></i>
|
||||
<i></i>
|
||||
</ul>
|
||||
</slot>
|
||||
</div>
|
||||
<div class="tiny-mobile-pull-refresh__content">
|
||||
<slot></slot>
|
||||
</div>
|
||||
<div class="tiny-mobile-pull-refresh__tips tiny-mobile-pull-refresh__foot" :style="{ height: state.pullUp.footHeight + 'px' }" v-if="state.pullUpLoading || state.pullUpReplaces">
|
||||
<span v-if="!state.pullUpLoading">{{ state.pullUpReplaces }}</span>
|
||||
<slot name="loading" v-if="state.pullUpLoading">
|
||||
<ul v-if="state.pullUpLoading" class="tiny-mobile-pull-refresh__loading">
|
||||
<i></i>
|
||||
<i></i>
|
||||
<i></i>
|
||||
</ul>
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
import { renderless, api } from '@opentiny/vue-renderless/pull-refresh/vue'
|
||||
import '@opentiny/vue-theme-mobile/pull-refresh/index.less'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'PullRefresh',
|
||||
props: {
|
||||
modelValue: Boolean,
|
||||
loosingText: String,
|
||||
successText: String,
|
||||
failedText: String,
|
||||
successDuration: {
|
||||
type: [Number, String],
|
||||
default: 500
|
||||
},
|
||||
animationDuration: {
|
||||
type: [Number, String],
|
||||
default: 300
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
pullUp: {
|
||||
type: Function
|
||||
},
|
||||
pullDown: {
|
||||
type: Function
|
||||
},
|
||||
hasMore: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,120 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<script lang="tsx">
|
||||
import { renderless, api } from '@opentiny/vue-renderless/scrollbar/vue'
|
||||
import { $prefix, setup, h, defineComponent } from '@opentiny/vue-common'
|
||||
import scrollbarWidth from '@opentiny/vue-renderless/common/deps/scrollbar-width'
|
||||
import { toObject } from '@opentiny/vue-renderless/common/array'
|
||||
import Bar from './bar.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'Scrollbar',
|
||||
emits: ['mouseenter', 'mousemove', 'scroll'],
|
||||
components: {
|
||||
Bar
|
||||
},
|
||||
props: {
|
||||
marginBottomAdjust: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
native: Boolean,
|
||||
// 如果container尺寸不会发生变化,最好设置它可以优化性能
|
||||
noresize: Boolean,
|
||||
tag: {
|
||||
type: String,
|
||||
default: 'div'
|
||||
},
|
||||
viewClass: {},
|
||||
viewStyle: {},
|
||||
wrapClass: {},
|
||||
wrapStyle: {}
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
},
|
||||
render() {
|
||||
const {
|
||||
tag,
|
||||
vm: { $slots },
|
||||
native,
|
||||
wrapStyle,
|
||||
wrapClass,
|
||||
viewStyle,
|
||||
viewClass,
|
||||
handleScroll,
|
||||
state,
|
||||
marginBottomAdjust
|
||||
} = this
|
||||
const gutter = scrollbarWidth()
|
||||
let style = wrapStyle
|
||||
|
||||
if (gutter) {
|
||||
const gutterWith = `-${gutter}px`
|
||||
const gutterHeight = `-${gutter - marginBottomAdjust}px`
|
||||
const gutterStyle = `margin-bottom: ${gutterHeight}; margin-right: ${gutterWith};`
|
||||
|
||||
if (Array.isArray(wrapStyle)) {
|
||||
style = toObject(wrapStyle)
|
||||
style.marginRight = gutterWith
|
||||
style.marginBottom = gutterHeight
|
||||
} else if (typeof wrapStyle === 'string') {
|
||||
style += gutterStyle
|
||||
} else {
|
||||
style = gutterStyle
|
||||
}
|
||||
}
|
||||
|
||||
const view = h(
|
||||
tag,
|
||||
{
|
||||
class: ['tiny-scrollbar__view', viewClass],
|
||||
style: viewStyle,
|
||||
ref: 'resize'
|
||||
},
|
||||
$slots.default ? $slots.default() : $slots.empty && $slots.empty()
|
||||
)
|
||||
|
||||
const wrap = (
|
||||
<div ref="wrap" style={style} onScroll={handleScroll} class={[wrapClass, 'tiny-scrollbar__wrap', gutter ? '' : 'tiny-scrollbar__wrap--hidden-default']}>
|
||||
{[view]}
|
||||
</div>
|
||||
)
|
||||
|
||||
let nodes
|
||||
|
||||
if (native) {
|
||||
nodes = [
|
||||
<div ref="wrap" class={[wrapClass, 'tiny-scrollbar__wrap']} style={style}>
|
||||
{[view]}
|
||||
</div>
|
||||
]
|
||||
} else {
|
||||
nodes = [wrap, <Bar move={state.moveX} size={state.sizeWidth}></Bar>, <Bar vertical move={state.moveY} size={state.sizeHeight}></Bar>]
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
class="tiny-scrollbar"
|
||||
onMouseenter={(e) => {
|
||||
this.$emit('mouseenter', e)
|
||||
}}
|
||||
onMousemove={(e) => {
|
||||
this.$emit('mousemove', e)
|
||||
}}
|
||||
>
|
||||
{nodes}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,124 +0,0 @@
|
|||
<template>
|
||||
<div data-tag="tiny-select-mobile" v-show="visible">
|
||||
<tiny-action-sheet tiny_mode="mobile-first" :title="title" :visible="state.toggle" @update:visible="state.toggle = $event" @close="hide" :show-header="!state.search.show" show-footer :custom-class="[{ 'min-h-[95%]': state.search.show }]">
|
||||
<div v-show="!state.search.show" :class="['flex flex-col px-6']">
|
||||
<div v-if="multiple" :class="['flex items-start leading-[1.375rem] py-3 cursor-pointer select-none']" @click="allCheckHandler">
|
||||
<component v-if="multiple" :is="
|
||||
state.checkList.length === 0
|
||||
? 'icon-check'
|
||||
: state.checkList.length === menus.length
|
||||
? 'icon-checked-sur'
|
||||
: 'icon-halfselect'
|
||||
" :class="[
|
||||
'flex-none w-4 h-4 mt-0.5 mr-2',
|
||||
state.checkList.length ? 'fill-color-brand' : 'fill-color-icon-disabled'
|
||||
]" />
|
||||
<div :class="['flex-auto', { 'truncate': ellipsis }]">{{ t('ui.base.all') }}</div>
|
||||
</div>
|
||||
<tiny-option v-for="(item, index) in menus" :key="item[valueField]" :multiple="multiple" :ellipsis="ellipsis" :selected="multiple ? includeOptionIndex(state.checkList, item) > -1 : item[valueField] === modelValue" @click="selectOption(item, index)">
|
||||
{{ item[textField] }}
|
||||
</tiny-option>
|
||||
</div>
|
||||
<!-- search box -->
|
||||
<div :class="[state.search.show ? 'flex flex-col flex-auto' : 'hidden']">
|
||||
<!-- search header -->
|
||||
<div class="flex leading-6 pb-4 px-6 text-base items-center">
|
||||
<div class="flex-auto flex items-center h-7 py-1 px-3 bg-color-bg-4 rounded">
|
||||
<IconSearch class="h-4 w-4 mr-1 fill-color-icon-disabled"></IconSearch>
|
||||
<input v-model="state.search.input" class="h-5 flex-auto text-xs bg-transparent outline-0" placeholder="请搜索" @input="searchMethod" />
|
||||
</div>
|
||||
<div class="flex items-center pl-3 cursor-pointer">
|
||||
<div @click="searchBoxToggle(false)">取消</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- search body -->
|
||||
<div class="flex-auto overflow-auto">
|
||||
<div v-show="state.search.filterOptions.length" :class="['flex flex-col px-6']">
|
||||
<tiny-option v-for="(item, index) in state.search.filterOptions" :key="item[valueField]" :multiple="multiple" :ellipsis="ellipsis" :selected="multiple ? includeOptionIndex(state.checkList, item) > -1 : item[valueField] === modelValue" @click="searchSelectHandler(item, index)">
|
||||
{{ item[textField] }}
|
||||
</tiny-option>
|
||||
</div>
|
||||
<div v-show="!state.search.filterOptions.length" class="w-full flex justify-center items-center text-center">
|
||||
<div>
|
||||
<p>无相关搜索结果,请重新输入</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<template #header-left>
|
||||
<IconSearch class="h-5 w-5 cursor-pointer" @click="searchBoxToggle(true)"></IconSearch>
|
||||
</template>
|
||||
<template #footer>
|
||||
<tiny-button v-if="multiple" tiny_mode="mobile-first" class="flex-1" type="primary" :reset-time="0" @click="confirm">{{ t('ui.button.confirm') }}</tiny-button>
|
||||
>
|
||||
</template>
|
||||
</tiny-action-sheet>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { renderless, api } from '@opentiny/vue-renderless/select-mobile/vue'
|
||||
import { $prefix, setup, $props } from '@opentiny/vue-common'
|
||||
import { IconSearch, IconClose, IconHalfselect, IconCheckedSur, IconCheck } from '@opentiny/vue-icon'
|
||||
import Button from '@opentiny/vue-button'
|
||||
import ActionSheet from '@opentiny/vue-action-sheet'
|
||||
import Option from './option.vue'
|
||||
|
||||
export default {
|
||||
name: $prefix + 'SelectMobile',
|
||||
components: {
|
||||
TinyActionSheet: ActionSheet,
|
||||
TinyOption: Option,
|
||||
TinyButton: Button,
|
||||
IconCheck: IconCheck(),
|
||||
IconCheckedSur: IconCheckedSur(),
|
||||
IconHalfselect: IconHalfselect(),
|
||||
IconSearch: IconSearch(),
|
||||
IconClose: IconClose()
|
||||
},
|
||||
props: {
|
||||
...$props,
|
||||
menus: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
modelValue: [Number, String, Array],
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
ellipsis: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
valueField: {
|
||||
type: String,
|
||||
default: 'id'
|
||||
},
|
||||
textField: {
|
||||
type: String,
|
||||
default: 'label'
|
||||
},
|
||||
title: String,
|
||||
showHeader: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
showFooter: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
multiple: Boolean,
|
||||
searchConfig: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
options: [],
|
||||
searchMethod: null
|
||||
})
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,45 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<i :style="styleExternalIcon" class="tiny-svg" v-on="$listeners" />
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { $prefix, defineComponent } from '@opentiny/vue-common'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'SvgIcon',
|
||||
props: {
|
||||
src: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
width: String,
|
||||
height: String,
|
||||
fill: String
|
||||
},
|
||||
computed: {
|
||||
styleExternalIcon() {
|
||||
const style = {
|
||||
mask: `url(${this.src}) no-repeat 50% 50%`,
|
||||
'-webkit-mask': `url(${this.src}) no-repeat 50% 50%`
|
||||
}
|
||||
|
||||
this.width && (style.width = this.width)
|
||||
this.height && (style.height = this.height)
|
||||
this.fill && (style.background = this.fill)
|
||||
|
||||
return style
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,45 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<div
|
||||
v-if="!lazy || state.loaded || state.active"
|
||||
v-show="state.active"
|
||||
:aria-hidden="!state.active"
|
||||
:id="`pane-${state.paneName}`"
|
||||
:aria-labelledby="`tab-${state.paneName}`"
|
||||
:class="['tiny-tab-pane', state.animateShow ? 'active-item' : '']"
|
||||
role="tabpanel"
|
||||
>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
import { renderless, api } from '@opentiny/vue-renderless/tab-item/vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'TabItem',
|
||||
componentName: 'TabItem',
|
||||
props: {
|
||||
title: String,
|
||||
labelContent: Function,
|
||||
name: String,
|
||||
withClose: Boolean,
|
||||
disabled: Boolean,
|
||||
lazy: Boolean
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,45 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<component :is="$view" v-bind="$bind">
|
||||
<template>
|
||||
<slot></slot>
|
||||
</template>
|
||||
<template #icon="{ active }">
|
||||
<slot name="icon" :active="active"></slot>
|
||||
</template>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { $props, $prefix, $setup, defineComponent } from '@opentiny/vue-common'
|
||||
import template from 'virtual-template?mobile'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'TabbarItem',
|
||||
componentName: 'TinyTabbarItem',
|
||||
props: {
|
||||
...$props,
|
||||
url: String,
|
||||
replace: Boolean,
|
||||
to: [String, Object],
|
||||
dot: Boolean,
|
||||
icon: Object,
|
||||
name: [Number, String],
|
||||
info: [Number, String],
|
||||
badge: [Number, String]
|
||||
},
|
||||
setup(props, context) {
|
||||
return $setup({ props, context, template })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,53 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<div :class="{ 'tiny-mobile-tabbar-placeholder': placeholder }" :style="{ height: state.height }">
|
||||
<div class="tiny-mobile-tabbar" :class="[{ 'is-border': border }, { unfit: !state.fit, 'tiny-mobile-tabbar--fixed': fixed }]">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { setup, $prefix, defineComponent } from '@opentiny/vue-common'
|
||||
import { renderless, api } from '@opentiny/vue-renderless/tabbar/vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'Tabbar',
|
||||
props: {
|
||||
activeColor: String,
|
||||
border: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
fixed: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
inactiveColor: String,
|
||||
modelValue: {
|
||||
type: [Number, String],
|
||||
default: 0
|
||||
},
|
||||
placeholder: Boolean,
|
||||
route: Boolean,
|
||||
safeAreaInsetBottom: {
|
||||
type: Boolean,
|
||||
default: null
|
||||
},
|
||||
zIndex: [Number, String]
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,59 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<transition name="tiny-zoom-in-top" @before-enter="handleMenuEnter" @after-leave="emitDestroy">
|
||||
<div
|
||||
ref="popper"
|
||||
v-show="state.visible"
|
||||
:style="{ width: state.width + 'px' }"
|
||||
:class="state.popperClass"
|
||||
class="tiny-picker-panel tiny-time-select tiny-popper"
|
||||
>
|
||||
<tiny-scrollbar noresize wrap-class="tiny-picker-panel__content">
|
||||
<div
|
||||
class="tiny-time-select__item"
|
||||
v-for="item in state.items"
|
||||
:class="{
|
||||
selected: state.value === item.value,
|
||||
disabled: item.disabled,
|
||||
default: item.value === state.default
|
||||
}"
|
||||
:disabled="item.disabled"
|
||||
:key="item.value"
|
||||
@click="handleClick(item)"
|
||||
>
|
||||
{{ item.value }}
|
||||
</div>
|
||||
</tiny-scrollbar>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { renderless, api } from '@opentiny/vue-renderless/time-panel/vue'
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
import Scrollbar from '@opentiny/vue-scrollbar'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'TimePanel',
|
||||
emits: ['dodestroy', 'pick'],
|
||||
components: {
|
||||
TinyScrollbar: Scrollbar
|
||||
},
|
||||
props: {
|
||||
emitter: Object
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,11 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
|
@ -1,92 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
|
||||
<template>
|
||||
<transition name="tiny-zoom-in-top" @after-leave="$emit('dodestroy')">
|
||||
<div v-show="state.visible" class="tiny-time-range-picker tiny-picker-panel tiny-popper" :class="state.popperClass">
|
||||
<div class="tiny-time-range-picker__content">
|
||||
<div class="tiny-time-range-picker__cell">
|
||||
<div class="tiny-time-range-picker__header">
|
||||
{{ t('ui.datepicker.startTime') }}
|
||||
</div>
|
||||
<div
|
||||
:class="{
|
||||
'has-seconds': state.showSeconds,
|
||||
'is-arrow': state.arrowControl
|
||||
}"
|
||||
class="tiny-time-range-picker__body tiny-time-panel__content"
|
||||
>
|
||||
<time-spinner
|
||||
ref="minSpinner"
|
||||
:show-seconds="state.showSeconds"
|
||||
:am-pm-mode="state.amPmMode"
|
||||
@change="handleMinChange"
|
||||
:arrow-control="state.arrowControl"
|
||||
@select-range="setMinSelectionRange"
|
||||
:date="state.minDate"
|
||||
>
|
||||
</time-spinner>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tiny-time-range-picker__cell">
|
||||
<div class="tiny-time-range-picker__header">
|
||||
{{ t('ui.datepicker.endTime') }}
|
||||
</div>
|
||||
<div
|
||||
:class="{
|
||||
'has-seconds': state.showSeconds,
|
||||
'is-arrow': state.arrowControl
|
||||
}"
|
||||
class="tiny-time-range-picker__body tiny-time-panel__content"
|
||||
>
|
||||
<time-spinner
|
||||
ref="maxSpinner"
|
||||
:show-seconds="state.showSeconds"
|
||||
:am-pm-mode="state.amPmMode"
|
||||
@change="handleMaxChange"
|
||||
:arrow-control="state.arrowControl"
|
||||
@select-range="setMaxSelectionRange"
|
||||
:date="state.maxDate"
|
||||
>
|
||||
</time-spinner>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tiny-time-panel__footer">
|
||||
<button type="button" class="tiny-time-panel__btn cancel" @click="handleCancel()">
|
||||
{{ t('ui.datepicker.cancel') }}
|
||||
</button>
|
||||
<button type="button" class="tiny-time-panel__btn confirm" @click="handleConfirm()" :disabled="state.btnDisabled">
|
||||
{{ t('ui.datepicker.confirm') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { renderless, api } from '@opentiny/vue-renderless/time-range/vue'
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
import TimeSpinner from '@opentiny/vue-time-spinner'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'TimeRange',
|
||||
emits: ['dodestroy', 'pick', 'select-range'],
|
||||
components: { TimeSpinner },
|
||||
props: {
|
||||
emitter: Object
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,11 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
|
@ -1,177 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="tiny-time-spinner" :class="{ 'has-seconds': showSeconds }">
|
||||
<template v-if="!arrowControl">
|
||||
<tiny-scrollbar
|
||||
@mouseenter="emitSelectRange('hours')"
|
||||
@mousemove="adjustCurrentSpinner('hours')"
|
||||
:class="[state.animationName]"
|
||||
class="tiny-time-spinner__wrapper"
|
||||
wrap-style="max-height: inherit;"
|
||||
view-class="tiny-time-spinner__list"
|
||||
noresize
|
||||
tag="ul"
|
||||
ref="hours"
|
||||
>
|
||||
<li
|
||||
@click="handleClick('hours', { value: hour, disabled })"
|
||||
v-for="(disabled, hour) in state.hoursList"
|
||||
class="tiny-time-spinner__item"
|
||||
:key="hour"
|
||||
:class="{ active: hour === state.hours, disabled }"
|
||||
>
|
||||
<span>{{ ('0' + (amPmMode ? hour % 12 || 12 : hour)).slice(-2) }}{{ amPm(hour) }}</span>
|
||||
</li>
|
||||
</tiny-scrollbar>
|
||||
<tiny-scrollbar
|
||||
@mouseenter="emitSelectRange('minutes')"
|
||||
@mousemove="adjustCurrentSpinner('minutes')"
|
||||
:class="[state.animationName + '-up']"
|
||||
class="tiny-time-spinner__wrapper"
|
||||
wrap-style="max-height: inherit;"
|
||||
view-class="tiny-time-spinner__list"
|
||||
noresize
|
||||
tag="ul"
|
||||
ref="minutes"
|
||||
>
|
||||
<li
|
||||
@click="handleClick('minutes', { value: key, disabled: false })"
|
||||
v-for="(enabled, key) in state.minutesList"
|
||||
:key="key"
|
||||
class="tiny-time-spinner__item"
|
||||
:class="{ active: key === state.minutes, disabled: !enabled }"
|
||||
>
|
||||
<span>{{ ('0' + key).slice(-2) }}</span>
|
||||
</li>
|
||||
</tiny-scrollbar>
|
||||
<tiny-scrollbar
|
||||
v-show="showSeconds"
|
||||
@mouseenter="emitSelectRange('seconds')"
|
||||
@mousemove="adjustCurrentSpinner('seconds')"
|
||||
:class="[state.animationName]"
|
||||
class="tiny-time-spinner__wrapper"
|
||||
wrap-style="max-height: inherit;"
|
||||
view-class="tiny-time-spinner__list"
|
||||
noresize
|
||||
tag="ul"
|
||||
ref="seconds"
|
||||
>
|
||||
<li
|
||||
@click="handleClick('seconds', { value: key, disabled: false })"
|
||||
v-for="(second, key) in 60"
|
||||
class="tiny-time-spinner__item"
|
||||
:class="{ active: key === state.seconds }"
|
||||
:key="key"
|
||||
>
|
||||
<span>{{ ('0' + key).slice(-2) }}</span>
|
||||
</li>
|
||||
</tiny-scrollbar>
|
||||
</template>
|
||||
<template v-if="arrowControl">
|
||||
<div @mouseenter="emitSelectRange('hours')" class="tiny-time-spinner__wrapper is-arrow">
|
||||
<i class="tiny-time-spinner__arrow tiny-icon-arrow-up" v-repeat-click="decrease">
|
||||
<icon-chevron-up></icon-chevron-up>
|
||||
</i>
|
||||
<i class="tiny-time-spinner__arrow tiny-icon-arrow-down" v-repeat-click="increase">
|
||||
<icon-chevron-down></icon-chevron-down>
|
||||
</i>
|
||||
|
||||
<ul class="tiny-time-spinner__list" ref="hours" :class="[state.animationName]">
|
||||
<li
|
||||
class="tiny-time-spinner__item"
|
||||
:class="{
|
||||
active: hour === state.hours,
|
||||
disabled: state.hoursList[hour]
|
||||
}"
|
||||
v-for="(hour, key) in state.arrowHourList"
|
||||
:key="key"
|
||||
>
|
||||
<span>{{ hour === undefined ? '' : ('0' + (amPmMode ? hour % 12 || 12 : hour)).slice(-2) + amPm(hour) }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div @mouseenter="emitSelectRange('minutes')" class="tiny-time-spinner__wrapper is-arrow">
|
||||
<i class="tiny-time-spinner__arrow tiny-icon-arrow-up" v-repeat-click="decrease">
|
||||
<icon-chevron-up></icon-chevron-up>
|
||||
</i>
|
||||
<i class="tiny-time-spinner__arrow tiny-icon-arrow-down" v-repeat-click="increase">
|
||||
<icon-chevron-down></icon-chevron-down>
|
||||
</i>
|
||||
<ul class="tiny-time-spinner__list" ref="minutes" :class="[state.animationName + '-up']">
|
||||
<li class="tiny-time-spinner__item" :class="{ active: minute === state.minutes }" v-for="(minute, key) in state.arrowMinuteList" :key="key">
|
||||
<span>{{ minute === undefined ? '' : ('0' + minute).slice(-2) }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div @mouseenter="emitSelectRange('seconds')" class="tiny-time-spinner__wrapper is-arrow" v-if="showSeconds">
|
||||
<i class="tiny-time-spinner__arrow tiny-icon-arrow-up" v-repeat-click="decrease">
|
||||
<icon-chevron-up></icon-chevron-up>
|
||||
</i>
|
||||
<i class="tiny-time-spinner__arrow tiny-icon-arrow-down" v-repeat-click="increase">
|
||||
<icon-chevron-down></icon-chevron-down>
|
||||
</i>
|
||||
<ul class="tiny-time-spinner__list" ref="seconds" :class="[state.animationName]">
|
||||
<li v-for="(second, key) in state.arrowSecondList" class="tiny-time-spinner__item" :class="{ active: second === state.seconds }" :key="key">
|
||||
<span>{{ second === undefined ? '' : ('0' + second).slice(-2) }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { renderless, api } from '@opentiny/vue-renderless/time-spinner/vue'
|
||||
import { $prefix, setup, directive, defineComponent } from '@opentiny/vue-common'
|
||||
import Scrollbar from '@opentiny/vue-scrollbar'
|
||||
import bind from '@opentiny/vue-renderless/common/deps/repeat-click'
|
||||
import { iconChevronDown, iconChevronUp } from '@opentiny/vue-icon'
|
||||
|
||||
const $constants = {
|
||||
ANIMATIONNAME: 'tiny-transition-timepicker'
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'TimeSpinner',
|
||||
emits: ['change', 'select-range'],
|
||||
components: {
|
||||
TinyScrollbar: Scrollbar,
|
||||
IconChevronDown: iconChevronDown(),
|
||||
IconChevronUp: iconChevronUp()
|
||||
},
|
||||
directives: directive({
|
||||
repeatClick: { bind }
|
||||
}),
|
||||
props: {
|
||||
_constants: {
|
||||
type: Object,
|
||||
default: () => $constants
|
||||
},
|
||||
date: {},
|
||||
defaultValue: {},
|
||||
showSeconds: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
arrowControl: Boolean,
|
||||
amPmMode: {
|
||||
type: String,
|
||||
default: '' // 'a': am/pm; 'A': AM/PM
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,60 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<transition name="tiny-zoom-in-top" @after-leave="$emit('dodestroy')">
|
||||
<div v-show="state.visible" class="tiny-time-panel tiny-popper" :class="state.popperClass">
|
||||
<div class="tiny-time-panel__content" :class="{ 'has-seconds': state.showSeconds }">
|
||||
<time-spinner
|
||||
ref="spinner"
|
||||
@change="handleChange"
|
||||
:arrow-control="state.useArrow"
|
||||
:show-seconds="state.showSeconds"
|
||||
:am-pm-mode="state.amPmMode"
|
||||
@select-range="setSelectionRange"
|
||||
:date="state.date"
|
||||
>
|
||||
</time-spinner>
|
||||
</div>
|
||||
<div class="tiny-time-panel__footer">
|
||||
<button type="button" class="tiny-time-panel__btn cancel" @click="handleCancel">
|
||||
{{ t('ui.datepicker.cancel') }}
|
||||
</button>
|
||||
<button type="button" class="tiny-time-panel__btn" :class="{ confirm: !state.disabled }" @click="handleConfirm()">
|
||||
{{ t('ui.datepicker.confirm') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { renderless, api } from '@opentiny/vue-renderless/time/vue'
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
import TimeSpinner from '@opentiny/vue-time-spinner'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'Time',
|
||||
emits: ['dodestroy', 'pick', 'select-range'],
|
||||
components: {
|
||||
TimeSpinner
|
||||
},
|
||||
props: {
|
||||
show: Boolean,
|
||||
timeArrowControl: Boolean,
|
||||
emitter: Object,
|
||||
value: Date
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,232 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
|
||||
<script lang="tsx">
|
||||
import { renderless, api } from '@opentiny/vue-renderless/tooltip/vue'
|
||||
import { $prefix, setup, createComponent, parseVnode, h, defineComponent } from '@opentiny/vue-common'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'Tooltip',
|
||||
componentName: 'Tooltip',
|
||||
props: {
|
||||
visible: {
|
||||
type: String,
|
||||
default: () => 'always',
|
||||
validator: (value: string) => ['always', 'auto'].includes(value)
|
||||
},
|
||||
adjustArrow: {
|
||||
type: Boolean,
|
||||
default: () => false
|
||||
},
|
||||
appendToBody: {
|
||||
type: Boolean,
|
||||
default: () => true
|
||||
},
|
||||
arrowOffset: {
|
||||
type: Number,
|
||||
default: () => 0
|
||||
},
|
||||
boundariesPadding: {
|
||||
type: Number,
|
||||
default: () => 5
|
||||
},
|
||||
closeDelay: {
|
||||
type: Number,
|
||||
default: () => 300
|
||||
},
|
||||
content: { type: String },
|
||||
disabled: { type: Boolean },
|
||||
effect: {
|
||||
type: String,
|
||||
default: () => 'dark'
|
||||
},
|
||||
enterable: {
|
||||
type: Boolean,
|
||||
default: () => true
|
||||
},
|
||||
hideAfter: {
|
||||
type: Number,
|
||||
default: () => 0
|
||||
},
|
||||
manual: { type: Boolean },
|
||||
modelValue: { type: Boolean },
|
||||
offset: {
|
||||
default: () => 0
|
||||
},
|
||||
openDelay: {
|
||||
type: Number,
|
||||
default: () => 0
|
||||
},
|
||||
placement: {
|
||||
type: String,
|
||||
default: () => 'bottom'
|
||||
},
|
||||
popper: {},
|
||||
popperClass: { type: String },
|
||||
popperOptions: {
|
||||
default: () => ({ gpuAcceleration: false, boundariesPadding: 10 })
|
||||
},
|
||||
pre: { type: Boolean },
|
||||
reference: {},
|
||||
renderContent: { type: Function },
|
||||
tabindex: {
|
||||
type: Number,
|
||||
default: () => 0
|
||||
},
|
||||
transformOrigin: {
|
||||
type: [Boolean, String],
|
||||
default: () => true
|
||||
},
|
||||
transition: {
|
||||
type: String,
|
||||
default: () => 'tiny-fade-in-linear'
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
validator: (value: string) => Boolean(~['normal', 'warning', 'error', 'info', 'success'].indexOf(value))
|
||||
},
|
||||
visibleArrow: {
|
||||
type: Boolean,
|
||||
default: () => true
|
||||
},
|
||||
zIndex: {
|
||||
type: String,
|
||||
default: () => 'next'
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
},
|
||||
render() {
|
||||
const getContent = (vm) => {
|
||||
let slotContent = vm.slots.content && vm.slots.content()
|
||||
|
||||
if (slotContent) {
|
||||
return slotContent
|
||||
}
|
||||
|
||||
let attrContent
|
||||
|
||||
if (vm.renderContent) {
|
||||
attrContent = vm.renderContent(h, vm.content)
|
||||
} else if (vm.pre) {
|
||||
attrContent = vm.content ? h('pre', vm.content) : null
|
||||
} else {
|
||||
attrContent = vm.content
|
||||
}
|
||||
|
||||
return attrContent
|
||||
}
|
||||
|
||||
Object.prototype.hasOwnProperty.call(this, 'popperVM') ||
|
||||
this.d({
|
||||
popperVM: {
|
||||
get: () =>
|
||||
// 使用适配器里的createComponent创建一个新的vue的vnode节点为一个新组件,挂载到el下面去
|
||||
createComponent({
|
||||
el: document.createElement('div'),
|
||||
component: {
|
||||
render: () => {
|
||||
let content = getContent(this)
|
||||
let propsData = {
|
||||
attrs: { name: this.transition },
|
||||
on: { 'after-leave': this.doDestroy }
|
||||
}
|
||||
let typeClass = 'is-' + (this.type || this.effect)
|
||||
let mouseenter = () => this.setExpectedState(true)
|
||||
let mouseleave = () => {
|
||||
this.setExpectedState(false)
|
||||
this.debounceClose()
|
||||
}
|
||||
|
||||
this.$nextTick(() => this.updatePopper())
|
||||
|
||||
return h('transition', propsData, [
|
||||
<div
|
||||
ref="popper"
|
||||
id={this.state.tooltipId}
|
||||
v-show={!this.disabled && this.state.showPopper && content}
|
||||
appendToBody={this.appendToBody}
|
||||
class={['tiny-tooltip', 'tiny-tooltip__popper', typeClass, this.popperClass]}
|
||||
role="tooltip"
|
||||
aria-hidden={this.disabled || !this.state.showPopper ? 'true' : 'false'}
|
||||
onMouseenter={() => mouseenter()}
|
||||
onMouseleave={() => mouseleave()}>
|
||||
{content}
|
||||
</div>
|
||||
])
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const stringifyClassObj = (classObj) =>
|
||||
Object.keys(classObj)
|
||||
.filter((key) => classObj[key])
|
||||
.join(' ')
|
||||
|
||||
const stringifyClassArr = (classArr) =>
|
||||
classArr
|
||||
.filter((item) => item)
|
||||
.map((item) =>
|
||||
typeof item === 'string' ? item.trim() : typeof item === 'object' ? stringifyClassObj(item) : ''
|
||||
)
|
||||
.join(' ')
|
||||
|
||||
const addTooltipClass = (bindClass) => {
|
||||
let className = ''
|
||||
|
||||
if (bindClass) {
|
||||
if (typeof bindClass === 'string') {
|
||||
className = bindClass.trim()
|
||||
} else if (Array.isArray(bindClass)) {
|
||||
className = stringifyClassArr(bindClass)
|
||||
} else if (typeof bindClass === 'object') {
|
||||
className = stringifyClassObj(bindClass)
|
||||
}
|
||||
}
|
||||
|
||||
return 'tiny-tooltip ' + className.replace(/\btiny-tooltip\b/g, '').trim()
|
||||
}
|
||||
|
||||
// 查找默认的slots, 并把它渲染到组件所在位置上。
|
||||
const getFirstElement = () => {
|
||||
const slots = this.slots.default && this.slots.default()
|
||||
|
||||
if (!Array.isArray(slots)) return null
|
||||
|
||||
let element = null
|
||||
|
||||
for (let index = 0; index < slots.length; index++) {
|
||||
const vnode = parseVnode(slots[index])
|
||||
|
||||
if (vnode && vnode.type) {
|
||||
element = vnode
|
||||
}
|
||||
}
|
||||
|
||||
return element
|
||||
}
|
||||
|
||||
const firstElement = getFirstElement()
|
||||
|
||||
if (!firstElement) return null
|
||||
|
||||
const data = firstElement.data || firstElement.props || (firstElement.props = {})
|
||||
|
||||
data.class = addTooltipClass(data.class)
|
||||
|
||||
return firstElement
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,173 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="tiny-transfer-panel" :class="[state.renderType === 'TinyTable' ? 'transferGrid' : '']">
|
||||
<p class="tiny-transfer-panel__header">
|
||||
<tiny-checkbox v-model="state.allChecked" @change="handleAllCheckedChange" :indeterminate="state.isIndeterminate">
|
||||
{{ title }}
|
||||
<div class="headSort" v-if="render && state.renderType !== 'TinyTable' && data.flag === 'sort'">
|
||||
<div class="sort-btn disabled up" @click="setPosition('up', $event)">
|
||||
<icon-arrow-up fill="#1890ff"></icon-arrow-up>
|
||||
</div>
|
||||
<div class="sort-btn disabled down" @click="setPosition('down', $event)">
|
||||
<icon-arrow-down fill="#1890ff"></icon-arrow-down>
|
||||
</div>
|
||||
</div>
|
||||
<span>{{ state.checkedSummary }}</span>
|
||||
</tiny-checkbox>
|
||||
</p>
|
||||
<div :class="['tiny-transfer-panel__body', state.hasFooter ? 'is-with-footer' : '']" ref="reference">
|
||||
<tiny-input
|
||||
class="tiny-transfer-panel__filter"
|
||||
v-model="state.query"
|
||||
size="small"
|
||||
:placeholder="placeholder"
|
||||
@mouseenter="state.inputHover = true"
|
||||
@mouseleave="state.inputHover = false"
|
||||
v-if="filterable"
|
||||
>
|
||||
<template #prefix>
|
||||
<i :class="['tiny-input__icon', 'tiny-icon-' + state.inputIcon]" @click="clearQuery"></i>
|
||||
</template>
|
||||
</tiny-input>
|
||||
<transition-group
|
||||
name="tiny-transition-transfer-fade"
|
||||
tag="div"
|
||||
v-show="!render"
|
||||
role="group"
|
||||
aria-label="checkbox-group"
|
||||
class="tiny-checkbox-group tiny-transfer-panel__list"
|
||||
:class="{ 'is-filterable': filterable }"
|
||||
>
|
||||
<label
|
||||
class="tiny-checkbox tiny-transfer-panel__item"
|
||||
:class="[
|
||||
item[state.disabledProp] ? 'is-disabled' : '',
|
||||
state.checked.length > 0 && state.checked.indexOf(item[state.keyProp]) > -1 ? 'is-checked' : ''
|
||||
]"
|
||||
@click.stop.prevent="checkedEvent(item[state.keyProp], item[state.disabledProp])"
|
||||
:key="item[state.keyProp]"
|
||||
v-for="item in state.filteredData"
|
||||
>
|
||||
<span
|
||||
class="tiny-checkbox__input"
|
||||
:class="[
|
||||
item[state.disabledProp] ? 'is-disabled' : '',
|
||||
state.checked.length > 0 && state.checked.indexOf(item[state.keyProp]) > -1 ? 'is-checked' : ''
|
||||
]"
|
||||
>
|
||||
<span class="tiny-checkbox__inner">
|
||||
<icon-check v-if="!(state.checked.length > 0 && state.checked.indexOf(item[state.keyProp]) > -1)" class="tiny-svg-size" />
|
||||
<icon-checked-sur v-else class="tiny-svg-size" />
|
||||
</span>
|
||||
<input type="checkbox" aria-hidden="false" :disabled="item[state.disabledProp]" class="tiny-checkbox__original" :value="item[state.keyProp]" />
|
||||
</span>
|
||||
<span class="tiny-checkbox__label">
|
||||
<option-content :option="optionRender(item)"></option-content>
|
||||
</span>
|
||||
</label>
|
||||
</transition-group>
|
||||
<component ref="plugin" v-if="render && render.plugin" :is="markRaw(toRaw(render.plugin))" v-bind="state.render" v-on="state.render.on"></component>
|
||||
<tiny-pager
|
||||
v-show="showPager && state.renderType === 'TinyTable'"
|
||||
@size-change="sizesChange"
|
||||
ref="pager"
|
||||
:total="state.pagerTotal.length"
|
||||
:current-page="state.currentPage"
|
||||
@update:current-page="state.currentPage = $event"
|
||||
:page-size="pagerOp.pageVO.pageSize"
|
||||
:layout="pagerOp.pageVO.layout"
|
||||
:page-sizes="pagerOp.pageVO.pageSizes"
|
||||
:mode="pagerOp.mode"
|
||||
:pager-count="pagerOp.pagerCount"
|
||||
@current-change="handlePageChange"
|
||||
>
|
||||
</tiny-pager>
|
||||
|
||||
<p class="tiny-transfer-panel__empty" v-show="!render && state.hasNoMatch">
|
||||
{{ t('ui.transfer.noMatch') }}
|
||||
</p>
|
||||
<p class="tiny-transfer-panel__empty" v-show="!render && data.length === 0 && !state.hasNoMatch">
|
||||
{{ t('ui.transfer.noData') }}
|
||||
</p>
|
||||
</div>
|
||||
<p class="tiny-transfer-panel__footer" v-if="$parent.slots['left-footer'] || $parent.slots['right-footer']">
|
||||
<slot></slot>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
import { renderless, api } from '@opentiny/vue-renderless/transfer-panel/vue'
|
||||
import Checkbox from '@opentiny/vue-checkbox'
|
||||
import Input from '@opentiny/vue-input'
|
||||
import Pager from '@opentiny/vue-pager'
|
||||
import { iconArrowUp, iconArrowDown, iconCheckedSur, iconCheck } from '@opentiny/vue-icon'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'TransferPanel',
|
||||
componentName: 'TransferPanel',
|
||||
inheritAttrs: false,
|
||||
components: {
|
||||
TinyCheckbox: Checkbox,
|
||||
TinyInput: Input,
|
||||
TinyPager: Pager,
|
||||
IconArrowDown: iconArrowDown(),
|
||||
IconArrowUp: iconArrowUp(),
|
||||
IconCheckedSur: iconCheckedSur(),
|
||||
IconCheck: iconCheck(),
|
||||
OptionContent: {
|
||||
props: {
|
||||
option: [Object, Array]
|
||||
},
|
||||
render() {
|
||||
return this.option
|
||||
}
|
||||
}
|
||||
},
|
||||
props: {
|
||||
columns: Array,
|
||||
data: {
|
||||
type: Array,
|
||||
default() {
|
||||
return []
|
||||
}
|
||||
},
|
||||
defaultChecked: Array,
|
||||
filterMethod: Function,
|
||||
filterable: Boolean,
|
||||
format: Object,
|
||||
isToLeft: Boolean,
|
||||
optionRender: Function,
|
||||
pagerOp: Object,
|
||||
placeholder: String,
|
||||
props: Object,
|
||||
render: Object,
|
||||
renderContent: Function,
|
||||
showLeft: Boolean,
|
||||
showPager: Boolean,
|
||||
title: String,
|
||||
treeOp: Object,
|
||||
value: {
|
||||
type: Array,
|
||||
default() {
|
||||
return []
|
||||
}
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,148 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="tiny-tree-menu">
|
||||
<tiny-input v-model="state.filterText" v-if="showFilter" :placeholder="t('ui.treeMenu.placeholder')" :prefix-icon="searchIcon" />
|
||||
<tiny-tree
|
||||
ref="tree"
|
||||
:class="{
|
||||
'tiny-tree-menu__wrap': !ellipsis ? wrap : false,
|
||||
'tiny-tree-menu__overflow': ellipsis
|
||||
}"
|
||||
tiny_mode="pc"
|
||||
:accordion="accordion"
|
||||
:data="state.data"
|
||||
:node-key="nodeKey"
|
||||
:empty-text="emptyText"
|
||||
:filter-node-method="filterNodeMethod || filterNode"
|
||||
:draggable="draggable"
|
||||
:default-expand-all="defaultExpandAll"
|
||||
:check-strictly="checkStrictly"
|
||||
:lazy="lazy"
|
||||
:load="load"
|
||||
:show-checkbox="showCheckbox"
|
||||
:indent="indent"
|
||||
:default-checked-keys="defaultCheckedKeys"
|
||||
:default-expanded-keys="defaultExpandedKeys"
|
||||
:default-expanded-keys-highlight="defaultExpandedKeysHighlight"
|
||||
:allow-drag="allowDrag"
|
||||
:props="props"
|
||||
:allow-drop="allowDrop"
|
||||
:expand-on-click-node="expandOnClickNode"
|
||||
@node-drag-start="nodeDragStart"
|
||||
@node-drag-enter="nodeDragEnter"
|
||||
@node-drag-over="nodeDragOver"
|
||||
@node-drag-end="nodeDragEnd"
|
||||
@node-drop="nodeDrop"
|
||||
@node-expand="nodeExpand"
|
||||
@node-collapse="nodeCollapse"
|
||||
@node-click="nodeClick"
|
||||
@check-change="checkChange"
|
||||
@check="check"
|
||||
@current-change="currentChange"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<div class="tree-node">
|
||||
<div class="tree-menus-link tiny-tree-node__label">
|
||||
<a class="tree-node-body" :title="getTitle(data.label)" :href="data.url || void 0">
|
||||
<span class="tree-node-name">
|
||||
<component v-if="prefixIcon" :is="prefixIcon"></component>
|
||||
<slot :node="node" :data="data" :label="data.label">
|
||||
{{ data.label || node.label }}
|
||||
</slot>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</tiny-tree>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
import { renderless, api } from '@opentiny/vue-renderless/tree-menu/vue'
|
||||
import Tree from '@opentiny/vue-tree'
|
||||
import Input from '@opentiny/vue-input'
|
||||
import { iconSearch } from '@opentiny/vue-icon'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'TreeMenu',
|
||||
components: {
|
||||
TinyTree: Tree,
|
||||
TinyInput: Input
|
||||
},
|
||||
props: {
|
||||
data: Array,
|
||||
nodeKey: String,
|
||||
defaultExpandAll: Boolean,
|
||||
suffixIcon: Object,
|
||||
prefixIcon: Object,
|
||||
searchIcon: {
|
||||
type: Object,
|
||||
default: () => iconSearch()
|
||||
},
|
||||
props: Object,
|
||||
draggable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
emptyText: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
checkStrictly: Boolean,
|
||||
lazy: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
load: Function,
|
||||
showCheckbox: Boolean,
|
||||
filterNodeMethod: Function,
|
||||
defaultCheckedKeys: Array,
|
||||
defaultExpandedKeys: Array,
|
||||
defaultExpandedKeysHighlight: [Number, String],
|
||||
indent: {
|
||||
type: Number,
|
||||
default: 16
|
||||
},
|
||||
allowDrag: Function,
|
||||
allowDrop: Function,
|
||||
expandOnClickNode: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
ellipsis: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
wrap: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
getMenuDataSync: Function,
|
||||
accordion: Boolean,
|
||||
showTitle: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
showFilter: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,38 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="tiny-upload-dragger"
|
||||
:class="{ 'is-dragover': state.dragover }"
|
||||
@drop.prevent="onDrop"
|
||||
@dragover.prevent="onDragOver"
|
||||
@dragleave.prevent="state.dragover = false"
|
||||
>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
import { renderless, api } from '@opentiny/vue-renderless/upload-dragger/vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'UploadDragger',
|
||||
props: {
|
||||
disabled: Boolean
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,236 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div :class="['tiny-mobile-upload-list', 'tiny-mobile-upload-list--' + listType, { 'is-disabled': disabled }]" v-if="state.screenType">
|
||||
<transition-group tag="ul" name="tiny-list">
|
||||
<li
|
||||
v-for="(file, index) in files"
|
||||
:class="['tiny-mobile-upload-list__item', 'is-' + file.status, state.focusing ? 'focusing' : '']"
|
||||
:key="file.uid"
|
||||
tabindex="0"
|
||||
@keydown.delete="!disabled && $emit('remove', file)"
|
||||
@click="picturefilePreview(index)"
|
||||
>
|
||||
<slot :file="file">
|
||||
<div class="tiny-mobile-upload-list__card" v-if="['picture-card'].indexOf(listType) > -1">
|
||||
<img
|
||||
class="tiny-mobile-upload-list__item-thumbnail"
|
||||
v-if="file.status !== 'uploading' && ['picture-card'].indexOf(listType) > -1"
|
||||
:src="file.url"
|
||||
alt=""
|
||||
/>
|
||||
<icon-error class="icon-close card-close" v-if="listType === 'picture-card' && display" @click.stop="$emit('remove', file)"></icon-error>
|
||||
<Progress v-if="file.status === 'uploading'" type="circle" :percentage="parsePercentage(file.percentage)" :stroke-width="1.4" :width="32">
|
||||
</Progress>
|
||||
</div>
|
||||
<div class="tiny-mobile-upload-list__list" v-else>
|
||||
<div class="file-type">
|
||||
<icon-attachment v-if="filesIcon.length === 0" />
|
||||
<template v-for="(item, index) in filesIcon">
|
||||
<img
|
||||
:class="['file-type-icon', 'is-' + item.type]"
|
||||
:key="index"
|
||||
:src="item.url"
|
||||
v-if="filesIcon && state.screenType && file.fileType === item.type"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
<div class="tiny-mobile-upload-list__text file-content" @click="handleClick(file)">
|
||||
<p class="tiny-mobile-upload-list__text-details file-name">
|
||||
{{ file.name }}
|
||||
</p>
|
||||
<p class="tiny-mobile-upload-list__text-details file-size">
|
||||
{{ file.size }}
|
||||
</p>
|
||||
<Progress v-if="file.status === 'uploading'" :show-text="false" :stroke-width="2" :percentage="parsePercentage(file.percentage)"> </Progress>
|
||||
</div>
|
||||
<div class="file-delete">
|
||||
<icon-close-circle class="icon-close" v-if="listType !== 'picture-card' && display" @click="$emit('remove', file)"></icon-close-circle>
|
||||
</div>
|
||||
</div>
|
||||
</slot>
|
||||
</li>
|
||||
</transition-group>
|
||||
<tiny-image-viewer
|
||||
v-if="listType === 'picture-card'"
|
||||
:url-list="srcList"
|
||||
:close-show="true"
|
||||
:show-index="true"
|
||||
:startPosition="state.startPostion"
|
||||
tool-show
|
||||
@update:preview-visible="state.shows = $event"
|
||||
delete-button
|
||||
@newImageList="getDeleteData"
|
||||
></tiny-image-viewer>
|
||||
</div>
|
||||
<transition-group tag="ul" v-else :class="['tiny-upload-list', 'tiny-upload-list--' + listType, { 'is-disabled': disabled }]" name="tiny-list">
|
||||
<li
|
||||
v-for="file in files"
|
||||
:key="file.uid"
|
||||
:class="['tiny-upload-list__item', 'is-' + file.status, state.focusing ? 'focusing' : '', { isEdm }]"
|
||||
tabindex="0"
|
||||
@keydown.delete="!disabled && $emit('remove', file)"
|
||||
@focus="state.focusing = true"
|
||||
@blur="state.focusing = false"
|
||||
@click="state.focusing = false"
|
||||
>
|
||||
<slot :file="file">
|
||||
<img
|
||||
class="tiny-upload-list__item-thumbnail"
|
||||
v-if="file.status !== 'uploading' && ['picture-card', 'picture'].indexOf(listType) > -1"
|
||||
:src="file.url"
|
||||
alt=""
|
||||
/>
|
||||
<a
|
||||
:class="['tiny-upload-list__item-name', { isFail: isEdm && file.status === 'fail' }]"
|
||||
@click="handleClick(file)"
|
||||
:title="isFolderTitle ? (file.path || '') + file.name : file.name"
|
||||
>
|
||||
<icon-attachment v-if="!isFolder" :fill="isEdm && file.status === 'fail' ? '#f5222d' : ''" class="tiny-svg-size" />{{ file.name }}
|
||||
</a>
|
||||
<div :class="['tiny-upload-list__item-edminfo', { isFail: isEdm && file.status === 'fail' }]" v-if="isEdm">
|
||||
<span>{{ file.docId }}</span>
|
||||
|
||||
<span>{{ file.version }}</span>
|
||||
<span>{{ file.size }}</span>
|
||||
<span>{{ file.serverName }}</span>
|
||||
</div>
|
||||
<label class="tiny-upload-list__item-status-label">
|
||||
<icon-successful class="tiny-svg-size icon-successful" v-if="listType === 'text'" />
|
||||
<icon-yes class="tiny-svg-size tiny-icon-check" v-if="['picture-card', 'picture'].indexOf(listType) > -1" />
|
||||
</label>
|
||||
<span v-if="isEdm && !isFolder && !disabled && file.status !== 'fail'" :title="t('ui.fileUpload.updateFile')" @click="$emit('update', file)">
|
||||
<icon-file-cloudupload class="tiny-svg-size icon-refres" :fill="isEdm && file.status === 'fail' ? '#f5222d' : ''"></icon-file-cloudupload>
|
||||
</span>
|
||||
<span v-if="!disabled" :title="t('ui.fileUpload.deleteFile')" @click="$emit('remove', file)">
|
||||
<icon-close class="tiny-svg-size icon-close" :fill="isEdm && file.status === 'fail' ? '#f5222d' : ''"></icon-close>
|
||||
</span>
|
||||
<i class="tiny-icon-close-tip" v-if="!disabled"> {{ t('ui.fileUpload.deleteTip') }}</i>
|
||||
<Progress
|
||||
v-if="file.status === 'uploading' || file.status === 'downloading'"
|
||||
:type="listType === 'picture-card' ? 'circle' : 'line'"
|
||||
:stroke-width="listType === 'picture-card' ? 6 : 2"
|
||||
:percentage="parsePercentage(file.percentage)"
|
||||
>
|
||||
</Progress>
|
||||
<span class="tiny-upload-list__item-actions" v-if="listType === 'picture-card'">
|
||||
<span v-if="openDownloadFile" class="tiny-upload-list__item-download" :title="t('ui.fileUpload.downloadFile')" @click="handleClick(file)">
|
||||
<icon-download class="tiny-svg-size" />
|
||||
</span>
|
||||
<span class="tiny-upload-list__item-preview" v-if="handlePreview" :title="t('ui.fileUpload.previewFile')" @click="handlePreview(file)">
|
||||
<icon-view class="tiny-svg-size" />
|
||||
</span>
|
||||
<span
|
||||
v-if="isEdm && !isFolder && !disabled"
|
||||
:title="t('ui.fileUpload.updateFile')"
|
||||
class="tiny-upload-list__item-refres"
|
||||
@click="$emit('update', file)"
|
||||
>
|
||||
<icon-file-cloudupload class="tiny-svg-size" />
|
||||
</span>
|
||||
<span v-if="!disabled" class="tiny-upload-list__item-delete" :title="t('ui.fileUpload.deleteFile')" @click="$emit('remove', file)">
|
||||
<icon-del class="tiny-svg-size" />
|
||||
</span>
|
||||
</span>
|
||||
</slot>
|
||||
</li>
|
||||
</transition-group>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
import { renderless, api } from '@opentiny/vue-renderless/upload-list/vue'
|
||||
import Progress from '@opentiny/vue-progress'
|
||||
import ImageViewer from '@opentiny/vue-image-viewer'
|
||||
import {
|
||||
iconAttachment,
|
||||
iconSuccessful,
|
||||
iconClose,
|
||||
iconView,
|
||||
iconDel,
|
||||
iconYes,
|
||||
iconCloseCircle,
|
||||
iconError,
|
||||
iconFileCloudupload,
|
||||
iconDownload
|
||||
} from '@opentiny/vue-icon'
|
||||
import Modal from '@opentiny/vue-modal'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'UploadList',
|
||||
components: {
|
||||
Progress,
|
||||
TinyImageViewer: ImageViewer,
|
||||
IconAttachment: iconAttachment(),
|
||||
IconSuccessful: iconSuccessful(),
|
||||
IconClose: iconClose(),
|
||||
IconView: iconView(),
|
||||
IconDel: iconDel(),
|
||||
IconYes: iconYes(),
|
||||
IconCloseCircle: iconCloseCircle(),
|
||||
IconError: iconError(),
|
||||
IconFileCloudupload: iconFileCloudupload(),
|
||||
IconDownload: iconDownload()
|
||||
},
|
||||
props: {
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: () => false
|
||||
},
|
||||
display: {
|
||||
type: Boolean,
|
||||
default: () => true
|
||||
},
|
||||
files: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
filesIcon: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
handlePreview: Function,
|
||||
isEdm: {
|
||||
type: Boolean,
|
||||
default: () => false
|
||||
},
|
||||
isFolder: {
|
||||
type: Boolean,
|
||||
default: () => false
|
||||
},
|
||||
listType: String,
|
||||
openDownloadFile: {
|
||||
type: Boolean,
|
||||
default: () => false
|
||||
},
|
||||
srcList: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
isFolderTitle: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({
|
||||
props,
|
||||
context,
|
||||
renderless,
|
||||
api,
|
||||
mono: true,
|
||||
extendOptions: { Modal }
|
||||
})
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,139 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
|
||||
<script lang="tsx">
|
||||
import { $prefix, setup, h, defineComponent } from '@opentiny/vue-common' // 此处引入 h 是为了防止打包后 h 被重命名导致组件报错的问题
|
||||
import { renderless, api } from '@opentiny/vue-renderless/upload/vue'
|
||||
import UploadDragger from '@opentiny/vue-upload-dragger'
|
||||
import uploadAjax from '@opentiny/vue-renderless/common/deps/upload-ajax'
|
||||
import Modal from '@opentiny/vue-modal'
|
||||
|
||||
export default defineComponent({
|
||||
inheritAttrs: false,
|
||||
name: $prefix + 'Upload',
|
||||
props: {
|
||||
accept: String,
|
||||
action: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
autoUpload: Boolean,
|
||||
beforeUpload: Function,
|
||||
data: Object,
|
||||
disabled: Boolean,
|
||||
drag: Boolean,
|
||||
edmToken: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
fileList: Array,
|
||||
headers: Object,
|
||||
httpRequest: {
|
||||
type: Function,
|
||||
default: uploadAjax
|
||||
},
|
||||
isFolder: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
limit: Number,
|
||||
listType: String,
|
||||
multiple: Boolean,
|
||||
name: {
|
||||
type: String,
|
||||
default: 'file'
|
||||
},
|
||||
onError: Function,
|
||||
onExceed: Function,
|
||||
onPreview: {
|
||||
type: Function,
|
||||
default: () => {}
|
||||
},
|
||||
onProgress: Function,
|
||||
onRemove: {
|
||||
type: Function,
|
||||
default: () => {}
|
||||
},
|
||||
onStart: Function,
|
||||
onSuccess: Function,
|
||||
size: String,
|
||||
type: String,
|
||||
withCredentials: Boolean,
|
||||
isHidden: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({
|
||||
props,
|
||||
context,
|
||||
renderless,
|
||||
api,
|
||||
mono: true,
|
||||
h,
|
||||
extendOptions: { Modal }
|
||||
})
|
||||
},
|
||||
render() {
|
||||
let {
|
||||
accept,
|
||||
disabled,
|
||||
drag,
|
||||
handleChange,
|
||||
handleClick,
|
||||
handleKeydown,
|
||||
isFolder,
|
||||
listType,
|
||||
multiple,
|
||||
name,
|
||||
uploadFiles,
|
||||
fileList,
|
||||
limit,
|
||||
isHidden
|
||||
} = this
|
||||
|
||||
const defaultSlot = (this.slots.default && this.slots.default()) || []
|
||||
|
||||
const hidden = isHidden && fileList.length >= limit
|
||||
|
||||
return (
|
||||
<div
|
||||
class={['tiny-upload', `tiny-upload--${listType}`, disabled ? 'is-disabled' : '', hidden ? 'is-hidden' : '']}
|
||||
onClick={handleClick}
|
||||
onKeydown={handleKeydown}
|
||||
tabindex="0"
|
||||
>
|
||||
{drag
|
||||
? (
|
||||
<UploadDragger disabled={disabled} onFile={uploadFiles}>
|
||||
{defaultSlot}
|
||||
</UploadDragger>
|
||||
)
|
||||
: (
|
||||
defaultSlot
|
||||
)}
|
||||
<input
|
||||
class="tiny-upload__input"
|
||||
type="file"
|
||||
webkitdirectory={isFolder}
|
||||
ref="input"
|
||||
name={name}
|
||||
onChange={handleChange}
|
||||
multiple={isFolder ? true : multiple}
|
||||
accept={accept}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,74 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<div class="tiny-mobile-wheel">
|
||||
<div class="tiny-mobile-wheel__container">
|
||||
<transition name="picker-move">
|
||||
<div class="tiny-mobile-wheel__picker__panel" @click.stop>
|
||||
<div class="tiny-mobile-wheel__picker__content">
|
||||
<div class="tiny-mobile-wheel__wheel__wrapper" ref="wheelWrapper">
|
||||
<div class="wheel" v-for="(data, index) in state.pickerData" :key="index">
|
||||
<ul class="wheel__scroll_hasFooter" v-if="hasFooter">
|
||||
<li v-for="item in data" :key="item.label" :class="[item.selected ? 'wheel__item__selected' : '', 'wheel__item']">{{ item.label }}</li>
|
||||
</ul>
|
||||
<ul class="wheel__scroll_noFooter" v-else>
|
||||
<li
|
||||
v-for="(item, index) in data"
|
||||
:key="item.label"
|
||||
:class="[item.selected ? 'wheel__item__selected' : '', 'wheel__item']"
|
||||
@click="clickWheelItem(index)"
|
||||
>
|
||||
{{ item.label }}
|
||||
<IconYes class="size20" v-if="item.selected"></IconYes>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
import { renderless, api } from '@opentiny/vue-renderless/wheel/vue'
|
||||
import { IconYes } from '@opentiny/vue-icon'
|
||||
import BScroll from '@better-scroll/core'
|
||||
import Wheel from '@better-scroll/wheel'
|
||||
BScroll.use(Wheel)
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'Wheel',
|
||||
components: {
|
||||
IconYes: IconYes()
|
||||
},
|
||||
props: {
|
||||
dataSource: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
defaultSelectedIndexs: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
hasFooter: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true, extendOptions: { BScroll } })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,81 +0,0 @@
|
|||
<!--
|
||||
* Copyright (c) 2022 - present TinyVue Authors.
|
||||
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
-->
|
||||
|
||||
<template>
|
||||
<table @click="handleYearTableClick" class="tiny-year-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="available" :class="getCellStyle(state.startYear + 0)">
|
||||
<a class="cell">{{ state.startYear }}</a>
|
||||
</td>
|
||||
<td class="available" :class="getCellStyle(state.startYear + 1)">
|
||||
<a class="cell">{{ state.startYear + 1 }}</a>
|
||||
</td>
|
||||
<td class="available" :class="getCellStyle(state.startYear + 2)">
|
||||
<a class="cell">{{ state.startYear + 2 }}</a>
|
||||
</td>
|
||||
<td class="available" :class="getCellStyle(state.startYear + 3)">
|
||||
<a class="cell">{{ state.startYear + 3 }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="available" :class="getCellStyle(state.startYear + 4)">
|
||||
<a class="cell">{{ state.startYear + 4 }}</a>
|
||||
</td>
|
||||
<td class="available" :class="getCellStyle(state.startYear + 5)">
|
||||
<a class="cell">{{ state.startYear + 5 }}</a>
|
||||
</td>
|
||||
<td class="available" :class="getCellStyle(state.startYear + 6)">
|
||||
<a class="cell">{{ state.startYear + 6 }}</a>
|
||||
</td>
|
||||
<td class="available" :class="getCellStyle(state.startYear + 7)">
|
||||
<a class="cell">{{ state.startYear + 7 }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="available" :class="getCellStyle(state.startYear + 8)">
|
||||
<a class="cell">{{ state.startYear + 8 }}</a>
|
||||
</td>
|
||||
<td class="available" :class="getCellStyle(state.startYear + 9)">
|
||||
<a class="cell">{{ state.startYear + 9 }}</a>
|
||||
</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<script lang="tsx">
|
||||
import { renderless, api } from '@opentiny/vue-renderless/year-table/vue'
|
||||
import { isDate } from '@opentiny/vue-renderless/common/deps/date-util'
|
||||
import { $prefix, setup, defineComponent } from '@opentiny/vue-common'
|
||||
|
||||
export default defineComponent({
|
||||
name: $prefix + 'YearTable',
|
||||
emits: ['pick'],
|
||||
props: {
|
||||
disabledDate: {},
|
||||
value: {},
|
||||
defaultValue: {
|
||||
validator(val) {
|
||||
// null or valid Date Object
|
||||
return val === null || (val instanceof Date && isDate(val))
|
||||
}
|
||||
},
|
||||
date: {}
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api, mono: true })
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,64 +0,0 @@
|
|||
diff --git a/dist/index.d.ts b/dist/index.d.ts
|
||||
index db9f95e0c23a27b1991782e5e1b824e4224ba2f8..1027527a0b49d55e57f95a52f0183ac691eb25b0 100644
|
||||
--- a/dist/index.d.ts
|
||||
+++ b/dist/index.d.ts
|
||||
@@ -1,6 +1,9 @@
|
||||
interface ImportOption {
|
||||
- [key: string]: any;
|
||||
libraryName: string;
|
||||
+ style?: string | boolean | ((name: string, file?: any) => string);
|
||||
+ styleLibraryDirectory?: string;
|
||||
+ customName?: (name: string, file: any) => string;
|
||||
+ customStyleName?: (name: string) => string;
|
||||
libraryDirectory?: string;
|
||||
camel2DashComponentName?: boolean;
|
||||
}
|
||||
diff --git a/dist/index.js b/dist/index.js
|
||||
index 8f41efa9facb84ec8f8c437cd09de1b0d34e664a..468456172970fc6224e1c367b9cd1d95b0c5546e 100644
|
||||
--- a/dist/index.js
|
||||
+++ b/dist/index.js
|
||||
@@ -37,8 +37,9 @@ var import_acorn2 = require("acorn");
|
||||
var import_magic_string = __toESM(require("magic-string"));
|
||||
|
||||
// src/format.ts
|
||||
-var import_lodash = __toESM(require("lodash"));
|
||||
-var kebabCase = import_lodash.default.kebabCase;
|
||||
+var import_param_case = __toESM(require("param-case"));
|
||||
+var kebabCase = import_param_case.paramCase;
|
||||
+
|
||||
function formatedComponentName(libraryName, componentName, option) {
|
||||
const {
|
||||
libraryDirectory = "lib",
|
||||
@@ -316,7 +317,7 @@ function dynamicImportPlugin(options) {
|
||||
throw new Error("Options must be array.");
|
||||
}
|
||||
const ext = import_path.default.extname(id).slice(1);
|
||||
- if (["js", "jsx", "ts", "tsx"].indexOf(ext) > -1) {
|
||||
+ if (["js", "jsx", "ts", "tsx", "vue"].indexOf(ext) > -1) {
|
||||
code = await transform_default(code, importOptions);
|
||||
}
|
||||
return code;
|
||||
diff --git a/dist/index.mjs b/dist/index.mjs
|
||||
index 2813fc5d7336fcadf9e14f411d0624d58503872d..baf135c4932159f1d31d6f12d96920af2407761b 100644
|
||||
--- a/dist/index.mjs
|
||||
+++ b/dist/index.mjs
|
||||
@@ -7,8 +7,8 @@ import { Parser as Parser2 } from "acorn";
|
||||
import MagicString from "magic-string";
|
||||
|
||||
// src/format.ts
|
||||
-import _ from "lodash";
|
||||
-var kebabCase = _.kebabCase;
|
||||
+import { paramCase } from 'param-case'
|
||||
+var kebabCase = paramCase;
|
||||
function formatedComponentName(libraryName, componentName, option) {
|
||||
const {
|
||||
libraryDirectory = "lib",
|
||||
@@ -286,7 +286,7 @@ function dynamicImportPlugin(options) {
|
||||
throw new Error("Options must be array.");
|
||||
}
|
||||
const ext = path.extname(id).slice(1);
|
||||
- if (["js", "jsx", "ts", "tsx"].indexOf(ext) > -1) {
|
||||
+ if (["js", "jsx", "ts", "tsx", "vue"].indexOf(ext) > -1) {
|
||||
code = await transform_default(code, importOptions);
|
||||
}
|
||||
return code;
|
Loading…
Reference in New Issue