Compare commits
47 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
2cda7bde09 | |
|
|
6255f1632c | |
|
|
ef51f7f1cc | |
|
|
252a0e2563 | |
|
|
bbb7670df1 | |
|
|
fcdda4a0be | |
|
|
79b63b41c6 | |
|
|
56d9b358f2 | |
|
|
b58e73d51a | |
|
|
e8ec520d9a | |
|
|
ce56f0c8f6 | |
|
|
723bb47a42 | |
|
|
57ea8a65d4 | |
|
|
7e5008080d | |
|
|
74b3018945 | |
|
|
28b1c4f62d | |
|
|
04f6ba33c7 | |
|
|
35c1ad9c80 | |
|
|
e9f8ea7903 | |
|
|
27acc9a80e | |
|
|
43ad5dec90 | |
|
|
aa8802679f | |
|
|
aa211fd789 | |
|
|
61d39be86f | |
|
|
b80bd37f6e | |
|
|
3db5e191b8 | |
|
|
45c7109212 | |
|
|
b58d0fb723 | |
|
|
a21a1ca533 | |
|
|
4a37016f4e | |
|
|
5d6ebb30ac | |
|
|
888457238d | |
|
|
b0d9309471 | |
|
|
f64d0718ae | |
|
|
968317ca9f | |
|
|
22dad3ba6d | |
|
|
4f7bd6f28d | |
|
|
12fcfa15b1 | |
|
|
e46d537d45 | |
|
|
ac9d1b0a7f | |
|
|
2c7008d786 | |
|
|
49d4b3166e | |
|
|
339fb4a230 | |
|
|
bb443a05e2 | |
|
|
3a79f72816 | |
|
|
89eec07145 | |
|
|
c69a6d29b2 |
|
|
@ -1,4 +1,4 @@
|
|||
blank_issues_enabled: false
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: Create new issue
|
||||
url: https://vuecomponent.github.io/issue-helper/
|
||||
|
|
@ -12,6 +12,3 @@ contact_links:
|
|||
- name: Paypal
|
||||
url: https://www.paypal.me/tangjinzhou
|
||||
about: Love Ant Design Vue? Please consider supporting us via Paypal.
|
||||
- name: 支付宝/微信 赞助
|
||||
url: https://aliyuncdn.antdv.com/alipay-and-wechat.png
|
||||
about: Ant Design Vue 的健康持续发展需要您的支持,🙏
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
name: Build and Deploy to Cloudflare
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
name: Build Application
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install --force
|
||||
|
||||
- name: Build application
|
||||
run: npm run build
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: build-files
|
||||
path: site/dist/
|
||||
retention-days: 1
|
||||
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
name: Deploy to Cloudflare
|
||||
needs: build
|
||||
permissions:
|
||||
contents: read
|
||||
deployments: write
|
||||
steps:
|
||||
- name: Checkout (for config files)
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
sparse-checkout: |
|
||||
wrangler.jsonc
|
||||
sparse-checkout-cone-mode: false
|
||||
|
||||
- name: Download build artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: build-files
|
||||
path: site/dist/
|
||||
|
||||
- name: Deploy (Workers + Static Assets)
|
||||
uses: cloudflare/wrangler-action@v3.14.1
|
||||
with:
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
command: deploy --config wrangler.jsonc
|
||||
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
|
@ -10,7 +10,7 @@ jobs:
|
|||
uses: actions/checkout@v2
|
||||
|
||||
- name: cache package-lock.json
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: package-temp-dir
|
||||
key: lock-${{ github.sha }}
|
||||
|
|
@ -27,7 +27,7 @@ jobs:
|
|||
|
||||
- name: cache node_modules
|
||||
id: node_modules_cache_id
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: node_modules
|
||||
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
||||
|
|
@ -52,13 +52,13 @@ jobs:
|
|||
# submodules: true
|
||||
|
||||
- name: restore cache from package-lock.json
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: package-temp-dir
|
||||
key: lock-${{ github.sha }}
|
||||
|
||||
- name: restore cache from node_modules
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: node_modules
|
||||
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ jobs:
|
|||
uses: actions/checkout@v2
|
||||
|
||||
- name: cache package-lock.json
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: package-temp-dir
|
||||
key: lock-${{ github.sha }}
|
||||
|
|
@ -27,7 +27,7 @@ jobs:
|
|||
|
||||
- name: cache node_modules
|
||||
id: node_modules_cache_id
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: node_modules
|
||||
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
||||
|
|
@ -43,25 +43,25 @@ jobs:
|
|||
uses: actions/checkout@v2
|
||||
|
||||
- name: restore cache from package-lock.json
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: package-temp-dir
|
||||
key: lock-${{ github.sha }}
|
||||
|
||||
- name: restore cache from node_modules
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: node_modules
|
||||
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
||||
|
||||
- name: cache lib
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: lib
|
||||
key: lib-${{ github.sha }}
|
||||
|
||||
- name: cache es
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: es
|
||||
key: es-${{ github.sha }}
|
||||
|
|
@ -77,13 +77,13 @@ jobs:
|
|||
uses: actions/checkout@v2
|
||||
|
||||
- name: restore cache from package-lock.json
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: package-temp-dir
|
||||
key: lock-${{ github.sha }}
|
||||
|
||||
- name: restore cache from node_modules
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: node_modules
|
||||
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
||||
|
|
@ -99,13 +99,13 @@ jobs:
|
|||
uses: actions/checkout@v2
|
||||
|
||||
- name: restore cache from package-lock.json
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: package-temp-dir
|
||||
key: lock-${{ github.sha }}
|
||||
|
||||
- name: restore cache from node_modules
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: node_modules
|
||||
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,22 @@
|
|||
|
||||
---
|
||||
|
||||
## 4.2.6
|
||||
|
||||
- 🐞 Fix Modal component aria-hidden error problem under chrome [#7823](https://github.com/vueComponent/ant-design-vue/issues/7823)
|
||||
- 🐞 Fix the problem that the built-in input method of Safari automatically fills in the decimal point when inputting Chinese [#7918](https://github.com/vueComponent/ant-design-vue/issues/7918)
|
||||
- 🐞 Fix InputNumber component disabled style problem [#7776](https://github.com/vueComponent/ant-design-vue/issues/7776)
|
||||
- 🐞 Fix Select cannot lose focus problem [#7819](https://github.com/vueComponent/ant-design-vue/issues/7819)
|
||||
|
||||
## 4.2.5
|
||||
|
||||
- 🐞 Fix Empty component memory leak problem
|
||||
- 🐞 Fix Image width & height property not working problem
|
||||
|
||||
## 4.2.4
|
||||
|
||||
- 🐞 Fix Wave memory leak problem
|
||||
|
||||
## 4.2.3
|
||||
|
||||
- 🌟 TourStep custom Button, support function children [#7628](https://github.com/vueComponent/ant-design-vue/pull/7628)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,22 @@
|
|||
|
||||
---
|
||||
|
||||
## 4.2.6
|
||||
|
||||
- 🐞 修复 Modal 组件在 chrome 下,aria-hidden 报错问题 [#7823](https://github.com/vueComponent/ant-design-vue/issues/7823)
|
||||
- 🐞 修复 Safari 下自带输入法 input 组件输入中文时,自动填写小数点问题 [#7918](https://github.com/vueComponent/ant-design-vue/issues/7918)
|
||||
- 🐞 修复 InputNumber 组件 disabled 样式问题 [#7776](https://github.com/vueComponent/ant-design-vue/issues/7776)
|
||||
- 🐞 修复 Select 无法失焦问题 [#7819](https://github.com/vueComponent/ant-design-vue/issues/7819)
|
||||
|
||||
## 4.2.5
|
||||
|
||||
- 🐞 修复 Empty 组件内存泄漏问题
|
||||
- 🐞 修复 Image width & height 属性不生效问题
|
||||
|
||||
## 4.2.4
|
||||
|
||||
- 🐞 修复 Wave 内存泄漏问题
|
||||
|
||||
## 4.2.3
|
||||
|
||||
- 🌟 TourStep 自定义 Button,支持函数 children [#7628](https://github.com/vueComponent/ant-design-vue/pull/7628)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,3 @@
|
|||
<p align="center">
|
||||
<a href="https://www.antdv.com/">
|
||||
<img width="200" src="https://aliyuncdn.antdv.com/logo.png">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<h1 align="center">
|
||||
<a href="https://www.antdv.com/" target="_blank">Ant Design Vue</a>
|
||||
</h1>
|
||||
|
|
@ -18,6 +12,14 @@
|
|||
|
||||
[](https://www.antdv.com/)
|
||||
|
||||
<div align="center">
|
||||
<sup><strong>赞助商</strong></sup>
|
||||
<br>
|
||||
<a href="https://mentorbook.ai/" target="_blank">
|
||||
<img src="/site/public/mentorbook_banner_zh.svg" alt="Mentorbook.AI - 你的 AI 导师,你的学习之旅" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
[English](./README.md) | 简体中文
|
||||
|
||||
## 特性
|
||||
|
|
@ -73,6 +75,7 @@ $ yarn add ant-design-vue
|
|||
| [vue-dash-event](https://github.com/vueComponent/vue-dash-event) | 在 DOM 模板中,您可以使用 ant-design-vue 组件的自定义事件(camelCase) |
|
||||
| [@formily/antdv](https://github.com/formilyjs/antdv) | 这是一个结合了 Formily 和 ant-design-vue 的组件库 |
|
||||
| [@ant-design-vue/nuxt](https://github.com/vueComponent/ant-design-vue-nuxt) | ant-design-vue 的 nuxt 模块扩展 |
|
||||
| [ant-design-x-vue](https://github.com/wzc520pyfm/ant-design-x-vue) | 基于 Ant Design X 设计规范的 Vue AI 界面解决方案 |
|
||||
|
||||
## 问答
|
||||
|
||||
|
|
@ -87,14 +90,13 @@ ant-design-vue 是 MIT 协议的开源项目。为了项目能够更好的持续
|
|||
- [Patreon](https://www.patreon.com/tangjinzhou)
|
||||
- [opencollective](https://opencollective.com/ant-design-vue)
|
||||
- [paypal](https://www.paypal.me/tangjinzhou)
|
||||
- [支付宝或微信](https://aliyuncdn.antdv.com/alipay-and-wechat.png)
|
||||
- ETH: 0x30cc48515d8ae9fefa20ab87226ad7e8ab9c3bc2
|
||||
|
||||
## 赞助商
|
||||
|
||||
成为赞助商,并在 Github 上的自述文件上获得您的徽标,并链接到您的网站。 [[成为赞助商](https://opencollective.com/ant-design-vue#sponsor)]
|
||||
|
||||
<a href="http://www.jeecg.com/" target="_blank"><img src="https://aliyuncdn.antdv.com/jeecg-logo.png" height="64"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/0/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/1/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/2/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/2/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/3/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/3/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/4/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/4/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/5/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/5/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/6/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/6/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/7/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/7/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/8/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/8/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/9/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/9/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/10/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/10/avatar.svg"></a>
|
||||
<a href="http://www.jeecg.com/" target="_blank"><img src="https://www.antdv.com/jeecg-logo.png" height="64"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/0/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/1/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/2/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/2/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/3/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/3/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/4/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/4/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/5/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/5/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/6/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/6/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/7/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/7/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/8/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/8/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/9/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/9/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/10/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/10/avatar.svg"></a>
|
||||
|
||||
## 支持者
|
||||
|
||||
|
|
|
|||
14
README.md
|
|
@ -1,6 +1,6 @@
|
|||
<p align="center">
|
||||
<a href="https://www.antdv.com/">
|
||||
<img width="200" src="https://aliyuncdn.antdv.com/logo.png">
|
||||
<img width="200" src="https://www.antdv.com/logo.png">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
|
|
@ -18,6 +18,14 @@ An enterprise-class UI components based on Ant Design and Vue.
|
|||
|
||||
[](https://www.antdv.com/)
|
||||
|
||||
<div align="center">
|
||||
<sup><strong>Sponsored by</strong></sup>
|
||||
<br>
|
||||
<a href="https://mentorbook.ai/" target="_blank">
|
||||
<img src="/site/public/mentorbook_banner_en.svg" alt="Mentorbook.AI - Your AI Mentor, Your Learning Journey" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
English | [简体中文](./README-zh_CN.md)
|
||||
|
||||
## Features
|
||||
|
|
@ -73,6 +81,7 @@ If you are in a bad network environment, you can try other registries and tools
|
|||
| [vue-dash-event](https://github.com/vueComponent/vue-dash-event) | The library function, implemented in the DOM template, can use the custom event of the ant-design-vue component (camelCase) |
|
||||
| [@formily/antdv](https://github.com/formilyjs/antdv) | The Library with Formily and ant-design-vue |
|
||||
| [@ant-design-vue/nuxt](https://github.com/vueComponent/ant-design-vue-nuxt) | A nuxt module for ant-design-vue |
|
||||
| [ant-design-x-vue](https://github.com/wzc520pyfm/ant-design-x-vue) | A Vue AI interface solutions base on the Ant Design X design specification |
|
||||
|
||||
## Donation
|
||||
|
||||
|
|
@ -81,14 +90,13 @@ ant-design-vue is an MIT-licensed open source project. In order to achieve bette
|
|||
- [Patreon](https://www.patreon.com/tangjinzhou)
|
||||
- [opencollective](https://opencollective.com/ant-design-vue)
|
||||
- [paypal](https://www.paypal.me/tangjinzhou)
|
||||
- [支付宝或微信](https://aliyuncdn.antdv.com/alipay-and-wechat.png)
|
||||
- ETH: 0x30cc48515d8ae9fefa20ab87226ad7e8ab9c3bc2
|
||||
|
||||
## Sponsors
|
||||
|
||||
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/ant-design-vue#sponsor)]
|
||||
|
||||
<a href="http://www.jeecg.com/" target="_blank"><img src="https://aliyuncdn.antdv.com/jeecg-logo.png" height="64"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/0/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/1/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/2/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/2/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/3/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/3/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/4/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/4/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/5/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/5/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/6/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/6/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/7/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/7/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/8/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/8/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/9/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/9/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/10/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/10/avatar.svg"></a>
|
||||
<a href="http://www.jeecg.com/" target="_blank"><img src="https://www.antdv.com/jeecg-logo.png" height="64"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/0/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/1/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/2/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/2/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/3/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/3/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/4/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/4/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/5/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/5/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/6/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/6/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/7/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/7/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/8/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/8/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/9/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/9/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/10/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/10/avatar.svg"></a>
|
||||
|
||||
## [More Sponsor (From Patreon、alipay、wechat、paypal...)](https://github.com/vueComponent/ant-design-vue/blob/master/BACKERS.md)
|
||||
|
||||
|
|
|
|||
|
|
@ -159,6 +159,12 @@ function showWaveEffect(node: HTMLElement, className: string) {
|
|||
node?.insertBefore(holder, node?.firstChild);
|
||||
|
||||
render(<WaveEffect target={node} className={className} />, holder);
|
||||
return () => {
|
||||
render(null, holder);
|
||||
if (holder.parentElement) {
|
||||
holder.parentElement.removeChild(holder);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default showWaveEffect;
|
||||
|
|
|
|||
|
|
@ -33,13 +33,12 @@ export default defineComponent({
|
|||
|
||||
// =============================== Wave ===============================
|
||||
const showWave = useWave(
|
||||
instance,
|
||||
computed(() => classNames(prefixCls.value, hashId.value)),
|
||||
wave,
|
||||
);
|
||||
let onClick: (e: MouseEvent) => void;
|
||||
const clear = () => {
|
||||
const node = findDOMNode(instance);
|
||||
const node = findDOMNode(instance) as HTMLElement;
|
||||
node.removeEventListener('click', onClick, true);
|
||||
};
|
||||
onMounted(() => {
|
||||
|
|
|
|||
|
|
@ -1,21 +1,25 @@
|
|||
import type { ComponentInternalInstance, ComputedRef, Ref } from 'vue';
|
||||
import type { ComputedRef, Ref } from 'vue';
|
||||
import { onBeforeUnmount, getCurrentInstance } from 'vue';
|
||||
import { findDOMNode } from '../props-util';
|
||||
import showWaveEffect from './WaveEffect';
|
||||
|
||||
export default function useWave(
|
||||
instance: ComponentInternalInstance | null,
|
||||
className: Ref<string>,
|
||||
wave?: ComputedRef<{ disabled?: boolean }>,
|
||||
): VoidFunction {
|
||||
const instance = getCurrentInstance();
|
||||
let stopWave: () => void;
|
||||
function showWave() {
|
||||
const node = findDOMNode(instance);
|
||||
|
||||
stopWave?.();
|
||||
if (wave?.value?.disabled || !node) {
|
||||
return;
|
||||
}
|
||||
|
||||
showWaveEffect(node, className.value);
|
||||
stopWave = showWaveEffect(node, className.value);
|
||||
}
|
||||
onBeforeUnmount(() => {
|
||||
stopWave?.();
|
||||
});
|
||||
|
||||
return showWave;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ If you want specific control over the positioning and placement of the `Icon`, t
|
|||
|
||||
<template>
|
||||
<a-space direction="vertical">
|
||||
<a-space warp>
|
||||
<a-space wrap>
|
||||
<a-tooltip title="search">
|
||||
<a-button type="primary" shape="circle" :icon="h(SearchOutlined)" />
|
||||
</a-tooltip>
|
||||
|
|
@ -32,7 +32,7 @@ If you want specific control over the positioning and placement of the `Icon`, t
|
|||
</a-tooltip>
|
||||
<a-button :icon="h(SearchOutlined)">Search</a-button>
|
||||
</a-space>
|
||||
<a-space warp>
|
||||
<a-space wrap>
|
||||
<a-tooltip title="search">
|
||||
<a-button shape="circle" :icon="h(SearchOutlined)" />
|
||||
</a-tooltip>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { defineComponent } from 'vue';
|
||||
import { defineComponent, h } from 'vue';
|
||||
import type { CSSProperties, ExtractPropTypes } from 'vue';
|
||||
import classNames from '../_util/classNames';
|
||||
import LocaleReceiver from '../locale-provider/LocaleReceiver';
|
||||
|
|
@ -11,9 +11,6 @@ import useConfigInject from '../config-provider/hooks/useConfigInject';
|
|||
|
||||
import useStyle from './style';
|
||||
|
||||
const defaultEmptyImg = <DefaultEmptyImg />;
|
||||
const simpleEmptyImg = <SimpleEmptyImg />;
|
||||
|
||||
interface Locale {
|
||||
description?: string;
|
||||
}
|
||||
|
|
@ -40,13 +37,16 @@ const Empty = defineComponent({
|
|||
return () => {
|
||||
const prefixCls = prefixClsRef.value;
|
||||
const {
|
||||
image = slots.image?.() || defaultEmptyImg,
|
||||
image: mergedImage = slots.image?.() || h(DefaultEmptyImg),
|
||||
description = slots.description?.() || undefined,
|
||||
imageStyle,
|
||||
class: className = '',
|
||||
...restProps
|
||||
} = { ...props, ...attrs };
|
||||
|
||||
const image =
|
||||
typeof mergedImage === 'function' ? (mergedImage as () => VueNode)() : mergedImage;
|
||||
const isNormal =
|
||||
typeof image === 'object' && 'type' in image && (image.type as any).PRESENTED_IMAGE_SIMPLE;
|
||||
return wrapSSR(
|
||||
<LocaleReceiver
|
||||
componentName="Empty"
|
||||
|
|
@ -64,7 +64,7 @@ const Empty = defineComponent({
|
|||
return (
|
||||
<div
|
||||
class={classNames(prefixCls, className, hashId.value, {
|
||||
[`${prefixCls}-normal`]: image === simpleEmptyImg,
|
||||
[`${prefixCls}-normal`]: isNormal,
|
||||
[`${prefixCls}-rtl`]: direction.value === 'rtl',
|
||||
})}
|
||||
{...restProps}
|
||||
|
|
@ -85,7 +85,7 @@ const Empty = defineComponent({
|
|||
},
|
||||
});
|
||||
|
||||
Empty.PRESENTED_IMAGE_DEFAULT = defaultEmptyImg;
|
||||
Empty.PRESENTED_IMAGE_SIMPLE = simpleEmptyImg;
|
||||
Empty.PRESENTED_IMAGE_DEFAULT = () => h(DefaultEmptyImg);
|
||||
Empty.PRESENTED_IMAGE_SIMPLE = () => h(SimpleEmptyImg);
|
||||
|
||||
export default withInstall(Empty);
|
||||
|
|
|
|||
|
|
@ -33,11 +33,11 @@ tag: New
|
|||
| target | 相当于 a 标签的 target 属性,href 存在时生效 | string | - | |
|
||||
| badge | 带徽标数字的悬浮按钮(不支持 status 以及相关属性) | [BadgeProps](/components/badge-cn#api) | - | |
|
||||
|
||||
### common events
|
||||
### 共同的事件
|
||||
|
||||
| 事件名称 | 说明 | 回调参数 | 版本 |
|
||||
| -------- | --------------------------------------- | ----------------- | ---- |
|
||||
| click | Set the handler to handle `click` event | `(event) => void` | - |
|
||||
| 事件名称 | 说明 | 回调参数 | 版本 |
|
||||
| -------- | ----------------------------- | ----------------- | ---- |
|
||||
| click | 设置处理 `click` 事件的处理器 | `(event) => void` | - |
|
||||
|
||||
### FloatButton.Group
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ tag: New
|
|||
| trigger | 触发方式(有触发方式为菜单模式) | `click` \| `hover` | - | |
|
||||
| open(v-model) | 受控展开 | boolean | - | |
|
||||
|
||||
### FloatButton.Group Events
|
||||
### FloatButton.Group 事件
|
||||
|
||||
| 事件名称 | 说明 | 回调参数 | 版本 |
|
||||
| ---------- | ---------------- | ----------------------- | ---- |
|
||||
|
|
|
|||
|
|
@ -122,6 +122,8 @@ See [iconfont.cn documents](http://iconfont.cn/help/detail?spm=a313x.7781069.199
|
|||
|
||||
### Custom SVG Icon
|
||||
|
||||
#### vue cli 3
|
||||
|
||||
You can import SVG icon as an vue component by using `vue cli 3` and [`vue-svg-loader`](https://www.npmjs.com/package/vue-svg-loader). `vue-svg-loader`'s `options` [reference](https://github.com/visualfanatic/vue-svg-loader).
|
||||
|
||||
```js
|
||||
|
|
@ -149,6 +151,84 @@ export default defineComponent({
|
|||
});
|
||||
```
|
||||
|
||||
#### Rsbuild
|
||||
|
||||
Rsbuild is a new generation of build tool, official website https://rsbuild.dev/
|
||||
Create your own `vue-svg-loader.js` file, which allows you to customize and beautify SVG, and then configure it in `rsbuild.config.ts`
|
||||
|
||||
```js
|
||||
// vue-svg-loader.js
|
||||
/* eslint-disable */
|
||||
const { optimize } = require('svgo');
|
||||
const { version } = require('vue');
|
||||
const semverMajor = require('semver/functions/major');
|
||||
|
||||
module.exports = async function (svg) {
|
||||
const callback = this.async();
|
||||
|
||||
try {
|
||||
({ data: svg } = await optimize(svg, {
|
||||
path: this.resourcePath,
|
||||
js2svg: {
|
||||
indent: 2,
|
||||
pretty: true,
|
||||
},
|
||||
plugins: [
|
||||
'convertStyleToAttrs',
|
||||
'removeDoctype',
|
||||
'removeXMLProcInst',
|
||||
'removeComments',
|
||||
'removeMetadata',
|
||||
'removeTitle',
|
||||
'removeDesc',
|
||||
'removeStyleElement',
|
||||
'removeXMLNS',
|
||||
'removeXMLProcInst',
|
||||
],
|
||||
}));
|
||||
} catch (error) {
|
||||
callback(error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (semverMajor(version) === 2) {
|
||||
svg = svg.replace('<svg', '<svg v-on="$listeners"');
|
||||
}
|
||||
|
||||
callback(null, `<template>${svg}</template>`);
|
||||
};
|
||||
```
|
||||
|
||||
```js
|
||||
// rsbuild.config.ts
|
||||
/* eslint-disable */
|
||||
import { defineConfig } from '@rsbuild/core';
|
||||
import { pluginVue } from '@rsbuild/plugin-vue';
|
||||
|
||||
export default defineConfig({
|
||||
tools: {
|
||||
bundlerChain(chain, { CHAIN_ID }) {
|
||||
chain.module.rule(CHAIN_ID.RULE.SVG).exclude.add(/\.svg$/);
|
||||
},
|
||||
rspack: {
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.svg$/,
|
||||
use: ['vue-loader', 'vue-svg-loader'],
|
||||
},
|
||||
],
|
||||
},
|
||||
resolveLoader: {
|
||||
alias: {
|
||||
'vue-svg-loader': require('path').join(__dirname, './vue-svg-loader.js'),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
The following properties are available for the component:
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
|
|
|
|||
|
|
@ -119,7 +119,9 @@ export default defineComponent({
|
|||
|
||||
### 自定义 SVG 图标
|
||||
|
||||
如果使用 `vue cli 3`,可以通过配置 [vue-svg-loader](https://www.npmjs.com/package/vue-svg-loader) 来将 `svg` 图标作为 `Vue` 组件导入。更多`vue-svg-loader` 的使用方式请参阅 [文档](https://github.com/visualfanatic/vue-svg-loader)。
|
||||
#### vue cli 3
|
||||
|
||||
可以通过配置 [vue-svg-loader](https://www.npmjs.com/package/vue-svg-loader) 来将 `svg` 图标作为 `Vue` 组件导入。更多`vue-svg-loader` 的使用方式请参阅 [文档](https://github.com/visualfanatic/vue-svg-loader)。
|
||||
|
||||
```js
|
||||
// vue.config.js
|
||||
|
|
@ -146,6 +148,88 @@ export default defineComponent({
|
|||
});
|
||||
```
|
||||
|
||||
#### Rsbuild
|
||||
|
||||
Rsbuild 是新一代构建工具,官网 https://rsbuild.dev/
|
||||
|
||||
自己实现一个 `vue-svg-loader.js` 文件,好处是可以自定义美化 svg,然后在 `rsbuild.config.ts` 中配置:
|
||||
|
||||
```js
|
||||
// vue-svg-loader.js
|
||||
/* eslint-disable */
|
||||
const { optimize } = require('svgo');
|
||||
const { version } = require('vue');
|
||||
const semverMajor = require('semver/functions/major');
|
||||
|
||||
module.exports = async function (svg) {
|
||||
const callback = this.async();
|
||||
|
||||
try {
|
||||
({ data: svg } = await optimize(svg, {
|
||||
path: this.resourcePath,
|
||||
js2svg: {
|
||||
indent: 2,
|
||||
pretty: true,
|
||||
},
|
||||
plugins: [
|
||||
'convertStyleToAttrs',
|
||||
'removeDoctype',
|
||||
'removeXMLProcInst',
|
||||
'removeComments',
|
||||
'removeMetadata',
|
||||
'removeTitle',
|
||||
'removeDesc',
|
||||
'removeStyleElement',
|
||||
'removeXMLNS',
|
||||
'removeXMLProcInst',
|
||||
],
|
||||
}));
|
||||
} catch (error) {
|
||||
callback(error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (semverMajor(version) === 2) {
|
||||
svg = svg.replace('<svg', '<svg v-on="$listeners"');
|
||||
}
|
||||
|
||||
callback(null, `<template>${svg}</template>`);
|
||||
};
|
||||
```
|
||||
|
||||
```js
|
||||
// rsbuild.config.ts
|
||||
/* eslint-disable */
|
||||
import { defineConfig } from '@rsbuild/core';
|
||||
import { pluginVue } from '@rsbuild/plugin-vue';
|
||||
|
||||
export default defineConfig({
|
||||
tools: {
|
||||
bundlerChain(chain, { CHAIN_ID }) {
|
||||
chain.module
|
||||
// 先给svg排除默认的规则,方便下面自定义loader
|
||||
.rule(CHAIN_ID.RULE.SVG)
|
||||
.exclude.add(/\.svg$/);
|
||||
},
|
||||
rspack: {
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.svg$/,
|
||||
use: ['vue-loader', 'vue-svg-loader'],
|
||||
},
|
||||
],
|
||||
},
|
||||
resolveLoader: {
|
||||
alias: {
|
||||
'vue-svg-loader': require('path').join(__dirname, './vue-svg-loader.js'),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
`Icon` 中的 `component` 组件的接受的属性如下:
|
||||
|
||||
| 字段 | 说明 | 类型 | 只读值 |
|
||||
|
|
|
|||
|
|
@ -58,13 +58,13 @@ exports[`renders ./components/image/demo/placeholder.vue correctly 1`] = `
|
|||
`;
|
||||
|
||||
exports[`renders ./components/image/demo/preview-group.vue correctly 1`] = `
|
||||
<div class="ant-image" style="width: 200px;"><img width="200" class="ant-image-img" src="https://aliyuncdn.antdv.com/vue.png">
|
||||
<div class="ant-image" style="width: 200px;"><img width="200" class="ant-image-img" src="https://www.antdv.com/vue.png">
|
||||
<!---->
|
||||
<div class="ant-image-mask">
|
||||
<div class="ant-image-mask-info"><span role="img" aria-label="eye" class="anticon anticon-eye"><svg focusable="false" class="" data-icon="eye" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 000 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"></path></svg></span>Preview</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-image" style="width: 200px;"><img width="200" class="ant-image-img" src="https://aliyuncdn.antdv.com/logo.png">
|
||||
<div class="ant-image" style="width: 200px;"><img width="200" class="ant-image-img" src="https://www.antdv.com/logo.png">
|
||||
<!---->
|
||||
<div class="ant-image-mask">
|
||||
<div class="ant-image-mask-info"><span role="img" aria-label="eye" class="anticon anticon-eye"><svg focusable="false" class="" data-icon="eye" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 000 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"></path></svg></span>Preview</div>
|
||||
|
|
@ -106,7 +106,7 @@ exports[`renders ./components/image/demo/preview-group-visible.vue correctly 1`]
|
|||
`;
|
||||
|
||||
exports[`renders ./components/image/demo/preview-src.vue correctly 1`] = `
|
||||
<div class="ant-image" style="width: 200px;"><img width="200" class="ant-image-img" src="https://aliyuncdn.antdv.com/logo.png">
|
||||
<div class="ant-image" style="width: 200px;"><img width="200" class="ant-image-img" src="https://www.antdv.com/logo.png">
|
||||
<!---->
|
||||
<div class="ant-image-mask">
|
||||
<div class="ant-image-mask-info"><span role="img" aria-label="eye" class="anticon anticon-eye"><svg focusable="false" class="" data-icon="eye" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 000 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"></path></svg></span>Preview</div>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ Click the left and right switch buttons to preview multiple images.
|
|||
|
||||
<template>
|
||||
<a-image-preview-group>
|
||||
<a-image :width="200" src="https://aliyuncdn.antdv.com/vue.png" />
|
||||
<a-image :width="200" src="https://aliyuncdn.antdv.com/logo.png" />
|
||||
<a-image :width="200" src="https://www.antdv.com/vue.png" />
|
||||
<a-image :width="200" src="https://www.antdv.com/logo.png" />
|
||||
</a-image-preview-group>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ You can set different preview image.
|
|||
<template>
|
||||
<a-image
|
||||
:width="200"
|
||||
src="https://aliyuncdn.antdv.com/logo.png"
|
||||
src="https://www.antdv.com/logo.png"
|
||||
:preview="{
|
||||
src: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
|
||||
}"
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ export type ImageProps = Partial<
|
|||
ExtractPropTypes<ReturnType<typeof imageProps>> &
|
||||
Omit<ImgHTMLAttributes, 'placeholder' | 'onClick'>
|
||||
>;
|
||||
const Image = defineComponent<ImageProps>({
|
||||
const Image = defineComponent({
|
||||
name: 'AImage',
|
||||
inheritAttrs: false,
|
||||
props: imageProps() as any,
|
||||
props: imageProps(),
|
||||
setup(props, { slots, attrs }) {
|
||||
const { prefixCls, rootPrefixCls, configProvider } = useConfigInject('image', props);
|
||||
// Style
|
||||
|
|
|
|||
|
|
@ -395,6 +395,11 @@ export default defineComponent({
|
|||
}
|
||||
};
|
||||
|
||||
// Solve the issue of the event triggering sequence when entering numbers in chinese input (Safari)
|
||||
const onBeforeInput = () => {
|
||||
userTypingRef.value = true;
|
||||
};
|
||||
|
||||
const onKeyDown: KeyboardEventHandler = event => {
|
||||
const { which } = event;
|
||||
userTypingRef.value = true;
|
||||
|
|
@ -577,6 +582,7 @@ export default defineComponent({
|
|||
onBlur={onBlur}
|
||||
onCompositionstart={onCompositionStart}
|
||||
onCompositionend={onCompositionEnd}
|
||||
onBeforeinput={onBeforeInput}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -263,6 +263,10 @@ const genInputNumberStyles: GenerateStyle<InputNumberToken> = (token: InputNumbe
|
|||
[`${componentCls}-handler-wrap`]: {
|
||||
display: 'none',
|
||||
},
|
||||
|
||||
[`${componentCls}-input`]: {
|
||||
color: 'inherit',
|
||||
},
|
||||
},
|
||||
|
||||
[`
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ const value15 = ref<string>('Sign Up');
|
|||
const value16 = ref<string>('');
|
||||
const value17 = ref<string>('Home');
|
||||
const value18 = ref<string[]>([]);
|
||||
const value19 = ref<string>('https://surely.cool');
|
||||
const value19 = ref<string>('https://surelyvue.com');
|
||||
const value20 = ref<string>('https://antdv.com');
|
||||
</script>
|
||||
<style scoped>
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ A basic widget for getting the user input is a text field. Keyboard and mouse ca
|
|||
| id | The ID for input | string | | |
|
||||
| maxlength | max length | number | | 1.5.0 |
|
||||
| prefix | The prefix icon for the Input. | string\|slot | | |
|
||||
| showCount | Whether show text count | boolean | false | 3.0 |
|
||||
| showCount | Whether show text count | boolean \| { formatter: (info: { value: string, count: number, maxLength?: number }) => string | false | 3.0 |
|
||||
| status | Set validation status | 'error' \| 'warning' | - | 3.3.0 |
|
||||
| size | The size of the input box. Note: in the context of a form, the `middle` size is used. Available: `large` `middle` `small` | string | - | |
|
||||
| suffix | The suffix icon for the Input. | string\|slot | | |
|
||||
|
|
@ -52,7 +52,7 @@ A basic widget for getting the user input is a text field. Keyboard and mouse ca
|
|||
| allowClear | allow to remove input content with clear icon | boolean | | 1.5.0 | |
|
||||
| autosize | Height autosize feature, can be set to `true | false`or an object`{ minRows: 2, maxRows: 6 }` | boolean\|object | false | |
|
||||
| defaultValue | The initial input content | string | | | |
|
||||
| showCount | Whether show text count | boolean | false | | |
|
||||
| showCount | Whether show text count | boolean \| { formatter: (info: { value: string, count: number, maxLength?: number }) => string | false | | |
|
||||
| value(v-model) | The input content value | string | | | |
|
||||
|
||||
### TextArea Events
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*sBqqTatJ-AkAAA
|
|||
| id | 输入框的 id | string | | |
|
||||
| maxlength | 最大长度 | number | | 1.5.0 |
|
||||
| prefix | 带有前缀图标的 input | string\|slot | | |
|
||||
| showCount | 是否展示字数 | boolean | false | 3.0 |
|
||||
| showCount | 是否展示字数 | boolean \| { formatter: (info: { value: string, count: number, maxLength?: number }) => string } | false | 3.0 |
|
||||
| status | 设置校验状态 | 'error' \| 'warning' | - | 3.3.0 |
|
||||
| size | 控件大小。注:标准表单内的输入框大小限制为 `middle`。可选 `large` `middle` `small` | string | - | |
|
||||
| suffix | 带有后缀图标的 input | string\|slot | | |
|
||||
|
|
@ -53,7 +53,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*sBqqTatJ-AkAAA
|
|||
| allowClear | 可以点击清除图标删除内容 | boolean | | 1.5.0 | |
|
||||
| autosize | 自适应内容高度,可设置为 `true | false` 或对象:`{ minRows: 2, maxRows: 6 }` | boolean\|object | false | |
|
||||
| defaultValue | 输入框默认内容 | string | | | |
|
||||
| showCount | 是否展示字数 | boolean | false | | |
|
||||
_| showCount | 是否展示字数 | boolean \| { formatter: (info: { value: string, count: number, maxLength?: number }) => string } | false | | |_
|
||||
| value(v-model) | 输入框内容 | string | | | |
|
||||
|
||||
### TextArea 事件
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
order: 4
|
||||
title:
|
||||
zh-CN: 向上展开
|
||||
en-US: Placemen
|
||||
en-US: Placement
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
|
|
|||
|
|
@ -47,7 +47,9 @@ const Holder = defineComponent({
|
|||
'rtl',
|
||||
'transitionName',
|
||||
'onAllRemoved',
|
||||
] as any,
|
||||
'animation',
|
||||
'staticGetContainer',
|
||||
],
|
||||
setup(props, { expose }) {
|
||||
const { getPrefixCls, getPopupContainer } = useConfigInject('message', props);
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ exports[`renders ./components/qrcode/demo/icon.vue correctly 1`] = `
|
|||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/qrcode/demo/popover.vue correctly 1`] = `<img width="100" height="100" src="https://aliyuncdn.antdv.com/logo.png">`;
|
||||
exports[`renders ./components/qrcode/demo/popover.vue correctly 1`] = `<img width="100" height="100" src="https://www.antdv.com/logo.png">`;
|
||||
|
||||
exports[`renders ./components/qrcode/demo/status.vue correctly 1`] = `
|
||||
<div class="ant-space ant-space-horizontal ant-space-align-center">
|
||||
|
|
|
|||
|
|
@ -19,6 +19,6 @@ With Popover.
|
|||
<template #content>
|
||||
<a-qrcode value="http://www.antdv.com" :bordered="false" />
|
||||
</template>
|
||||
<img width="100" height="100" src="https://aliyuncdn.antdv.com/logo.png" />
|
||||
<img width="100" height="100" src="https://www.antdv.com/logo.png" />
|
||||
</a-popover>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -159,6 +159,52 @@ describe('Select', () => {
|
|||
}, 500);
|
||||
});
|
||||
|
||||
it('The select trigger should be blur when the panel is closed.', async () => {
|
||||
const wrapper = mount(
|
||||
{
|
||||
render() {
|
||||
return (
|
||||
<Select
|
||||
dropdownRender={() => {
|
||||
return <input id="dropdownRenderInput" />;
|
||||
}}
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
sync: false,
|
||||
attachTo: 'body',
|
||||
},
|
||||
);
|
||||
await asyncExpect(async () => {
|
||||
await wrapper.find('.ant-select-selector').trigger('mousedown');
|
||||
await wrapper.find('.ant-select-selection-search-input').trigger('focus');
|
||||
});
|
||||
|
||||
await asyncExpect(async () => {
|
||||
const el = wrapper.find('.ant-select');
|
||||
|
||||
expect(el.classes()).toContain('ant-select-focused');
|
||||
$$('#dropdownRenderInput')[0].focus();
|
||||
|
||||
expect(el.classes()).toContain('ant-select-focused');
|
||||
|
||||
document.body.dispatchEvent(
|
||||
new MouseEvent('mousedown', {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
view: window,
|
||||
}),
|
||||
);
|
||||
}, 100);
|
||||
|
||||
await asyncExpect(async () => {
|
||||
const el = wrapper.find('.ant-select');
|
||||
expect(el.classes()).not.toContain('ant-select-focused');
|
||||
}, 200);
|
||||
});
|
||||
|
||||
describe('Select Custom Icons', () => {
|
||||
it('should support customized icons', () => {
|
||||
const wrapper = mount({
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ Select component to select value from options.
|
|||
| searchValue | The current input "search" text | string | - | |
|
||||
| showArrow | Whether to show the drop-down arrow | boolean | single:true, multiple:false | |
|
||||
| showSearch | Whether select is searchable | boolean | single:false, multiple:true | |
|
||||
| size | Size of Select input. `default` `large` `small` | string | default | |
|
||||
| size | Size of Select input. `middle` `large` `small` | string | middle | |
|
||||
| status | Set validation status | 'error' \| 'warning' | - | 3.3.0 |
|
||||
| suffixIcon | The custom suffix icon | VNode \| slot | - | |
|
||||
| tagRender | Customize tag render, only applies when `mode` is set to `multiple` or `tags` | slot \| (props) => any | - | |
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*5oPiTqPxGAUAAA
|
|||
| searchValue | 控制搜索文本 | string | - | |
|
||||
| showArrow | 是否显示下拉小箭头 | boolean | 单选为 true,多选为 false | |
|
||||
| showSearch | 配置是否可搜索 | boolean | 单选为 false,多选为 true | |
|
||||
| size | 选择框大小,可选 `large` `small` | string | default | |
|
||||
| size | 选择框大小,可选 `middle` `large` `small` | string | middle | |
|
||||
| status | 设置校验状态 | 'error' \| 'warning' | - | 3.3.0 |
|
||||
| suffixIcon | 自定义的选择框后缀图标 | VNode \| slot | - | |
|
||||
| tagRender | 自定义 tag 内容 render,仅在 `mode` 为 `multiple` 或 `tags` 时生效 | slot \| (props) => any | - | 3.0 |
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ export default function genMultipleStyle(token: SelectToken): CSSInterpolation {
|
|||
[`${componentCls}-multiple${componentCls}-sm`]: {
|
||||
[`${componentCls}-selection-placeholder`]: {
|
||||
insetInlineStart: token.controlPaddingHorizontalSM - token.lineWidth,
|
||||
insetInlineEnd: 'auto',
|
||||
insetInlineEnd: token.controlPaddingHorizontalSM - token.lineWidth,
|
||||
},
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/29559
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ The `onChange` callback function will fire when the user changes the slider's va
|
|||
|
||||
<template>
|
||||
<div class="code-box-demo">
|
||||
<a-slider v-model:value="value1" @afterChange="onAfterChange" />
|
||||
<a-slider v-model:value="value2" range :step="10" @afterChange="onAfterChange" />
|
||||
<a-slider v-model:value="value1" @change="onChange" @afterChange="onAfterChange" />
|
||||
<a-slider v-model:value="value2" range :step="10" @change="onChange" @afterChange="onAfterChange" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
|
|
@ -26,6 +26,10 @@ import { ref } from 'vue';
|
|||
const value1 = ref<number>(30);
|
||||
const value2 = ref<[number, number]>([20, 50]);
|
||||
|
||||
const onChange = (value: number) => {
|
||||
console.log('onChange: ', value);
|
||||
};
|
||||
|
||||
const onAfterChange = (value: number) => {
|
||||
console.log('afterChange: ', value);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -182,6 +182,7 @@ const genBaseStyle: GenerateStyle<SliderToken> = token => {
|
|||
borderRadius: '50%',
|
||||
cursor: 'pointer',
|
||||
transition: `border-color ${token.motionDurationSlow}`,
|
||||
pointerEvents: 'auto',
|
||||
|
||||
'&-active': {
|
||||
borderColor: token.colorPrimaryBorder,
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ exports[`renders ./components/table/demo/basic.vue correctly 1`] = `
|
|||
`;
|
||||
|
||||
exports[`renders ./components/table/demo/big-data.vue correctly 1`] = `
|
||||
<iframe src="https://www.surely.cool/for-ant-demo" height="400"></iframe>
|
||||
<iframe src="https://www.surelyvue.com/for-ant-demo" height="400"></iframe>
|
||||
<!--v-if-->
|
||||
`;
|
||||
|
||||
|
|
|
|||
|
|
@ -79,8 +79,9 @@ type APIResult = {
|
|||
}[];
|
||||
};
|
||||
|
||||
const queryData = (params: APIParams) => {
|
||||
return axios.get<APIResult>('https://randomuser.me/api?noinfo', { params });
|
||||
const queryData = async (params: APIParams) => {
|
||||
const res = await axios.get<APIResult>('https://randomuser.me/api?noinfo', { params })
|
||||
return res.data.results;
|
||||
};
|
||||
|
||||
const {
|
||||
|
|
@ -90,7 +91,6 @@ const {
|
|||
current,
|
||||
pageSize,
|
||||
} = usePagination(queryData, {
|
||||
formatResult: res => res.data.results,
|
||||
pagination: {
|
||||
currentKey: 'page',
|
||||
pageSizeKey: 'results',
|
||||
|
|
|
|||
|
|
@ -8,21 +8,21 @@ title:
|
|||
|
||||
## zh-CN
|
||||
|
||||
该示例使用高级组件 [Surely Vue](https://www.surely.cool) 进行开发,Surely Vue 是 Ant Design Vue 旗下的高级组件,
|
||||
该示例使用高级组件 [Surely Vue](https://www.surelyvue.com) 进行开发,Surely Vue 是 Ant Design Vue 旗下的高级组件,
|
||||
该组件致力于解决大数据渲染、图表集成等复杂高频问题。 使用该组件可以流畅滚动 10 万行、10 万列的数据,你不必担心页面卡顿造成用户投诉,进而影响业务进展。
|
||||
|
||||
## en-US
|
||||
|
||||
This example uses advanced components [Surely Vue](https://www.surely.cool) for development.
|
||||
This example uses advanced components [Surely Vue](https://www.surelyvue.com) for development.
|
||||
This component is dedicated to solving complex high-frequency issues such as big data rendering and chart integration.
|
||||
Using this component, you can smoothly scroll through 100,000 rows and 100,000 columns of data.
|
||||
</docs>
|
||||
|
||||
<template>
|
||||
<iframe src="https://www.surely.cool/for-ant-demo" height="400"></iframe>
|
||||
<iframe src="https://www.surelyvue.com/for-ant-demo" height="400"></iframe>
|
||||
<div v-if="false">
|
||||
you can visit
|
||||
<a href="https://www.surely.cool"></a>
|
||||
<a href="https://www.surelyvue.com"></a>
|
||||
get more info
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ Ant Design has 3 types of Tabs for different situations.
|
|||
| --- | --- | --- | --- | --- |
|
||||
| activeKey(v-model) | Current TabPane's key | string | - | |
|
||||
| animated | Whether to change tabs with animation. Only works while tabPosition=`"top"` \| `"bottom"` | boolean \| {inkBar:boolean, tabPane:boolean} | `true`, `false` when `type="card"` | |
|
||||
| centered | Whether to display the labels in the center | boolean | false | 3.0 |
|
||||
| destroyInactiveTabPane | Whether destroy inactive TabPane when change tab | boolean | false | |
|
||||
| hideAdd | Hide plus icon or not. Only works while `type="editable-card"` | boolean | `false` | } |
|
||||
| size | preset tab bar size | `large` \| `middle` \| `small` | `middle` | |
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ Almost anything can be represented in a tree structure. Examples include directo
|
|||
| disableCheckbox | Disables the checkbox of the treeNode | boolean | false | |
|
||||
| disabled | Disables the treeNode | boolean | false | |
|
||||
| icon | customize icon. When you pass component, whose render will receive full TreeNode props as component props | slot\|slot-scope | - | |
|
||||
| isLeaf | Determines if this is a leaf node(effective when `loadData` is specified) | boolean | false | |
|
||||
| isLeaf | Determines if this is a leaf node(effective when `loadData` is specified) | boolean | - | |
|
||||
| key | Used with (default)ExpandedKeys / (default)CheckedKeys / (default)SelectedKeys. P.S.: It must be unique in all of treeNodes of the tree! | string \| number | internal calculated position of treeNode | |
|
||||
| selectable | Set whether the treeNode can be selected | boolean | true | |
|
||||
| style | style | string\|object | - | |
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*1GeUQJPTGUYAAA
|
|||
| disableCheckbox | 禁掉 checkbox | boolean | false | |
|
||||
| disabled | 禁掉响应 | boolean | false | |
|
||||
| icon | 自定义图标。可接收组件,props 为当前节点 props | slot\|slot-scope | - | |
|
||||
| isLeaf | 设置为叶子节点(设置了`loadData`时有效) | boolean | false | |
|
||||
| isLeaf | 设置为叶子节点(设置了`loadData`时有效) | boolean | - | |
|
||||
| key | 被树的 (default)ExpandedKeys / (default)CheckedKeys / (default)SelectedKeys 属性所用。注意:整个树范围内的所有节点的 key 值不能重复! | string \| number | 内部计算出的节点位置 | |
|
||||
| selectable | 设置节点是否可被选中 | boolean | true | |
|
||||
| style | 节点的 style | string\|object | - | |
|
||||
|
|
|
|||
|
|
@ -72,11 +72,11 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*LT2jR41Uj2EAAA
|
|||
| --- | --- | --- | --- | --- |
|
||||
| copyableIcon | 自定义拷贝图标 | `{ copied: boolean }` | `copied ? <CheckOutlined /> : <CopyOutlined />` | |
|
||||
| copyableTooltip | 自定义提示文案,当 `copyable.tooltip = false` 时关闭 | `{ copied: boolean }` | `copied ? '复制成功' : '复制'` | |
|
||||
| editableEnterIcon | 在编辑段中自定义“enter”图标 | `{className: string}` | `<EnterOutlined />` | 3.0 |
|
||||
| editableIcon | 自定义编辑图标 | - | <EditOutlined /> | |
|
||||
| editableTooltip | 自定义提示文本,当 `editable.tooltip = false` 时关闭 | - | `编辑` | |
|
||||
| ellipsisSymbol | 自定义展开描述文案 | - | - | |
|
||||
| ellipsisTooltip | 省略时,展示提示信息 | - | - | |
|
||||
| enterEnterIcon | 在编辑段中自定义“enter”图标 | `{className: string}` | `<EnterOutlined />` | 3.0 |
|
||||
|
||||
### copyable
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { getTransitionProps } from '../_util/transition';
|
|||
import dialogPropTypes from './IDialogPropTypes';
|
||||
import { offset } from './util';
|
||||
const sentinelStyle = { width: 0, height: 0, overflow: 'hidden', outline: 'none' };
|
||||
|
||||
const entityStyle = { outline: 'none' };
|
||||
export type ContentRef = {
|
||||
focus: () => void;
|
||||
changeActive: (next: boolean) => void;
|
||||
|
|
@ -28,14 +28,14 @@ export default defineComponent({
|
|||
const dialogRef = ref<HTMLDivElement>();
|
||||
expose({
|
||||
focus: () => {
|
||||
sentinelStartRef.value?.focus();
|
||||
sentinelStartRef.value?.focus({ preventScroll: true });
|
||||
},
|
||||
changeActive: next => {
|
||||
const { activeElement } = document;
|
||||
if (next && activeElement === sentinelEndRef.value) {
|
||||
sentinelStartRef.value.focus();
|
||||
sentinelStartRef.value.focus({ preventScroll: true });
|
||||
} else if (!next && activeElement === sentinelStartRef.value) {
|
||||
sentinelEndRef.value.focus();
|
||||
sentinelEndRef.value.focus({ preventScroll: true });
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
@ -143,9 +143,10 @@ export default defineComponent({
|
|||
onMousedown={onMousedown}
|
||||
onMouseup={onMouseup}
|
||||
>
|
||||
<div tabindex={0} ref={sentinelStartRef} style={sentinelStyle} aria-hidden="true" />
|
||||
{modalRender ? modalRender({ originVNode: content }) : content}
|
||||
<div tabindex={0} ref={sentinelEndRef} style={sentinelStyle} aria-hidden="true" />
|
||||
<div tabindex={0} ref={sentinelStartRef} style={entityStyle}>
|
||||
{modalRender ? modalRender({ originVNode: content }) : content}
|
||||
</div>
|
||||
<div tabindex={0} ref={sentinelEndRef} style={sentinelStyle} />
|
||||
</div>
|
||||
) : null}
|
||||
</Transition>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { ImgHTMLAttributes, CSSProperties, PropType } from 'vue';
|
||||
import type { CSSProperties, PropType } from 'vue';
|
||||
import { ref, watch, defineComponent, computed, onMounted, onUnmounted } from 'vue';
|
||||
import isNumber from 'lodash-es/isNumber';
|
||||
import cn from '../../_util/classNames';
|
||||
|
|
@ -32,6 +32,8 @@ export const imageProps = () => ({
|
|||
rootClassName: String,
|
||||
prefixCls: String,
|
||||
previewPrefixCls: String,
|
||||
width: [Number, String],
|
||||
height: [Number, String],
|
||||
previewMask: {
|
||||
type: [Boolean, Function] as PropType<false | (() => any)>,
|
||||
default: undefined,
|
||||
|
|
@ -201,8 +203,6 @@ const ImageInternal = defineComponent({
|
|||
placeholder,
|
||||
wrapperStyle,
|
||||
rootClassName,
|
||||
} = props;
|
||||
const {
|
||||
width,
|
||||
height,
|
||||
crossorigin,
|
||||
|
|
@ -213,7 +213,7 @@ const ImageInternal = defineComponent({
|
|||
usemap,
|
||||
class: cls,
|
||||
style,
|
||||
} = attrs as ImgHTMLAttributes;
|
||||
} = { ...props, ...attrs } as any;
|
||||
const { icons, maskClassName, ...dialogProps } = preview.value;
|
||||
|
||||
const wrappperClass = cn(prefixCls, wrapperClassName, rootClassName, {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { getTransitionGroupProps } from '../_util/transition';
|
|||
import type { Key, VueNode } from '../_util/type';
|
||||
import type { CSSProperties } from 'vue';
|
||||
import {
|
||||
toRaw,
|
||||
shallowRef,
|
||||
createVNode,
|
||||
computed,
|
||||
|
|
@ -72,10 +73,10 @@ type NotificationState = {
|
|||
holderCallback?: HolderReadyCallback;
|
||||
}[];
|
||||
|
||||
const Notification = defineComponent<NotificationProps>({
|
||||
const Notification = defineComponent({
|
||||
name: 'Notification',
|
||||
inheritAttrs: false,
|
||||
props: ['prefixCls', 'transitionName', 'animation', 'maxCount', 'closeIcon', 'hashId'] as any,
|
||||
props: ['prefixCls', 'transitionName', 'animation', 'maxCount', 'closeIcon', 'hashId'],
|
||||
setup(props, { attrs, expose, slots }) {
|
||||
const hookRefs = new Map<Key, HTMLDivElement>();
|
||||
const notices = ref<NotificationState>([]);
|
||||
|
|
@ -125,7 +126,7 @@ const Notification = defineComponent<NotificationProps>({
|
|||
};
|
||||
|
||||
const remove = (removeKey: Key) => {
|
||||
notices.value = notices.value.filter(({ notice: { key, userPassKey } }) => {
|
||||
notices.value = toRaw(notices.value as any).filter(({ notice: { key, userPassKey } }) => {
|
||||
const mergedKey = userPassKey || key;
|
||||
return mergedKey !== removeKey;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -39,14 +39,15 @@ const overflowProps = () => {
|
|||
/** When set to `full`, ssr will render full items by default and remove at client side */
|
||||
ssr: String as PropType<'full'>,
|
||||
onMousedown: Function as PropType<MouseEventHandler>,
|
||||
role: String,
|
||||
};
|
||||
};
|
||||
type InterOverflowProps = Partial<ExtractPropTypes<ReturnType<typeof overflowProps>>>;
|
||||
export type OverflowProps = HTMLAttributes & InterOverflowProps;
|
||||
const Overflow = defineComponent<OverflowProps>({
|
||||
const Overflow = defineComponent({
|
||||
name: 'Overflow',
|
||||
inheritAttrs: false,
|
||||
props: overflowProps() as any,
|
||||
props: overflowProps(),
|
||||
emits: ['visibleChange'],
|
||||
setup(props, { attrs, emit, slots }) {
|
||||
const fullySSR = computed(() => props.ssr === 'full');
|
||||
|
|
@ -331,6 +332,7 @@ const Overflow = defineComponent<OverflowProps>({
|
|||
class={classNames(!invalidate.value && prefixCls, className)}
|
||||
style={style}
|
||||
onMousedown={onMousedown}
|
||||
role={props.role}
|
||||
{...restAttrs}
|
||||
>
|
||||
{mergedData.value.map(internalRenderItemNode)}
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ export type TimeUnitColumnProps = {
|
|||
onSelect?: (value: number) => void;
|
||||
};
|
||||
|
||||
export default defineComponent<TimeUnitColumnProps>({
|
||||
export default defineComponent({
|
||||
name: 'TimeUnitColumn',
|
||||
props: ['prefixCls', 'units', 'onSelect', 'value', 'active', 'hideDisabledOptions'] as any,
|
||||
props: ['prefixCls', 'units', 'onSelect', 'value', 'active', 'hideDisabledOptions'],
|
||||
setup(props) {
|
||||
const { open } = useInjectPanel();
|
||||
|
||||
|
|
|
|||
|
|
@ -343,6 +343,14 @@ export default defineComponent({
|
|||
if (mergedOpen.value !== nextOpen && !props.disabled) {
|
||||
setInnerOpen(nextOpen);
|
||||
props.onDropdownVisibleChange && props.onDropdownVisibleChange(nextOpen);
|
||||
|
||||
if (!nextOpen && popupFocused.value) {
|
||||
popupFocused.value = false;
|
||||
setMockFocused(false, () => {
|
||||
focusRef.value = false;
|
||||
blurRef.value = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -832,6 +840,7 @@ export default defineComponent({
|
|||
customizeRawInputElement,
|
||||
{
|
||||
ref: selectorDomRef,
|
||||
tabindex: 0,
|
||||
},
|
||||
false,
|
||||
true,
|
||||
|
|
@ -869,7 +878,11 @@ export default defineComponent({
|
|||
|
||||
// Render raw
|
||||
if (customizeRawInputElement) {
|
||||
renderNode = selectorNode;
|
||||
renderNode = (
|
||||
<div onKeydown={onInternalKeyDown} onKeyup={onInternalKeyUp}>
|
||||
{selectorNode}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
renderNode = (
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ const SelectSelector = defineComponent<SelectorProps>({
|
|||
) {
|
||||
const onMouseDown = (e: MouseEvent) => {
|
||||
onPreventMouseDown(e);
|
||||
props.onToggleOpen(!open);
|
||||
props.onToggleOpen(!props.open);
|
||||
};
|
||||
let originData = option;
|
||||
// For TreeSelect
|
||||
|
|
|
|||
|
|
@ -2,11 +2,13 @@ import type { BaseOptionType, DefaultOptionType, RawValueType, FieldNames } from
|
|||
import { warning } from '../../vc-util/warning';
|
||||
import type { FlattenOptionData } from '../interface';
|
||||
|
||||
function getKey(data: BaseOptionType, index: number) {
|
||||
function getKey(data: BaseOptionType, index: number, fieldNames?: FieldNames) {
|
||||
const { key } = data;
|
||||
let value: RawValueType;
|
||||
|
||||
if ('value' in data) {
|
||||
if (fieldNames && fieldNames.value && data[fieldNames.value] !== undefined) {
|
||||
({ [fieldNames.value]: value } = data);
|
||||
} else if ('value' in data) {
|
||||
({ value } = data);
|
||||
}
|
||||
|
||||
|
|
@ -54,7 +56,7 @@ export function flattenOptions<OptionType extends BaseOptionType = DefaultOption
|
|||
const value = data[fieldValue];
|
||||
// Option
|
||||
flattenList.push({
|
||||
key: getKey(data, flattenList.length),
|
||||
key: getKey(data, flattenList.length, fieldNames),
|
||||
groupOption: isGroupOption,
|
||||
data,
|
||||
label,
|
||||
|
|
@ -67,7 +69,7 @@ export function flattenOptions<OptionType extends BaseOptionType = DefaultOption
|
|||
}
|
||||
// Option Group
|
||||
flattenList.push({
|
||||
key: getKey(data, flattenList.length),
|
||||
key: getKey(data, flattenList.length, fieldNames),
|
||||
group: true,
|
||||
data,
|
||||
label: grpLabel,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ const Track = (_, { attrs }) => {
|
|||
length = Math.abs(length);
|
||||
offset = 100 - offset;
|
||||
}
|
||||
const positonStyle = vertical
|
||||
const positionStyle = vertical
|
||||
? {
|
||||
[reverse ? 'top' : 'bottom']: `${offset}%`,
|
||||
[reverse ? 'bottom' : 'top']: 'auto',
|
||||
|
|
@ -21,7 +21,7 @@ const Track = (_, { attrs }) => {
|
|||
|
||||
const elStyle = {
|
||||
...style,
|
||||
...positonStyle,
|
||||
...positionStyle,
|
||||
};
|
||||
return included ? <div class={className} style={elStyle} /> : null;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ export interface CellProps<RecordType = DefaultRecordType> {
|
|||
|
||||
transformCellText?: TransformCellText<RecordType>;
|
||||
}
|
||||
export default defineComponent<CellProps>({
|
||||
export default defineComponent({
|
||||
name: 'Cell',
|
||||
props: [
|
||||
'prefixCls',
|
||||
|
|
@ -104,7 +104,7 @@ export default defineComponent<CellProps>({
|
|||
'column',
|
||||
'cellType',
|
||||
'transformCellText',
|
||||
] as any,
|
||||
],
|
||||
setup(props, { slots }) {
|
||||
const contextSlots = useInjectSlots();
|
||||
const { onHover, startRow, endRow } = useInjectHover();
|
||||
|
|
@ -318,7 +318,7 @@ export default defineComponent<CellProps>({
|
|||
|
||||
// ====================== Render ======================
|
||||
let title: string;
|
||||
const ellipsisConfig: CellEllipsisType = ellipsis === true ? { showTitle: true } : ellipsis;
|
||||
const ellipsisConfig = ellipsis === true ? { showTitle: true } : ellipsis;
|
||||
if (ellipsisConfig && (ellipsisConfig.showTitle || rowType === 'header')) {
|
||||
if (typeof childNode === 'string' || typeof childNode === 'number') {
|
||||
title = childNode.toString();
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ export interface SummaryCellProps {
|
|||
align?: AlignType;
|
||||
}
|
||||
|
||||
export default defineComponent<SummaryCellProps>({
|
||||
export default defineComponent({
|
||||
name: 'ATableSummaryCell',
|
||||
props: ['index', 'colSpan', 'rowSpan', 'align'] as any,
|
||||
props: ['index', 'colSpan', 'rowSpan', 'align'],
|
||||
setup(props, { attrs, slots }) {
|
||||
const tableContext = useInjectTable();
|
||||
const summaryContext = useInjectSummary();
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ export interface TableProps<RecordType = DefaultRecordType> {
|
|||
transformCellText?: TransformCellText<RecordType>;
|
||||
}
|
||||
|
||||
export default defineComponent<TableProps<DefaultRecordType>>({
|
||||
export default defineComponent({
|
||||
name: 'VcTable',
|
||||
inheritAttrs: false,
|
||||
props: [
|
||||
|
|
@ -191,7 +191,7 @@ export default defineComponent<TableProps<DefaultRecordType>>({
|
|||
'canExpandable',
|
||||
'onUpdateInternalRefs',
|
||||
'transformCellText',
|
||||
] as any,
|
||||
],
|
||||
emits: ['expand', 'expandedRowsChange', 'updateInternalRefs', 'update:expandedRowKeys'],
|
||||
setup(props, { attrs, slots, emit }) {
|
||||
const mergedData = computed(() => props.data || EMPTY_DATA);
|
||||
|
|
@ -271,7 +271,7 @@ export default defineComponent<TableProps<DefaultRecordType>>({
|
|||
// defalutXxxx 仅仅第一次生效
|
||||
stop();
|
||||
|
||||
const mergedExpandedKeys = computed(
|
||||
const mergedExpandedKeys = computed<Set<Key>>(
|
||||
() => new Set(props.expandedRowKeys || innerExpandedKeys.value || []),
|
||||
);
|
||||
|
||||
|
|
@ -282,9 +282,9 @@ export default defineComponent<TableProps<DefaultRecordType>>({
|
|||
const hasKey = mergedExpandedKeys.value.has(key);
|
||||
if (hasKey) {
|
||||
mergedExpandedKeys.value.delete(key);
|
||||
newExpandedKeys = [...mergedExpandedKeys.value];
|
||||
newExpandedKeys = [...(mergedExpandedKeys.value as any)];
|
||||
} else {
|
||||
newExpandedKeys = [...mergedExpandedKeys.value, key];
|
||||
newExpandedKeys = [...(mergedExpandedKeys.value as any), key];
|
||||
}
|
||||
innerExpandedKeys.value = newExpandedKeys;
|
||||
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ function useColumns<RecordType>(
|
|||
prefixCls?: Ref<string>;
|
||||
columns?: Ref<ColumnsType<RecordType>>;
|
||||
expandable: Ref<boolean>;
|
||||
expandedKeys: Ref<Set<Key>>;
|
||||
expandedKeys: ComputedRef<Set<Key>>;
|
||||
getRowKey: Ref<GetRowKey<RecordType>>;
|
||||
onTriggerExpand: TriggerEventHandler<RecordType>;
|
||||
expandIcon?: Ref<RenderExpandIcon<RecordType>>;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ export default function Mask(props: MaskProps) {
|
|||
|
||||
return (
|
||||
<Transition appear {...motion}>
|
||||
<div v-if={visible} style={{ zIndex }} class={`${prefixCls}-mask`} />
|
||||
<div v-show={visible} style={{ zIndex }} class={`${prefixCls}-mask`} />
|
||||
</Transition>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ export default defineComponent({
|
|||
ref={alignRef}
|
||||
monitorWindowResize
|
||||
disabled={alignDisabled.value}
|
||||
align={align}
|
||||
align={align as any}
|
||||
onAlign={onInternalAlign}
|
||||
v-slots={{
|
||||
default: () => (
|
||||
|
|
@ -204,11 +204,11 @@ export default defineComponent({
|
|||
class={mergedClassName}
|
||||
onMouseenter={onMouseenter}
|
||||
onMouseleave={onMouseleave}
|
||||
onMousedown={withModifiers(onMousedown, ['capture'])}
|
||||
onMousedown={withModifiers(onMousedown, ['capture'] as any)}
|
||||
{...{
|
||||
[supportsPassive ? 'onTouchstartPassive' : 'onTouchstart']: withModifiers(
|
||||
onTouchstart,
|
||||
['capture'],
|
||||
['capture'] as any,
|
||||
),
|
||||
}}
|
||||
style={mergedStyle}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "ant-design-vue",
|
||||
"version": "4.2.3",
|
||||
"version": "4.2.6",
|
||||
"title": "Ant Design Vue",
|
||||
"description": "An enterprise-class UI design language and Vue-based implementation",
|
||||
"keywords": [
|
||||
|
|
@ -36,7 +36,7 @@
|
|||
"precompile": "npm run version & npm run collect-token-statistic & npm run token-meta",
|
||||
"pretest": "npm run version",
|
||||
"predist": "npm run version",
|
||||
"presite": "npm run version & npm run routes & npm run collect-token-statistic & npm run token-meta",
|
||||
"prebuild": "npm run version & npm run routes & npm run collect-token-statistic & npm run token-meta",
|
||||
"dev": "npm run routes && vite serve site",
|
||||
"fast-dev": "npm run routes && vite serve site",
|
||||
"test": "cross-env NODE_ENV=test jest --config .jest.js",
|
||||
|
|
@ -60,7 +60,7 @@
|
|||
"routes": "node site/scripts/genrateRoutes.js",
|
||||
"tsc": "tsc --noEmit",
|
||||
"vue-tsc": "vue-tsc --noEmit",
|
||||
"site": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build site --base=https://next.antdv.com/",
|
||||
"build": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build site --base=/",
|
||||
"pub:site": "npm run site && node site/scripts/pushToOSS.js",
|
||||
"prepare": "husky install",
|
||||
"version": "node ./scripts/generate-version",
|
||||
|
|
@ -148,7 +148,6 @@
|
|||
"babel-plugin-transform-require-context": "^0.1.1",
|
||||
"case-sensitive-paths-webpack-plugin": "^2.1.2",
|
||||
"chalk": "^4.1.1",
|
||||
"cheerio": "^1.0.0-rc.2",
|
||||
"codecov": "^3.0.0",
|
||||
"codesandbox": "^2.2.3",
|
||||
"colorful": "^2.1.0",
|
||||
|
|
@ -262,7 +261,7 @@
|
|||
"vue-i18n": "^9.1.7",
|
||||
"vue-infinite-scroll": "^2.0.2",
|
||||
"vue-loader": "^17.0.0",
|
||||
"vue-request": "^1.0.2",
|
||||
"vue-request": "^2.0.4",
|
||||
"vue-router": "^4.0.0",
|
||||
"vue-style-loader": "^4.1.2",
|
||||
"vue-tsc": "^1.0.6",
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
content="An enterprise-class UI components based on Ant Design and Vue"
|
||||
/>
|
||||
<title>Ant Design Vue</title>
|
||||
<link rel="icon" type="image/x-icon" href="//aliyuncdn.antdv.com/favicon.ico" />
|
||||
<link rel="icon" type="image/x-icon" href="//www.antdv.com/favicon.ico" />
|
||||
<style id="nprogress-style">
|
||||
#page-404 {
|
||||
background-image: url('https://os.alipayobjects.com/rmsportal/NOAjOBbnYCrNzrW.jpg');
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
name="keywords"
|
||||
content="ant design vue,ant-design-vue,ant-design-vue admin,ant design pro,vue ant design,vue ant design pro,vue ant design admin,ant design vue官网,ant design vue中文文档,ant design vue文档"
|
||||
/>
|
||||
<link rel="shortcut icon" type="image/x-icon" href="//aliyuncdn.antdv.com/favicon.ico" />
|
||||
<link rel="shortcut icon" type="image/x-icon" href="//www.antdv.com/favicon.ico" />
|
||||
<style id="nprogress-style">
|
||||
#nprogress {
|
||||
display: none;
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script src="https://aliyuncdn.antdv.com/common/docsearch.min_2.6.3.js"></script>
|
||||
<script src="https://www.antdv.com/docsearch.min_2.6.3.js"></script>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-151755889-1"></script>
|
||||
|
|
@ -59,23 +59,5 @@
|
|||
gtag('config', 'UA-151755889-1');
|
||||
</script>
|
||||
<script type="text/javascript" src="https://cdn.wwads.cn/js/makemoney.js" async></script>
|
||||
<!-- <div
|
||||
class="surveybyantdv"
|
||||
data-sf-id="63ad5912f3e10066"
|
||||
data-sf-mode="popover"
|
||||
data-sf-button-color="#3a3939"
|
||||
data-sf-text-color="#ffffff"
|
||||
data-sf-button-radius="50"
|
||||
data-sf-button-icon="form-outlined"
|
||||
data-sf-default-open="false"
|
||||
data-sf-allow-repeat-submit="true"
|
||||
data-sf-close-after-submit="false"
|
||||
data-sf-hide-after-submit="false"
|
||||
data-sf-delay-visible="false"
|
||||
data-sf-preload="true"
|
||||
data-sf-width="368px"
|
||||
data-sf-height="407px"
|
||||
></div>
|
||||
<script async src="https://aliyuncdn.antdv.com/form/static/embed/runtime.js"></script> -->
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 172 KiB |
|
After Width: | Height: | Size: 7.3 KiB |
|
After Width: | Height: | Size: 155 KiB |
|
|
@ -0,0 +1,31 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="280" viewBox="0 0 1200 280">
|
||||
<defs>
|
||||
<linearGradient id="g" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0%" stop-color="#0B1021" />
|
||||
<stop offset="100%" stop-color="#182A4A" />
|
||||
</linearGradient>
|
||||
<pattern id="dots" width="28" height="28" patternUnits="userSpaceOnUse">
|
||||
<circle cx="2" cy="2" r="2" fill="#7FB3FF" opacity="0.12"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
|
||||
<!-- background -->
|
||||
<rect width="1200" height="280" fill="url(#g)"/>
|
||||
<rect width="1200" height="280" fill="url(#dots)"/>
|
||||
|
||||
<!-- decorative braces -->
|
||||
<text x="80" y="140.0" text-anchor="start" font-size="140" font-family="monospace" fill="#5DF2A3" opacity="0.08">{</text>
|
||||
<text x="1120" y="140.0" text-anchor="end" font-size="140" font-family="monospace" fill="#5DF2A3" opacity="0.08">}</text>
|
||||
|
||||
<!-- brand name -->
|
||||
<text x="600.0" y="120.0" text-anchor="middle"
|
||||
font-family="Inter, system-ui" font-weight="800" font-size="72" fill="#5DF2A3">Mentorbook.AI</text>
|
||||
|
||||
<!-- main slogan -->
|
||||
<text x="600.0" y="175.0" text-anchor="middle"
|
||||
font-family="Inter, system-ui" font-weight="700" font-size="42" fill="#EAF2FF">Your AI Mentor, Your Learning Journey</text>
|
||||
|
||||
<!-- value props -->
|
||||
<text x="600.0" y="225.0" text-anchor="middle"
|
||||
font-family="Inter, system-ui" font-weight="500" font-size="24" fill="#7FB3FF">✨ Personalized Courses · Instant Feedback · 100+ Subjects</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
|
|
@ -0,0 +1,33 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="280" viewBox="0 0 1200 280">
|
||||
<defs>
|
||||
<linearGradient id="g" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0%" stop-color="#0B1021" />
|
||||
<stop offset="100%" stop-color="#182A4A" />
|
||||
</linearGradient>
|
||||
<pattern id="dots" width="28" height="28" patternUnits="userSpaceOnUse">
|
||||
<circle cx="2" cy="2" r="2" fill="#7FB3FF" opacity="0.12" />
|
||||
</pattern>
|
||||
</defs>
|
||||
|
||||
<!-- background -->
|
||||
<rect width="1200" height="280" fill="url(#g)" />
|
||||
<rect width="1200" height="280" fill="url(#dots)" />
|
||||
|
||||
<!-- decorative braces -->
|
||||
<text x="80" y="140.0" text-anchor="start" font-size="140" font-family="monospace" fill="#5DF2A3"
|
||||
opacity="0.08">{</text>
|
||||
<text x="1120" y="140.0" text-anchor="end" font-size="140" font-family="monospace" fill="#5DF2A3"
|
||||
opacity="0.08">}</text>
|
||||
|
||||
<!-- brand name -->
|
||||
<text x="600.0" y="120.0" text-anchor="middle" font-family="Inter, system-ui" font-weight="800" font-size="72"
|
||||
fill="#5DF2A3">Mentorbook.AI</text>
|
||||
|
||||
<!-- main slogan -->
|
||||
<text x="600.0" y="175.0" text-anchor="middle" font-family="Inter, system-ui" font-weight="700" font-size="42"
|
||||
fill="#EAF2FF">你的 AI 导师,你的学习助手</text>
|
||||
|
||||
<!-- value props -->
|
||||
<text x="600.0" y="225.0" text-anchor="middle" font-family="Inter, system-ui" font-weight="500" font-size="24"
|
||||
fill="#7FB3FF">✨ 个性化课程 · 即时反馈 · 100+ 学科领域</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, provide, watch, ref } from 'vue';
|
||||
import type { Ref } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import useMediaQuery from './hooks/useMediaQuery';
|
||||
|
|
@ -21,16 +20,11 @@ import dayjs from 'dayjs';
|
|||
import 'dayjs/locale/zh-cn';
|
||||
import { theme as antdTheme } from 'ant-design-vue';
|
||||
import SiteToken from './SiteToken.vue';
|
||||
import type { GlobalConfig } from './type';
|
||||
function isZhCN(name: string) {
|
||||
return /-cn\/?$/.test(name);
|
||||
}
|
||||
export interface GlobalConfig {
|
||||
isMobile: Ref<boolean>;
|
||||
lang: Ref<'zh-CN' | 'en-US'>;
|
||||
isZhCN: Ref<boolean>;
|
||||
responsive: Ref<null | 'narrow' | 'crowded'>;
|
||||
blocked: Ref<boolean>;
|
||||
}
|
||||
|
||||
export type ThemeName = '' | 'light' | 'dark' | 'compact';
|
||||
const getAlgorithm = (themes: ThemeName[] = []) =>
|
||||
themes
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import type { GlobalConfig } from '../App.vue';
|
||||
import type { GlobalConfig } from '../type';
|
||||
import { GLOBAL_CONFIG } from '../SymbolKey';
|
||||
import { computed, defineComponent, inject, onMounted, ref } from 'vue';
|
||||
import { CheckOutlined, SnippetsOutlined, CodeSandboxOutlined } from '@ant-design/icons-vue';
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@ import type { InputProps } from 'ant-design-vue';
|
|||
import { ConfigProvider, Input, InputNumber, Select, theme } from 'ant-design-vue';
|
||||
import classNames from 'ant-design-vue/es/_util/classNames';
|
||||
import type { PropType } from 'vue';
|
||||
import { defineComponent, watchEffect, watch, computed, toRefs, ref } from 'vue';
|
||||
import { defineComponent, watchEffect, computed, toRefs, ref } from 'vue';
|
||||
import { HexColorPicker, RgbaColorPicker } from '../vue-colorful';
|
||||
import tinycolor from 'tinycolor2';
|
||||
import makeStyle from './utils/makeStyle';
|
||||
import type { ValueType } from 'ant-design-vue/es/input-number/src/utils/MiniDecimal';
|
||||
|
||||
const { useToken } = theme;
|
||||
|
||||
|
|
@ -168,24 +169,42 @@ const RgbColorInput = defineComponent({
|
|||
setup(props) {
|
||||
const { value, alpha } = toRefs(props);
|
||||
|
||||
watch(value, val => {
|
||||
props.onChange(val);
|
||||
});
|
||||
|
||||
const handleChange = (val: ValueType, key: 'r' | 'g' | 'b' | 'a') => {
|
||||
value.value[key] = val;
|
||||
props.onChange(value.value);
|
||||
};
|
||||
return () => {
|
||||
return (
|
||||
<div class="color-panel-rgba-input">
|
||||
<ConfigProvider theme={{ components: { InputNumber: { handleWidth: 12 } } }}>
|
||||
<div class="color-panel-rgba-input-part">
|
||||
<InputNumber min={0} max={255} size="small" v-model={[value.value.r, 'value']} />
|
||||
<InputNumber
|
||||
min={0}
|
||||
max={255}
|
||||
size="small"
|
||||
value={value.value.r}
|
||||
onChange={val => handleChange(val, 'r')}
|
||||
/>
|
||||
<div class="color-panel-mode-title">R</div>
|
||||
</div>
|
||||
<div class="color-panel-rgba-input-part">
|
||||
<InputNumber min={0} max={255} size="small" v-model={[value.value.g, 'value']} />
|
||||
<InputNumber
|
||||
min={0}
|
||||
max={255}
|
||||
size="small"
|
||||
value={value.value.g}
|
||||
onChange={val => handleChange(val, 'g')}
|
||||
/>
|
||||
<div class="color-panel-mode-title">G</div>
|
||||
</div>
|
||||
<div class="color-panel-rgba-input-part">
|
||||
<InputNumber min={0} max={255} size="small" v-model={[value.value.b, 'value']} />
|
||||
<InputNumber
|
||||
min={0}
|
||||
max={255}
|
||||
size="small"
|
||||
value={value.value.b}
|
||||
onChange={val => handleChange(val, 'b')}
|
||||
/>
|
||||
<div class="color-panel-mode-title">B</div>
|
||||
</div>
|
||||
{alpha.value && (
|
||||
|
|
@ -195,7 +214,8 @@ const RgbColorInput = defineComponent({
|
|||
max={1}
|
||||
step={0.01}
|
||||
size="small"
|
||||
v-model={[value.value.a, 'value']}
|
||||
value={value.value.a}
|
||||
onChange={val => handleChange(val, 'a')}
|
||||
/>
|
||||
<div class="color-panel-mode-title">A</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,45 +0,0 @@
|
|||
<template>
|
||||
<div v-show="visible" id="geektime">
|
||||
<a
|
||||
href="https://time.geekbang.org/course/intro/100024601?code=KHKYcoBU6vZa8nMglg7AWfDxxi3BWrz9INAzAY3umPk%3D"
|
||||
target="_blank"
|
||||
>
|
||||
<img width="150" alt="Vue 实战教程" src="https://aliyuncdn.antdv.com/geektime-vue.jpeg" />
|
||||
</a>
|
||||
<div class="close" @click="visible = false">
|
||||
<close-outlined />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { CloseOutlined } from '@ant-design/icons-vue';
|
||||
export default {
|
||||
components: {
|
||||
CloseOutlined,
|
||||
},
|
||||
props: ['isMobile'],
|
||||
data() {
|
||||
return {
|
||||
visible: true,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
#geektime {
|
||||
position: fixed;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
.close {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
top: -8px;
|
||||
right: -8px;
|
||||
font-size: 16px;
|
||||
padding: 15px;
|
||||
color: #6e3041;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
<template>
|
||||
<div
|
||||
v-if="isEffective(effectiveTime)"
|
||||
id="geektime-ads"
|
||||
:class="isMobile ? 'geektime-ads-mobile' : ''"
|
||||
>
|
||||
<a
|
||||
href="https://time.geekbang.org/column/intro/154?utm_term=zeusGZFFE&utm_source=app&utm_medium=tangjinzhou"
|
||||
target="_blank"
|
||||
>
|
||||
<img height="100" alt="重学前端" src="https://aliyuncdn.antdv.com/chongxueqianduan.jpg" />
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import dayjs from 'dayjs';
|
||||
import isBetween from 'dayjs/plugin/isBetween';
|
||||
import { defineComponent } from 'vue';
|
||||
dayjs.extend(isBetween);
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
isMobile: Boolean,
|
||||
},
|
||||
setup() {
|
||||
return {
|
||||
visible: true,
|
||||
effectiveTime: {
|
||||
start: '2019-08-05 17:00:00',
|
||||
end: '2019-09-05 17:00:00',
|
||||
},
|
||||
isEffective({ start, end }) {
|
||||
return dayjs().isBetween(start, end);
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
#geektime-ads {
|
||||
width: 266px;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
z-index: 9;
|
||||
background-color: #fff;
|
||||
border-radius: 3px;
|
||||
font-size: 13px;
|
||||
background: #f5f5f5;
|
||||
font-family: 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif;
|
||||
}
|
||||
#geektime-ads.geektime-ads-mobile {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 0;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -26,20 +26,7 @@ export default {
|
|||
isEffective,
|
||||
visible: true,
|
||||
v: dayjs().date(),
|
||||
ads: [
|
||||
{
|
||||
alt: 'geektime',
|
||||
img: 'https://aliyuncdn.antdv.com/geektime-web-small.jpg',
|
||||
href: 'http://gk.link/a/10l8O',
|
||||
visible: isEffective('2020-09-03 10:00:00', '2020-10-04 10:00:00'),
|
||||
},
|
||||
{
|
||||
alt: 'powerproject',
|
||||
img: 'https://aliyuncdn.antdv.com/powerproject.jpeg?v=20200327',
|
||||
href: 'http://www.powerproject.com.cn',
|
||||
visible: isEffective('2020-03-27 17:00:00', '2020-09-28 17:00:00'),
|
||||
},
|
||||
],
|
||||
ads: [],
|
||||
};
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,11 +10,6 @@
|
|||
<img height="51" src="https://cdn.tipe.io/tipe/tipe-cat-no-text.svg" alt="tipe" />
|
||||
</a>
|
||||
</li> -->
|
||||
<li v-if="isCN && isEffective(effectiveTime.kkb)" class="sponsorsItem">
|
||||
<a href="https://datayi.cn/w/Y9J3M2vR" target="_blank">
|
||||
<img height="66" src="https://aliyuncdn.antdv.com/kaikeba_ssr.jpeg" alt="kaikeba" />
|
||||
</a>
|
||||
</li>
|
||||
<li class="sponsorsItem" style="padding: 10px 0">
|
||||
<a-button type="primary" ghost style="font-size: 12px" @click="handleClick">
|
||||
{{ isCN ? '成为赞助商' : 'Become a Sponsor' }}
|
||||
|
|
|
|||
|
|
@ -1,64 +1,241 @@
|
|||
<template>
|
||||
<div v-if="show">
|
||||
<template v-if="ads.length">
|
||||
<a-carousel autoplay>
|
||||
<template v-for="ad in ads" :key="ad.href">
|
||||
<a :href="ad.href" target="_blank">
|
||||
<img style="width: 100%; max-width: 1200px" :alt="ad.alt || ''" :src="ad.img" />
|
||||
</a>
|
||||
</template>
|
||||
</a-carousel>
|
||||
</template>
|
||||
<template v-else-if="showGoogleAd">
|
||||
<!-- <template v-if="isCN">
|
||||
<WWAds :key="`WWAds_${$route.path}`" />
|
||||
</template> -->
|
||||
<google-ads-top :key="`GoogleAdsTop_${$route.path}`" />
|
||||
</template>
|
||||
<div class="top-rice">
|
||||
<!-- Mentorbook banner -->
|
||||
<div v-if="showMentorbook" class="mentorbook-banner">
|
||||
<a href="https://mentorbook.ai/" target="_blank" class="banner-content">
|
||||
<div class="brand-name">Mentorbook.AI</div>
|
||||
<div class="main-slogan">
|
||||
{{ isCN ? '你的 AI 导师,你的学习助手' : 'Your AI Mentor, Your Learning Journey' }}
|
||||
</div>
|
||||
<div class="value-props">
|
||||
{{
|
||||
isCN
|
||||
? '✨ 个性化课程 · 即时反馈 · 100+ 学科领域'
|
||||
: '✨ Personalized Courses · Instant Feedback · 100+ Subjects'
|
||||
}}
|
||||
</div>
|
||||
</a>
|
||||
<a href="https://mentorbook.ai/" target="_blank" class="start-button">
|
||||
{{ isCN ? '免费开始' : 'Get Started Free' }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dayjs from 'dayjs';
|
||||
import isBetween from 'dayjs/plugin/isBetween';
|
||||
dayjs.extend(isBetween);
|
||||
import GoogleAdsTop from './GoogleAdsTop.vue';
|
||||
// import WWAds from './WWAds.vue';
|
||||
const isEffective = (start, end) => {
|
||||
return dayjs().isBetween(start, end);
|
||||
};
|
||||
export default {
|
||||
components: {
|
||||
GoogleAdsTop,
|
||||
// WWAds,
|
||||
},
|
||||
props: ['isCN', 'isMobile'],
|
||||
data() {
|
||||
return {
|
||||
show: true,
|
||||
showGoogleAd: location.host.indexOf('antdv.com') > -1,
|
||||
showMentorbook: true,
|
||||
cnAds: [
|
||||
{
|
||||
img: `https://yidengfe.com/launches/01/yd.png?v=${Date.now()}`,
|
||||
href: 'https://yidengfe.com/launches/01/yd.html',
|
||||
visible: isEffective('2020-09-11 17:00:00', '2021-03-11 17:00:00'),
|
||||
visible: true,
|
||||
},
|
||||
].filter(ad => ad.visible),
|
||||
enAds: [
|
||||
{
|
||||
img: 'https://aliyuncdn.antdv.com/TheBigRichGroup.png',
|
||||
href: 'https://thebigrichgroup.com/',
|
||||
visible: isEffective('2020-09-18 17:00:00', '2021-07-09 17:00:00'),
|
||||
img: `https://yidengfe.com/launches/01/yd.png?v=${Date.now()}`,
|
||||
href: 'https://yidengfe.com/launches/01/yd.html',
|
||||
visible: true,
|
||||
},
|
||||
].filter(ad => ad.visible),
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
ads() {
|
||||
otherAds() {
|
||||
return this.isCN ? this.cnAds : this.enAds;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
<style lang="less" scoped>
|
||||
.top-rice {
|
||||
width: 100%;
|
||||
margin-bottom: 16px;
|
||||
|
||||
.mentorbook-banner {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
background: linear-gradient(135deg, #0b1021 0%, #182a4a 100%);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
padding: 0 16px;
|
||||
height: 48px;
|
||||
box-sizing: border-box;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
// Dots pattern background
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-image: radial-gradient(circle, rgba(127, 179, 255, 0.12) 2px, transparent 2px);
|
||||
background-size: 28px 28px;
|
||||
background-position: 0 0;
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
// Left brace
|
||||
&::after {
|
||||
content: '{';
|
||||
position: absolute;
|
||||
left: 20px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
font-size: 32px;
|
||||
font-family: monospace;
|
||||
color: #5df2a3;
|
||||
opacity: 0.08;
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.banner-content {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
flex: 1;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
text-decoration: none;
|
||||
transition: opacity 0.3s;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
|
||||
.start-button {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 32px;
|
||||
padding: 0 16px;
|
||||
background: #5df2a3;
|
||||
color: #0b1021;
|
||||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
text-decoration: none;
|
||||
border-radius: 6px;
|
||||
white-space: nowrap;
|
||||
transition: all 0.3s;
|
||||
margin-left: 16px;
|
||||
|
||||
&:hover {
|
||||
background: #4dd893;
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px rgba(93, 242, 163, 0.3);
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
font-size: 12px;
|
||||
padding: 0 12px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
font-size: 11px;
|
||||
padding: 0 10px;
|
||||
height: 26px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.brand-name {
|
||||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 800;
|
||||
font-size: 20px;
|
||||
color: #5df2a3;
|
||||
line-height: 48px;
|
||||
white-space: nowrap;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.main-slogan {
|
||||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
color: #eaf2ff;
|
||||
line-height: 48px;
|
||||
white-space: nowrap;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.value-props {
|
||||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
color: #7fb3ff;
|
||||
line-height: 48px;
|
||||
white-space: nowrap;
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ad-link {
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-decoration: none;
|
||||
transition: opacity 0.3s;
|
||||
margin-top: 16px;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
|
||||
.ad-image {
|
||||
width: 100%;
|
||||
max-width: 1200px;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,25 +1,10 @@
|
|||
<template>
|
||||
<div class="container">
|
||||
<a-carousel autoplay>
|
||||
<a style="display: inline-block" href="https://form.antdv.com/" target="_blank">
|
||||
<a style="display: inline-block" href="https://www.surelyvue.com/" target="_blank">
|
||||
<div :class="cls">
|
||||
<div class="logo">
|
||||
<img height="80" src="https://aliyuncdn.antdv.com/form/static/logo-blue.png" alt="" />
|
||||
</div>
|
||||
<div class="desc">
|
||||
<!-- <div class="title">Surely Form</div> -->
|
||||
<div class="sub-title">
|
||||
<strong>雪梨表单、为您定制</strong>
|
||||
<br />
|
||||
专属的调研,投票、NPS、报名等系统
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<a style="display: inline-block" href="https://www.surely.cool/" target="_blank">
|
||||
<div :class="cls">
|
||||
<div class="logo">
|
||||
<img height="80" src="https://www.surely.cool/surely-vue-logo.png" alt="" />
|
||||
<img height="80" src="https://www.surelyvue.com/surely-vue-logo.png" alt="" />
|
||||
</div>
|
||||
<div class="desc">
|
||||
<div class="title">Surely Table</div>
|
||||
|
|
|
|||
|
|
@ -60,12 +60,9 @@
|
|||
</div>
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24" :xs="24">
|
||||
<!-- <a-col :md="6" :sm="24" :xs="24">
|
||||
<div class="footer-center">
|
||||
<h2>{{ isCN ? '友情链接' : 'Links' }}</h2>
|
||||
<div v-if="showJeecg">
|
||||
<a href="http://www.jeecg.com/" target="_blank">Jeecg</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://cn.vuejs.org/" target="_blank">Vue</a>
|
||||
</div>
|
||||
|
|
@ -79,8 +76,8 @@
|
|||
<a href="https://antdv.formilyjs.org/" target="_blank">@formily/antdv</a>
|
||||
</div>
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24" :xs="24">
|
||||
</a-col> -->
|
||||
<a-col :md="12" :sm="24" :xs="24">
|
||||
<div class="footer-center">
|
||||
<h2>
|
||||
<img
|
||||
|
|
@ -88,28 +85,17 @@
|
|||
class="title-icon"
|
||||
src="https://gw.alipayobjects.com/zos/rmsportal/nBVXkrFdWHxbZlmMbsaH.svg"
|
||||
/>
|
||||
<span>{{ isCN ? '更多产品' : 'More Products' }}</span>
|
||||
<span>{{ isCN ? '友情链接' : 'Links' }}</span>
|
||||
</h2>
|
||||
<div>
|
||||
<a href="https://antv.alipay.com/" rel="noopener noreferrer" target="_blank">AntV</a>
|
||||
<a href="https://www.demoget.com?atp=tangjinzhou" target="_blank">DemoGet</a>
|
||||
<span>-</span>
|
||||
<span>{{ isCN ? '数据可视化' : 'Data Visualization' }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://eggjs.org/" rel="noopener noreferrer" target="_blank">Egg</a>
|
||||
<span>-</span>
|
||||
<span>{{ isCN ? '企业级 Node 开发框架' : 'Enterprise Node Framework' }}</span>
|
||||
<span>{{ isCN ? '好看好用的录屏工具' : 'Beautiful Screen Recordings' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
<div style="padding: 10px 144px">
|
||||
备案号:
|
||||
<a href="https://beian.miit.gov.cn/#/Integrated/index" target="_blank">浙ICP备19034671号</a>
|
||||
增值电信业务经营许可证:
|
||||
<a href="https://beian.miit.gov.cn/#/Integrated/index" target="_blank">浙B2-20220161</a>
|
||||
</div>
|
||||
</footer>
|
||||
</template>
|
||||
<script>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
<a-menu-item-group v-if="isZhCN" key="advanced" title="高级组件">
|
||||
<a-menu-item key="surely-table">
|
||||
<a
|
||||
href="https://www.surely.cool"
|
||||
href="https://www.surelyvue.com"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
style="position: relative"
|
||||
|
|
@ -23,17 +23,6 @@
|
|||
Surely Table
|
||||
</a>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="surely-form">
|
||||
<a
|
||||
href="https://form.antdv.com"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
style="position: relative"
|
||||
>
|
||||
Surely Form
|
||||
<a-badge color="red" style="position: absolute; top: -18px; right: -15px" />
|
||||
</a>
|
||||
</a-menu-item>
|
||||
</a-menu-item-group>
|
||||
<template v-for="m in menus">
|
||||
<template v-if="m.children">
|
||||
|
|
|
|||
|
|
@ -23,19 +23,6 @@
|
|||
<a-menu-item key="awesome">
|
||||
<a target="_blank" href="https://github.com/vueComponent/ant-design-vue-awesome">Awesome</a>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="wechat">
|
||||
<a-popover placement="right">
|
||||
<a>{{ isZhCN ? '微信' : 'WeChat' }}</a>
|
||||
<template #content>
|
||||
<img
|
||||
width="160"
|
||||
height="160"
|
||||
alt="wechat"
|
||||
src="https://aliyuncdn.antdv.com/wechat.jpeg"
|
||||
/>
|
||||
</template>
|
||||
</a-popover>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="qq1">
|
||||
<a>QQ 1群(217490093) 已满</a>
|
||||
</a-menu-item>
|
||||
|
|
@ -50,7 +37,7 @@
|
|||
</template>
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, inject } from 'vue';
|
||||
import type { GlobalConfig } from '../../App.vue';
|
||||
import type { GlobalConfig } from '../../type';
|
||||
import { GLOBAL_CONFIG } from '../../SymbolKey';
|
||||
import { getLocalizedPathname } from '../../utils/util';
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import type { GlobalConfig } from '../../App.vue';
|
||||
import type { GlobalConfig } from '../../type';
|
||||
import { GLOBAL_CONFIG } from '../../SymbolKey';
|
||||
import { defineComponent, inject } from 'vue';
|
||||
import logo from '../../assets/logo.svg';
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
<script lang="ts">
|
||||
import { computed, defineComponent, inject } from 'vue';
|
||||
import { DownOutlined } from '@ant-design/icons-vue';
|
||||
import type { GlobalConfig } from '../../App.vue';
|
||||
import type { GlobalConfig } from '../../type';
|
||||
import { GLOBAL_CONFIG } from '../../SymbolKey';
|
||||
import { getLocalizedPathname } from '../../utils/util';
|
||||
import Ecosystem from './Ecosystem.vue';
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
</template>
|
||||
<a-menu-item key="surely-table">
|
||||
<a
|
||||
href="https://www.surely.cool"
|
||||
href="https://www.surelyvue.com"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
style="position: relative"
|
||||
|
|
@ -33,17 +33,6 @@
|
|||
Surely Table
|
||||
</a>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="surely-form">
|
||||
<a
|
||||
href="https://form.antdv.com"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
style="position: relative"
|
||||
>
|
||||
Surely Form
|
||||
<a-badge color="red" style="position: absolute; top: -18px; right: -15px" />
|
||||
</a>
|
||||
</a-menu-item>
|
||||
</a-sub-menu>
|
||||
<a-menu-item key="store">
|
||||
<a
|
||||
|
|
@ -84,7 +73,7 @@
|
|||
</a-menu>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import type { GlobalConfig } from '../../App.vue';
|
||||
import type { GlobalConfig } from '../../type';
|
||||
import { GLOBAL_CONFIG } from '../../SymbolKey';
|
||||
import { getLocalizedPathname } from '../../utils/util';
|
||||
import { computed, defineComponent, inject, ref, watch } from 'vue';
|
||||
|
|
|
|||
|
|
@ -1,25 +1,5 @@
|
|||
<template>
|
||||
<header id="header" :class="headerClassName">
|
||||
<!-- <div v-if="visibleAdblockBanner" class="adblock-banner">
|
||||
<template v-if="isZhCN">
|
||||
我们检测到你可能使用了 AdBlock 或 Adblock
|
||||
Plus,它会影响到正常功能的使用(如复制、展开代码等)。
|
||||
<br />
|
||||
你可以将 Ant Design Vue 加入白名单,以便我们更好地提供服务。
|
||||
</template>
|
||||
<template v-else>
|
||||
We have detected that you may use AdBlock or Adblock Plus, which will affect the use of
|
||||
normal functions (such as copying, expanding code, etc.)
|
||||
<br />
|
||||
You can add Ant Design Vue to the whitelist so that we can provide better services.
|
||||
</template>
|
||||
|
||||
<CloseOutlined class="close-icon" @click="visibleAdblockBanner = false" />
|
||||
</div> -->
|
||||
<div class="alert-banner">
|
||||
Surely Form AI 助手内测开放申请
|
||||
<a target="_blank" href="https://form.antdv.com">立即申请</a>
|
||||
</div>
|
||||
<a-row :style="{ flexFlow: 'nowrap', height: 64, position: 'relative' }">
|
||||
<a-col v-bind="colProps[0]">
|
||||
<Logo />
|
||||
|
|
@ -57,15 +37,10 @@
|
|||
<strong>Ant Design Vue 4</strong>
|
||||
:五大新组件,全新 Design Token
|
||||
</li>
|
||||
<li class="alert-list-item">
|
||||
<strong>Surely Form</strong>
|
||||
:全新主题编辑, AI 问卷开放内测申请
|
||||
<a target="_blank" href="https://form.antdv.com">立即体验</a>
|
||||
</li>
|
||||
<li class="alert-list-item">
|
||||
<strong>Surely Table</strong>
|
||||
:支持高性能编辑模式了
|
||||
<a target="_blank" href="https://www.surely.cool/">立即体验</a>
|
||||
<a target="_blank" href="https://www.surelyvue.com/">立即体验</a>
|
||||
</li>
|
||||
<li class="alert-list-item">
|
||||
<strong>Admin Pro</strong>
|
||||
|
|
@ -77,7 +52,7 @@
|
|||
</header>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import type { GlobalConfig } from '../../App.vue';
|
||||
import type { GlobalConfig } from '../../type';
|
||||
import { GLOBAL_CONFIG } from '../../SymbolKey';
|
||||
import { getLocalizedPathname } from '../../utils/util';
|
||||
import { computed, defineComponent, inject, onMounted, ref, watch } from 'vue';
|
||||
|
|
@ -86,7 +61,6 @@ import Logo from './Logo.vue';
|
|||
import Menu from './Menu.vue';
|
||||
import { UnorderedListOutlined } from '@ant-design/icons-vue';
|
||||
import SearchBox from './SearchBox.vue';
|
||||
import { version } from 'ant-design-vue';
|
||||
export default defineComponent({
|
||||
components: {
|
||||
Logo,
|
||||
|
|
@ -157,13 +131,13 @@ export default defineComponent({
|
|||
watch(globalConfig?.blocked, val => {
|
||||
visibleAdblockBanner.value = val;
|
||||
});
|
||||
const alertKey = 'ant-design-vue-4-alert';
|
||||
const visibleAlertBanner = ref(!localStorage.getItem(alertKey));
|
||||
watch(visibleAlertBanner, () => {
|
||||
if (!visibleAlertBanner.value) {
|
||||
localStorage.setItem(alertKey, version);
|
||||
}
|
||||
});
|
||||
// const alertKey = 'ant-design-vue-4-alert';
|
||||
const visibleAlertBanner = ref(false);
|
||||
// watch(visibleAlertBanner, () => {
|
||||
// if (!visibleAlertBanner.value) {
|
||||
// localStorage.setItem(alertKey, version);
|
||||
// }
|
||||
// });
|
||||
return {
|
||||
isZhCN: globalConfig.isZhCN,
|
||||
isMobile: globalConfig.isMobile,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
<template>
|
||||
<TopAd :is-c-n="isZhCN" />
|
||||
<Header />
|
||||
<div v-if="headers.length" class="toc-affix" :style="y > 102 ? 'position:fixed; top: 16px;' : ''">
|
||||
<a-anchor style="width: 160px" :items="headers">
|
||||
|
|
@ -43,8 +44,6 @@
|
|||
</template>
|
||||
<a-col :xxxl="20" :xxl="20" :xl="19" :lg="18" :md="18" :sm="24" :xs="24">
|
||||
<section :class="mainContainerClass">
|
||||
<WWAdsVue v-if="isZhCN" />
|
||||
<TopAd v-else />
|
||||
<Demo v-if="isDemo" :page-data="pageData" :is-zh-c-n="isZhCN">
|
||||
<component :is="matchCom" />
|
||||
</Demo>
|
||||
|
|
@ -85,22 +84,6 @@
|
|||
</template>
|
||||
</a-float-button>
|
||||
</a-float-button-group>
|
||||
<!-- <div class="fixed-widgets" :style="isZhCN ? { bottom: '175px' } : {}">
|
||||
<a-dropdown placement="top">
|
||||
<template #overlay>
|
||||
<a-menu
|
||||
:selected-keys="[themeMode.theme.value]"
|
||||
@click="({ key }) => themeMode.changeTheme(key)"
|
||||
>
|
||||
<a-menu-item key="default">{{ $t('app.theme.switch.default') }}</a-menu-item>
|
||||
<a-menu-item key="dark">{{ $t('app.theme.switch.dark') }}</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
<a-avatar class="fixed-widgets-avatar" :size="44">
|
||||
<template #icon><ThemeIcon /></template>
|
||||
</a-avatar>
|
||||
</a-dropdown>
|
||||
</div> -->
|
||||
<PrevAndNext :menus="menus" :current-menu-index="currentMenuIndex" :is-zh-c-n="isZhCN" />
|
||||
<Footer />
|
||||
</a-col>
|
||||
|
|
@ -108,7 +91,6 @@
|
|||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import type { GlobalConfig } from '../App.vue';
|
||||
import { GLOBAL_CONFIG } from '../SymbolKey';
|
||||
import { defineComponent, inject, computed, ref, provide, watch } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
|
@ -129,6 +111,7 @@ import CompactIcon from './icons/Compact';
|
|||
import surelyVueVue from '../components/surelyVue.vue';
|
||||
import WWAdsVue from '../components/rice/WWAds.vue';
|
||||
import { useWindowScroll } from '@vueuse/core';
|
||||
import type { GlobalConfig } from '../type';
|
||||
|
||||
const rControl = /[\u0000-\u001f]/g;
|
||||
const rSpecial = /[\s~`!@#$%^&*()\-_+=[\]{}|\\;:"'<>,.?/]+/g;
|
||||
|
|
@ -227,25 +210,25 @@ export default defineComponent({
|
|||
{
|
||||
title: '大数据渲染',
|
||||
enTitle: 'Virtualized Table',
|
||||
href: 'https://surely.cool/doc/performance',
|
||||
href: 'https://surelyvue.com/doc/performance',
|
||||
target: '_blank',
|
||||
},
|
||||
{
|
||||
title: '行拖拽排序',
|
||||
enTitle: 'Row Drag Sort',
|
||||
href: 'https://surely.cool/doc/dragable#drag-row',
|
||||
href: 'https://surelyvue.com/doc/dragable#drag-row',
|
||||
target: '_blank',
|
||||
},
|
||||
{
|
||||
title: '列拖拽排序',
|
||||
enTitle: 'Column Drag Sort',
|
||||
href: 'https://surely.cool/doc/dragable#drag-column',
|
||||
href: 'https://surelyvue.com/doc/dragable#drag-column',
|
||||
target: '_blank',
|
||||
},
|
||||
{
|
||||
title: '更多高性能示例',
|
||||
enTitle: 'More high-performance examples ',
|
||||
href: 'https://surely.cool',
|
||||
href: 'https://surelyvue.com',
|
||||
target: '_blank',
|
||||
},
|
||||
],
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ html {
|
|||
&.rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
import type { Ref } from 'vue';
|
||||
export interface GlobalConfig {
|
||||
isMobile: Ref<boolean>;
|
||||
lang: Ref<'zh-CN' | 'en-US'>;
|
||||
isZhCN: Ref<boolean>;
|
||||
responsive: Ref<null | 'narrow' | 'crowded'>;
|
||||
blocked: Ref<boolean>;
|
||||
}
|
||||
|
|
@ -74,7 +74,7 @@
|
|||
</section>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import type { GlobalConfig } from '../App.vue';
|
||||
import type { GlobalConfig } from '../type';
|
||||
import { computed, defineComponent, inject, onMounted, ref } from 'vue';
|
||||
import { SearchOutlined } from '@ant-design/icons-vue';
|
||||
import { GLOBAL_CONFIG } from '../SymbolKey';
|
||||
|
|
@ -107,24 +107,12 @@ export default defineComponent({
|
|||
cols: 1,
|
||||
cover: 'https://gw.alipayobjects.com/zos/alicdn/f-SbcX2Lx/Table.svg',
|
||||
coverDark: 'https://gw.alipayobjects.com/zos/alicdn/f-SbcX2Lx/Table.svg',
|
||||
path: 'https://surely.cool/',
|
||||
path: 'https://surelyvue.com/',
|
||||
subtitle: '更强大的表格',
|
||||
title: 'Surely Table',
|
||||
type: 'Advanced And Powerful',
|
||||
target: '_blank',
|
||||
},
|
||||
{
|
||||
category: 'Components',
|
||||
cols: 1,
|
||||
cover: 'https://aliyuncdn.antdv.com/form/static/assets/landing-config.4f9d5425.png',
|
||||
coverDark:
|
||||
'https://aliyuncdn.antdv.com/form/static/assets/landing-config.4f9d5425.png',
|
||||
path: 'https://form.antdv.com/',
|
||||
subtitle: '在线表单',
|
||||
title: 'Surely Form',
|
||||
type: 'Advanced And Powerful',
|
||||
target: '_blank',
|
||||
},
|
||||
],
|
||||
enTitle: 'Advanced And Powerful',
|
||||
title: '更强大',
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Following the Ant Design specification, we developed a Vue UI library `antd` tha
|
|||
<div class="pic-plus">
|
||||
<img width="150" src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg" />
|
||||
<span>+</span>
|
||||
<img width="160" src="https://aliyuncdn.antdv.com/vue.png" />
|
||||
<img width="160" src="https://www.antdv.com/vue.png" />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<div class="pic-plus">
|
||||
<img width="150" src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg" />
|
||||
<span>+</span>
|
||||
<img width="160" src="https://aliyuncdn.antdv.com/vue.png" />
|
||||
<img width="160" src="https://www.antdv.com/vue.png" />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@ We accept donations through these channels:
|
|||
|
||||
<div>
|
||||
<a href="https://www.paypal.me/tangjinzhou" target="_blank">PayPal</a>
|
||||
<br/>
|
||||
<a href="https://aliyuncdn.antdv.com/alipay-and-wechat.png" target="_blank">Alipay or WeChat</a>
|
||||
</div>
|
||||
|
||||
## Recurring Pledges
|
||||
|
|
@ -33,7 +31,7 @@ You can consult me by email [antdv@foxmail.com](antdv@foxmail.com).
|
|||
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/ant-design-vue#sponsor)]
|
||||
|
||||
<div>
|
||||
<a href="http://www.jeecg.com/" target="_blank"><img src="https://aliyuncdn.antdv.com/jeecg-logo.png" height="64"></a>
|
||||
<a href="http://www.jeecg.com/" target="_blank"><img src="https://www.antdv.com/jeecg-logo.png" height="64"></a>
|
||||
<a href="https://opencollective.com/ant-design-vue/sponsor/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ant-design-vue/sponsor/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ant-design-vue/sponsor/2/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/2/avatar.svg"></a>
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@ ant-design-vue 是采用 MIT 许可的开源项目,使用完全免费。 但
|
|||
|
||||
<div>
|
||||
<a href="https://www.paypal.me/tangjinzhou" target="_blank">PayPal</a>
|
||||
<br/>
|
||||
<a href="https://aliyuncdn.antdv.com/alipay-and-wechat.png" target="_blank">支付宝或微信</a>
|
||||
</div>
|
||||
|
||||
## 购买贴纸
|
||||
|
|
@ -37,7 +35,7 @@ ant-design-vue 是采用 MIT 许可的开源项目,使用完全免费。 但
|
|||
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/ant-design-vue#sponsor)]
|
||||
|
||||
<div>
|
||||
<a href="http://www.jeecg.com/" target="_blank"><img src="https://aliyuncdn.antdv.com/jeecg-logo.png" height="64"></a>
|
||||
<a href="http://www.jeecg.com/" target="_blank"><img src="https://www.antdv.com/jeecg-logo.png" height="64"></a>
|
||||
<a href="https://opencollective.com/ant-design-vue/sponsor/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ant-design-vue/sponsor/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ant-design-vue/sponsor/2/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/2/avatar.svg"></a>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "antdv-v4",
|
||||
"compatibility_date": "2025-09-18",
|
||||
"assets": {
|
||||
"directory": "./site/dist",
|
||||
"not_found_handling": "single-page-application"
|
||||
},
|
||||
"routes": [
|
||||
{
|
||||
"pattern": "antdv.com/*",
|
||||
"zone_name": "antdv.com"
|
||||
},
|
||||
{
|
||||
"pattern": "www.antdv.com/*",
|
||||
"zone_name": "antdv.com"
|
||||
}
|
||||
]
|
||||
}
|
||||