fix(build) 修复grid、pager组件bug

This commit is contained in:
zzcr 2023-05-18 05:34:12 -07:00
parent b17660f055
commit 31ff849040
No known key found for this signature in database
GPG Key ID: F6C4DFD2EF53A673
69 changed files with 85 additions and 6984 deletions

View File

@ -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))

View File

@ -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))

View File

@ -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))

View File

@ -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))

View File

@ -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()
}

View File

@ -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,

View File

@ -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;
}
}

View File

@ -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',

View File

@ -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);
// 分页选择框右侧下拉按钮

View File

@ -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);
// 弹出框垂直外边距

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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') } }
})
]
)
]
},

View File

@ -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,

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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.
*
-->

View File

@ -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>

View File

@ -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.
*
-->

View File

@ -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>

View File

@ -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>

View File

@ -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: () =>
// 使createComponentvuevnodeel
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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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;