mirror of
https://github.com/ant-design/ant-design.git
synced 2025-06-11 11:32:52 +08:00
fix: update merge
This commit is contained in:
commit
7dd0bd396d
4
.github/CODEOWNERS
vendored
Normal file
4
.github/CODEOWNERS
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
package.json @ant-design/ant-design-core
|
||||||
|
.github/workflows/ @ant-design/ant-design-core
|
||||||
|
scripts/ @ant-design/ant-design-core
|
||||||
|
LICENSE @ant-design/ant-design-core
|
@ -14,7 +14,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: analysis
|
- name: analysis
|
||||||
uses: actions-cool/issues-similarity-analysis@v1.1.0
|
uses: actions-cool/issues-similarity-analysis@v1
|
||||||
with:
|
with:
|
||||||
filter-threshold: 0.5
|
filter-threshold: 0.5
|
||||||
title-excludes: ''
|
title-excludes: ''
|
||||||
|
2
.github/workflows/rebase.yml
vendored
2
.github/workflows/rebase.yml
vendored
@ -20,6 +20,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Automatic Rebase
|
- name: Automatic Rebase
|
||||||
uses: cirrus-actions/rebase@1.5
|
uses: cirrus-actions/rebase@1.6
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
17
.github/workflows/ui-upload.yml
vendored
17
.github/workflows/ui-upload.yml
vendored
@ -1,6 +1,5 @@
|
|||||||
# Upload 📷 UI snapshots to argos server, help visual regression testing.
|
# Upload 📷 UI snapshots to argos server, help visual regression testing.
|
||||||
|
name: 📷 UI Upload
|
||||||
name: UI Upload
|
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_run:
|
workflow_run:
|
||||||
@ -21,6 +20,9 @@ jobs:
|
|||||||
if: >
|
if: >
|
||||||
github.event.workflow_run.conclusion == 'success'
|
github.event.workflow_run.conclusion == 'success'
|
||||||
steps:
|
steps:
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Download commit artifact
|
- name: Download commit artifact
|
||||||
uses: dawidd6/action-download-artifact@v2
|
uses: dawidd6/action-download-artifact@v2
|
||||||
with:
|
with:
|
||||||
@ -47,8 +49,15 @@ jobs:
|
|||||||
workflow: ${{ github.event.workflow_run.workflow_id }}
|
workflow: ${{ github.event.workflow_run.workflow_id }}
|
||||||
workflow_conclusion: success
|
workflow_conclusion: success
|
||||||
name: snapshots
|
name: snapshots
|
||||||
|
path: imageSnapshots
|
||||||
|
|
||||||
|
- name: Install
|
||||||
|
run: npm i fast-glob lodash argos-cli
|
||||||
|
|
||||||
- name: Upload argos-ci
|
- name: Upload argos-ci
|
||||||
id: deploy
|
id: deploy
|
||||||
run: |
|
run: npm run argos
|
||||||
npx argos-cli upload ./ --token ${{ secrets.ARGOS_TOKEN }} --branch ${{ steps.branch.outputs.id }} --commit ${{ steps.commit.outputs.id }}
|
env:
|
||||||
|
ARGOS_TOKEN: ${{ secrets.ARGOS_TOKEN }}
|
||||||
|
ARGOS_GITHUB_BRANCH: ${{ steps.branch.outputs.id }}
|
||||||
|
ARGOS_GITHUB_COMMIT: ${{ steps.commit.outputs.id }}
|
||||||
|
11
.github/workflows/ui.yml
vendored
11
.github/workflows/ui.yml
vendored
@ -4,19 +4,14 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
types: [opened, synchronize, reopened]
|
types: [opened, synchronize, reopened]
|
||||||
push:
|
push:
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
|
|
||||||
# Cancel prev CI if new commit come
|
# Cancel prev CI if new commit come
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
imagesnapshot:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: checkout
|
- name: checkout
|
||||||
@ -28,6 +23,10 @@ jobs:
|
|||||||
path: package-temp-dir
|
path: package-temp-dir
|
||||||
key: lock-${{ github.sha }}
|
key: lock-${{ github.sha }}
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: '16'
|
||||||
|
|
||||||
- name: create package-lock.json
|
- name: create package-lock.json
|
||||||
run: npm i --package-lock-only --ignore-scripts
|
run: npm i --package-lock-only --ignore-scripts
|
||||||
|
|
||||||
|
4
.github/workflows/verify-files-modify.yml
vendored
4
.github/workflows/verify-files-modify.yml
vendored
@ -20,8 +20,9 @@ jobs:
|
|||||||
forbid-files: 'CHANGELOG.zh-CN.md, CHANGELOG.en-US.md, LICENSE'
|
forbid-files: 'CHANGELOG.zh-CN.md, CHANGELOG.en-US.md, LICENSE'
|
||||||
skip-verify-authority: 'write'
|
skip-verify-authority: 'write'
|
||||||
assignees: 'afc163, zombieJ, xrkffgg, MadCcc'
|
assignees: 'afc163, zombieJ, xrkffgg, MadCcc'
|
||||||
|
comment-mark: 'version'
|
||||||
comment: |
|
comment: |
|
||||||
Hi @${{ github.event.pull_request.user.login }}. Thanks for your contribution. The path `.github/` or `scripts/` and `CHANGELOG` `package.json` is only maintained by team members. This current PR will be closed and team members will help on this.
|
Hi @${{ github.event.pull_request.user.login }}. Thanks for your contribution. The path `.github/` or `scripts/` and `CHANGELOG` is only maintained by team members. This current PR will be closed and team members will help on this.
|
||||||
close: true
|
close: true
|
||||||
set-failed: false
|
set-failed: false
|
||||||
|
|
||||||
@ -30,6 +31,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
forbid-files: 'components/style/themes/default.less'
|
forbid-files: 'components/style/themes/default.less'
|
||||||
skip-verify-authority: 'admin'
|
skip-verify-authority: 'admin'
|
||||||
|
comment-mark: 'less'
|
||||||
comment: |
|
comment: |
|
||||||
🚨 Hi @${{ github.event.pull_request.user.login }}. Thanks for your contribution, as the `default.less` file is currently being upgraded, changes are not recommended.
|
🚨 Hi @${{ github.event.pull_request.user.login }}. Thanks for your contribution, as the `default.less` file is currently being upgraded, changes are not recommended.
|
||||||
|
|
||||||
|
187
AUTHORS.txt
187
AUTHORS.txt
@ -1,6 +1,7 @@
|
|||||||
+v <ljw@live.jp>
|
+v <ljw@live.jp>
|
||||||
07akioni <07akioni2@gmail.com>
|
07akioni <07akioni2@gmail.com>
|
||||||
17073025 <17073025@cnsuning.com>
|
17073025 <17073025@cnsuning.com>
|
||||||
|
2724635499 <2724635499@qq.com>
|
||||||
282159468 <282159468@qq.com>
|
282159468 <282159468@qq.com>
|
||||||
778758944 <778758944@qq.com>
|
778758944 <778758944@qq.com>
|
||||||
Aaron Cawte <aaron@bbncreative.co>
|
Aaron Cawte <aaron@bbncreative.co>
|
||||||
@ -9,6 +10,7 @@ Adam Stankiewicz <sheerun@sher.pl>
|
|||||||
Aditya Padhi <aditya.padhi@outlook.com>
|
Aditya Padhi <aditya.padhi@outlook.com>
|
||||||
Adrian Dimitrov <dimitrov.adrian@gmail.com>
|
Adrian Dimitrov <dimitrov.adrian@gmail.com>
|
||||||
Adriano Ruberto <adriano.ruberto@gmail.com>
|
Adriano Ruberto <adriano.ruberto@gmail.com>
|
||||||
|
Aex <adaex@qq.com>
|
||||||
Ahmad Abdelaziz <ahmad.abdelaziz@robustastudio.com>
|
Ahmad Abdelaziz <ahmad.abdelaziz@robustastudio.com>
|
||||||
Ahmed AlSammany <ahmed.alsammany@incorta.com>
|
Ahmed AlSammany <ahmed.alsammany@incorta.com>
|
||||||
Ahmet Simsek <iamaroott@gmail.com>
|
Ahmet Simsek <iamaroott@gmail.com>
|
||||||
@ -38,13 +40,18 @@ Alexey Vinogradov <vinogradov.a.i.93@gmail.com>
|
|||||||
Alexey Yakovlev <yallie@yandex.ru>
|
Alexey Yakovlev <yallie@yandex.ru>
|
||||||
Alfred Qiu <sc941203@gmail.com>
|
Alfred Qiu <sc941203@gmail.com>
|
||||||
Ali Zhdanov <makedonec88@gmail.com>
|
Ali Zhdanov <makedonec88@gmail.com>
|
||||||
|
Aliaksandr <puskin1914@gmail.com>
|
||||||
Alireza <alireza.mh@gmail.com>
|
Alireza <alireza.mh@gmail.com>
|
||||||
Alvin Abia <alvin.abia@icloud.com>
|
Alvin Abia <alvin.abia@icloud.com>
|
||||||
|
Aminul Islam <me@aminul.net>
|
||||||
Amir Arafat <amirarafat1@gmail.com>
|
Amir Arafat <amirarafat1@gmail.com>
|
||||||
Amorites <751809522@qq.com>
|
Amorites <751809522@qq.com>
|
||||||
|
Amour1688 <lcz_1996@foxmail.com>
|
||||||
Amumu <yoyo837@hotmail.com>
|
Amumu <yoyo837@hotmail.com>
|
||||||
Anas Tawfeek <anas.tawfeek@outlook.com>
|
Anas Tawfeek <anas.tawfeek@outlook.com>
|
||||||
Andre Perunicic <andre@intoli.com>
|
Andre Perunicic <andre@intoli.com>
|
||||||
|
Andre Zyczkowski <andre@oakslab.com>
|
||||||
|
Andrea Blanco <estefania_8_3@hotmail.com>
|
||||||
Andrew Murray <radarhere@gmail.com>
|
Andrew Murray <radarhere@gmail.com>
|
||||||
Andrew Shearer <andrew@ashearer.com>
|
Andrew Shearer <andrew@ashearer.com>
|
||||||
Andrey G <plandem@gmail.com>
|
Andrey G <plandem@gmail.com>
|
||||||
@ -52,6 +59,7 @@ Andrzej Dybionka <andrzej@arabel.la>
|
|||||||
André <mazoni.andre@gmail.com>
|
André <mazoni.andre@gmail.com>
|
||||||
Andrés <andresin87@gmail.com>
|
Andrés <andresin87@gmail.com>
|
||||||
Ankit Babbar <ankit.babbar@valuebound.com>
|
Ankit Babbar <ankit.babbar@valuebound.com>
|
||||||
|
Antee <gtavctt@protonmail.com>
|
||||||
Aobo Yang <yangaobo@gmail.com>
|
Aobo Yang <yangaobo@gmail.com>
|
||||||
Ardo Kusuma <ardo@uber.com>
|
Ardo Kusuma <ardo@uber.com>
|
||||||
Arlindo Torres <arlindofontetorres@gmail.com>
|
Arlindo Torres <arlindofontetorres@gmail.com>
|
||||||
@ -61,6 +69,7 @@ Artin <lengthmin@gmail.com>
|
|||||||
Arvin Xu <arvinx@foxmail.com>
|
Arvin Xu <arvinx@foxmail.com>
|
||||||
Ash Kumar <kumar.ashwin@outlook.com>
|
Ash Kumar <kumar.ashwin@outlook.com>
|
||||||
Ashot Mnatsakanyan <mnatsakanyan.ashot@gmail.com>
|
Ashot Mnatsakanyan <mnatsakanyan.ashot@gmail.com>
|
||||||
|
Austaras <austaras@outlook.com>
|
||||||
Aymen Bouchekoua <bouchekoua.aymen@gmail.com>
|
Aymen Bouchekoua <bouchekoua.aymen@gmail.com>
|
||||||
Aymen Chebbi <a.chebi@klarx.com>
|
Aymen Chebbi <a.chebi@klarx.com>
|
||||||
BK Heleth <bon.hoo@hotmail.com>
|
BK Heleth <bon.hoo@hotmail.com>
|
||||||
@ -102,15 +111,20 @@ C.J. Winslow <whoaa512@gmail.com>
|
|||||||
CORP\lianyufeng <15275222711@163.com>
|
CORP\lianyufeng <15275222711@163.com>
|
||||||
Calin Vlad <vlad.s.calin@gmail.com>
|
Calin Vlad <vlad.s.calin@gmail.com>
|
||||||
Cam Song <neosoyn@gmail.com>
|
Cam Song <neosoyn@gmail.com>
|
||||||
|
Camol <kwwnjujlc@sina.com>
|
||||||
Cang Ta <hoksilato176@gmail.com>
|
Cang Ta <hoksilato176@gmail.com>
|
||||||
Canwen Xu <canwenxu@126.com>
|
Canwen Xu <canwenxu@126.com>
|
||||||
Carlos Coves Prieto <carlos.coves@interacso.com>
|
Carlos Coves Prieto <carlos.coves@interacso.com>
|
||||||
Carter Feldman <carter@carter.at>
|
Carter Feldman <carter@carter.at>
|
||||||
|
Caspian Chen <624081567@qq.com>
|
||||||
|
Cat-XHS <1349021570@qq.com>
|
||||||
Catalin Miron <mironcatalin@gmail.com>
|
Catalin Miron <mironcatalin@gmail.com>
|
||||||
Cee Cirno <i@cee.moe>
|
Cee Cirno <i@cee.moe>
|
||||||
Cemre Mengu <cemremengu@gmail.com>
|
Cemre Mengu <cemremengu@gmail.com>
|
||||||
|
Chalk <chalkpe@gmail.com>
|
||||||
Chandler Moisen <chandlermoisen@gmail.com>
|
Chandler Moisen <chandlermoisen@gmail.com>
|
||||||
Chang Wang <cheapsteak@gmail.com>
|
Chang Wang <cheapsteak@gmail.com>
|
||||||
|
Chang Wei <867597730@qq.com>
|
||||||
Charles Covey-Brandt <chazcb@gmail.com>
|
Charles Covey-Brandt <chazcb@gmail.com>
|
||||||
Charlie Jonas <charlie@callawaycloudconsulting.com>
|
Charlie Jonas <charlie@callawaycloudconsulting.com>
|
||||||
Chelsea Huang <chelsea.huang@sap.com>
|
Chelsea Huang <chelsea.huang@sap.com>
|
||||||
@ -130,10 +144,12 @@ Chuang Yu <cyu9960@gmail.com>
|
|||||||
Chuck <wfhtzcf@gmail.com>
|
Chuck <wfhtzcf@gmail.com>
|
||||||
Claudio Restifo <claudio.restifo@gmail.com>
|
Claudio Restifo <claudio.restifo@gmail.com>
|
||||||
Cody Chan <int64ago@gmail.com>
|
Cody Chan <int64ago@gmail.com>
|
||||||
|
Cole <cqiufan@outlook.com>
|
||||||
Colton Pierson <colton@coltonpierson.com>
|
Colton Pierson <colton@coltonpierson.com>
|
||||||
Confiks <confiks@scriptbase.org>
|
Confiks <confiks@scriptbase.org>
|
||||||
Cong Yoo <roopher@163.com>
|
Cong Yoo <roopher@163.com>
|
||||||
Cong Zhang <dancerphil1994@gmail.com>
|
Cong Zhang <dancerphil1994@gmail.com>
|
||||||
|
Connor White <connor.bcw@gmail.com>
|
||||||
Conway Anderson <hello@conwayanderson.com>
|
Conway Anderson <hello@conwayanderson.com>
|
||||||
Cordaro <elvis07@163.com>
|
Cordaro <elvis07@163.com>
|
||||||
CornerSkyless <573196853@qq.com>
|
CornerSkyless <573196853@qq.com>
|
||||||
@ -149,6 +165,7 @@ Daniel <caishujunchn@163.com>
|
|||||||
Daniel Chang <danielchang2022@u.northwestern.edu>
|
Daniel Chang <danielchang2022@u.northwestern.edu>
|
||||||
Daniel Gomez <dgomez@orangeloops.com>
|
Daniel Gomez <dgomez@orangeloops.com>
|
||||||
Daniel Harrison <daniel.equiknox@gmail.com>
|
Daniel Harrison <daniel.equiknox@gmail.com>
|
||||||
|
Daniel Pfeffer <mail@danielpfeffer.de>
|
||||||
Danny Hoower Antonio Viasus Avila <danjavia@gmail.com>
|
Danny Hoower Antonio Viasus Avila <danjavia@gmail.com>
|
||||||
Daphne Won <daphne.won@shopee.com>
|
Daphne Won <daphne.won@shopee.com>
|
||||||
Daqi Song <dqaria@gmail.com>
|
Daqi Song <dqaria@gmail.com>
|
||||||
@ -161,13 +178,18 @@ David Broder-Rodgers <david.broder-rodgers@softwire.com>
|
|||||||
David Hatten <dhatten@covermymeds.com>
|
David Hatten <dhatten@covermymeds.com>
|
||||||
David Schneider <davschne@gmail.com>
|
David Schneider <davschne@gmail.com>
|
||||||
Davide Bianchi <bianchidavide12@gmail.com>
|
Davide Bianchi <bianchidavide12@gmail.com>
|
||||||
|
Dawnlck <chaokai.lck@antgroup.com>
|
||||||
Dean van Niekerk <deanvniekerk@gmail.com>
|
Dean van Niekerk <deanvniekerk@gmail.com>
|
||||||
Debiancc <never.be.evil.debian@gmail.com>
|
Debiancc <never.be.evil.debian@gmail.com>
|
||||||
DengYun <tdzl2003@gmail.com>
|
DengYun <tdzl2003@gmail.com>
|
||||||
Denis <shumkovdenis@gmail.com>
|
Denis <shumkovdenis@gmail.com>
|
||||||
|
Dennis273 <dennisc695@icloud.com>
|
||||||
|
Derrick <derricktel@foxmail.com>
|
||||||
|
Di Wu <di@gridx.cn>
|
||||||
DiamondYuan <admin@diamondyuan.com>
|
DiamondYuan <admin@diamondyuan.com>
|
||||||
DiamondYuan <541832074@qq.com>
|
DiamondYuan <541832074@qq.com>
|
||||||
Diego Barreiro <diego.barreiro.perez@gmail.com>
|
Diego Barreiro <diego.barreiro.perez@gmail.com>
|
||||||
|
Diego Villacís <diegovillacis101@gmail.com>
|
||||||
Dimitri Mitropoulos <dimitrimitropoulos@gmail.com>
|
Dimitri Mitropoulos <dimitrimitropoulos@gmail.com>
|
||||||
Dmitriy <dimusig@gmail.com>
|
Dmitriy <dimusig@gmail.com>
|
||||||
Dmitriy Mironov <dima.dev01@gmail.com>
|
Dmitriy Mironov <dima.dev01@gmail.com>
|
||||||
@ -178,9 +200,12 @@ Dmitry Manannikov <email@slonoed.net>
|
|||||||
Dmitry Snegirev <rikkitp@gmail.com>
|
Dmitry Snegirev <rikkitp@gmail.com>
|
||||||
Dmitry Tikhomirov <tikhomirov@element-soft.com>
|
Dmitry Tikhomirov <tikhomirov@element-soft.com>
|
||||||
Dongcheng Wang <dongcheng6@qq.com>
|
Dongcheng Wang <dongcheng6@qq.com>
|
||||||
|
Dony Sukardi <donysukardi@gmail.com>
|
||||||
Dorian <dorian@doma.io>
|
Dorian <dorian@doma.io>
|
||||||
DosLin <doslino@gmail.com>
|
DosLin <doslino@gmail.com>
|
||||||
Douglas Mason <Demasonjr@gmail.com>
|
Douglas Mason <Demasonjr@gmail.com>
|
||||||
|
Dreamcreative <m543438924@163.com>
|
||||||
|
Dzmitry Yarmoshkin <spanb4@gmail.com>
|
||||||
Eager <1226393396@qq.com>
|
Eager <1226393396@qq.com>
|
||||||
Eber Rodrigues <eberjoe@gmail.com>
|
Eber Rodrigues <eberjoe@gmail.com>
|
||||||
EcmaProSrc.P/ka <asoiso@foxmail.com>
|
EcmaProSrc.P/ka <asoiso@foxmail.com>
|
||||||
@ -193,14 +218,18 @@ Eduardo Ludi <eduludi@gmail.com>
|
|||||||
Edward <7047924@qq.com>
|
Edward <7047924@qq.com>
|
||||||
Egor Yurtaev <yurtaev.egor@gmail.com>
|
Egor Yurtaev <yurtaev.egor@gmail.com>
|
||||||
Elaina Cherudim <shr9192@gmail.com>
|
Elaina Cherudim <shr9192@gmail.com>
|
||||||
|
Eldar Mirzabekov <prog.eldar@gmail.com>
|
||||||
Eldar Mustafaiev <eldar.mustafaiev@gmail.com>
|
Eldar Mustafaiev <eldar.mustafaiev@gmail.com>
|
||||||
Eli White <github@eli-white.com>
|
Eli White <github@eli-white.com>
|
||||||
|
Eliot Sanford <eliot587@gmail.com>
|
||||||
Emerson Laurentino <emersonlaurentino@hotmail.com>
|
Emerson Laurentino <emersonlaurentino@hotmail.com>
|
||||||
Emily Xiong <xiongemi@gmail.com>
|
Emily Xiong <xiongemi@gmail.com>
|
||||||
Ender Lee <chnliquan@163.com>
|
Ender Lee <chnliquan@163.com>
|
||||||
Eric <84263800@qq.com>
|
Eric <84263800@qq.com>
|
||||||
|
Eric Bonow <ebonow@hotmail.com>
|
||||||
Eric Celeste <efc@clst.org>
|
Eric Celeste <efc@clst.org>
|
||||||
Eric Chen <airkro@qq.com>
|
Eric Chen <airkro@qq.com>
|
||||||
|
Eric Lee <ericfly33@gmail.com>
|
||||||
Eric Turriff <eric.turriff@gmail.com>
|
Eric Turriff <eric.turriff@gmail.com>
|
||||||
Eric Wang <eric@canva.com>
|
Eric Wang <eric@canva.com>
|
||||||
Eric Wang <wjun0912@gmail.com>
|
Eric Wang <wjun0912@gmail.com>
|
||||||
@ -210,36 +239,50 @@ Eugene Matvejev <eugene.matvejev@gmail.com>
|
|||||||
Eugene Molokov <molokovev@gmail.com>
|
Eugene Molokov <molokovev@gmail.com>
|
||||||
Eusen <179530591@qq.com>
|
Eusen <179530591@qq.com>
|
||||||
Evan Charlton <evancharlton@gmail.com>
|
Evan Charlton <evancharlton@gmail.com>
|
||||||
|
EvanOne(文一) <1656081615@qq.com>
|
||||||
Evgeny Kuznetsov <jackk@ya.ru>
|
Evgeny Kuznetsov <jackk@ya.ru>
|
||||||
Eward Song <eward.song@gmail.com>
|
Eward Song <eward.song@gmail.com>
|
||||||
|
FJHou <firemybugs@gmail.com>
|
||||||
|
Fachreza Muslim <fachreza.muslim7396@gmail.com>
|
||||||
Federico Marcos <marcosfede@gmail.com>
|
Federico Marcos <marcosfede@gmail.com>
|
||||||
Ferdi Koomen <info@madebyferdi.com>
|
Ferdi Koomen <info@madebyferdi.com>
|
||||||
Fergus Leung <fergusleung96@gmail.com>
|
Fergus Leung <fergusleung96@gmail.com>
|
||||||
Fernando Giarritiello <fgiarritiello@gmail.com>
|
Fernando Giarritiello <fgiarritiello@gmail.com>
|
||||||
Filip Kukovec <filip.kukovec1@gmail.com>
|
Filip Kukovec <filip.kukovec1@gmail.com>
|
||||||
|
Filip Seman <filip.seman@protonmail.com>
|
||||||
Florian Orpelière <florian.orpeliere@gmail.com>
|
Florian Orpelière <florian.orpeliere@gmail.com>
|
||||||
Flynn <li.fulin@foxmail.com>
|
Flynn <li.fulin@foxmail.com>
|
||||||
|
Fog3211 <fog3211@163.com>
|
||||||
For177 <mengqiang.q@gmail.com>
|
For177 <mengqiang.q@gmail.com>
|
||||||
Frank <frankdingv@gmail.com>
|
Frank <frankdingv@gmail.com>
|
||||||
|
Frank Fang <FrankFang1990@gmail.com>
|
||||||
Frezc <Frezcw@gmail.com>
|
Frezc <Frezcw@gmail.com>
|
||||||
Fullstop000 <fullstop1005@gmail.com>
|
Fullstop000 <fullstop1005@gmail.com>
|
||||||
GJ Wang <itellboy@foxmail.com>
|
GJ Wang <itellboy@foxmail.com>
|
||||||
GSBL <2602140596@qq.com>
|
GSBL <2602140596@qq.com>
|
||||||
Gabe Medrash <gabeme@alleninstitute.org>
|
Gabe Medrash <gabeme@alleninstitute.org>
|
||||||
|
Gabriel Henrique <bielrockx@gmail.com>
|
||||||
Gabriel Le Breton <lebreton.gabriel@gmail.com>
|
Gabriel Le Breton <lebreton.gabriel@gmail.com>
|
||||||
|
Gabriel Mendez Reyes <gabriel.mendez0@hotmail.com>
|
||||||
Gabriel Nunes <gabriel@multiverso.me>
|
Gabriel Nunes <gabriel@multiverso.me>
|
||||||
GalenWong <wonggalen1999@gmail.com>
|
GalenWong <wonggalen1999@gmail.com>
|
||||||
|
GannonSun <GannonSun@gmail.com>
|
||||||
Gao Jiangmiao <tolbkni@gmail.com>
|
Gao Jiangmiao <tolbkni@gmail.com>
|
||||||
|
Garrick Crouch <garrickcrouch@gmail.com>
|
||||||
Gautier <rollingautier2@gmail.com>
|
Gautier <rollingautier2@gmail.com>
|
||||||
Geoff Holden <geoff@brightloudnoise.com>
|
Geoff Holden <geoff@brightloudnoise.com>
|
||||||
|
Geoffrey Bell <gtb104@yahoo.com>
|
||||||
George Gray <george@ummodesign.com>
|
George Gray <george@ummodesign.com>
|
||||||
Germini <634709523@qq.com>
|
Germini <634709523@qq.com>
|
||||||
Gerson Garrido <ggarridom23@gmail.com>
|
Gerson Garrido <ggarridom23@gmail.com>
|
||||||
|
Gherciu Gheorghe <gherciu553@gmail.com>
|
||||||
|
Gianmarco Rengucci <rengucci.gianmarco@gmail.com>
|
||||||
Gin-X <xcbwyys@hotmail.com>
|
Gin-X <xcbwyys@hotmail.com>
|
||||||
Go7hic <gtfx0209@qq.com>
|
Go7hic <gtfx0209@qq.com>
|
||||||
Goh Zhao Yang <austinzy@airasia.com>
|
Goh Zhao Yang <austinzy@airasia.com>
|
||||||
Golevka <huangsamfisher@163.com>
|
Golevka <huangsamfisher@163.com>
|
||||||
Googleplex <yyoung2001@gmail.com>
|
Googleplex <yyoung2001@gmail.com>
|
||||||
|
Gourav Saini <mailtogouravsaini@gmail.com>
|
||||||
Graeme Yeates <yeatesgraeme@gmail.com>
|
Graeme Yeates <yeatesgraeme@gmail.com>
|
||||||
Graeme Yeates <gyeates@clearpath.ai>
|
Graeme Yeates <gyeates@clearpath.ai>
|
||||||
Grant Klinsing <gklinsing@gmail.com>
|
Grant Klinsing <gklinsing@gmail.com>
|
||||||
@ -247,10 +290,14 @@ Gray Choi <gray.choi.1988@gmail.com>
|
|||||||
Guan Hao <raptium@gmail.com>
|
Guan Hao <raptium@gmail.com>
|
||||||
Guan Yu Pan (Jacky) <jackypan1989@gmail.com>
|
Guan Yu Pan (Jacky) <jackypan1989@gmail.com>
|
||||||
Guichi Zhao <zgc910619@gmail.com>
|
Guichi Zhao <zgc910619@gmail.com>
|
||||||
|
Guojun Wang <itwanggj@163.com>
|
||||||
|
Guru Mahendran <me@gurubavan.com>
|
||||||
HJin.me <hjin.me@gmail.com>
|
HJin.me <hjin.me@gmail.com>
|
||||||
Hai Phan Nguyen <pnghai@gmail.com>
|
Hai Phan Nguyen <pnghai@gmail.com>
|
||||||
Haibin Yu <haibin.yu@oceanwing.com>
|
Haibin Yu <haibin.yu@oceanwing.com>
|
||||||
Hal-pan <hms181231@gmail.com>
|
Hal-pan <hms181231@gmail.com>
|
||||||
|
Hale Deng <haledeng88@gmail.com>
|
||||||
|
Han Han <haannn@qq.com>
|
||||||
Hanai <ihanai1991@gmail.com>
|
Hanai <ihanai1991@gmail.com>
|
||||||
Hanjun Kim <hallazzang@gmail.com>
|
Hanjun Kim <hallazzang@gmail.com>
|
||||||
Hanz Luo <lhz0516@gmail.com>
|
Hanz Luo <lhz0516@gmail.com>
|
||||||
@ -262,6 +309,7 @@ Harshit Mehrotra <harshitmehrotra@hotmail.com>
|
|||||||
Harutaka Kawamura <hkawamura0130@gmail.com>
|
Harutaka Kawamura <hkawamura0130@gmail.com>
|
||||||
He Linming <hlm52pk@163.com>
|
He Linming <hlm52pk@163.com>
|
||||||
Heaven <ne_smalltown@163.com>
|
Heaven <ne_smalltown@163.com>
|
||||||
|
Hell Cat <hellcatvn@gmail.com>
|
||||||
Henri Normak <henri.normak@gmail.com>
|
Henri Normak <henri.normak@gmail.com>
|
||||||
HeskeyBaozi <hezhiyu233@foxmail.com>
|
HeskeyBaozi <hezhiyu233@foxmail.com>
|
||||||
HiddenMan <1196089730@qq.com>
|
HiddenMan <1196089730@qq.com>
|
||||||
@ -282,6 +330,7 @@ ILdar Nogmanov <nogmanov@gmail.com>
|
|||||||
Igor <nemytyshew@yandex.ru>
|
Igor <nemytyshew@yandex.ru>
|
||||||
Igor Andriushchenko <igor.andriushchenko@snowsoftware.com>
|
Igor Andriushchenko <igor.andriushchenko@snowsoftware.com>
|
||||||
Igor G <i.gaidai4uk@gmail.com>
|
Igor G <i.gaidai4uk@gmail.com>
|
||||||
|
Ikko Ashimine <eltociear@gmail.com>
|
||||||
Ilan <hasanovtk@gmail.com>
|
Ilan <hasanovtk@gmail.com>
|
||||||
Ilya Bondarenko <bondarenko.ik@gmail.com>
|
Ilya Bondarenko <bondarenko.ik@gmail.com>
|
||||||
ImJoeHs <865439601@qq.com>
|
ImJoeHs <865439601@qq.com>
|
||||||
@ -297,6 +346,7 @@ Ivan Tsybulin <vanyatsybulin@gmail.com>
|
|||||||
Ivan Yakovlev <addictional2013@gmail.com>
|
Ivan Yakovlev <addictional2013@gmail.com>
|
||||||
Ivo Stratev <ivo.stratev.tues@gmail.com>
|
Ivo Stratev <ivo.stratev.tues@gmail.com>
|
||||||
JRoger <sjr_vip@126.com>
|
JRoger <sjr_vip@126.com>
|
||||||
|
Jabir K.H <khjabir@gmail.com>
|
||||||
Jack <jacklee82814@gmail.com>
|
Jack <jacklee82814@gmail.com>
|
||||||
Jack Hsieh <jack@egenware.com>
|
Jack Hsieh <jack@egenware.com>
|
||||||
Jack Lo <jack-lo@foxmail.com>
|
Jack Lo <jack-lo@foxmail.com>
|
||||||
@ -305,21 +355,27 @@ Jackie.Ls <418292038@qq.com>
|
|||||||
Jacques Kvam <jwkvam@gmail.com>
|
Jacques Kvam <jwkvam@gmail.com>
|
||||||
JaePil Jung <jjp5023@gmail.com>
|
JaePil Jung <jjp5023@gmail.com>
|
||||||
Jaewook Ahn <ajw4586@gmail.com>
|
Jaewook Ahn <ajw4586@gmail.com>
|
||||||
|
Jaimy de Graaf <me@vfour.dev>
|
||||||
Jake Richards <jake.richards@genesys.com>
|
Jake Richards <jake.richards@genesys.com>
|
||||||
Jaly <dcdlove@qq.com>
|
Jaly <dcdlove@qq.com>
|
||||||
|
James <daoxingyue@live.cn>
|
||||||
James <james@schoolshape.com>
|
James <james@schoolshape.com>
|
||||||
James Tsang <wentao_zeng1@163.com>
|
James Tsang <wentao_zeng1@163.com>
|
||||||
James Yeung <shunjiey@hotmail.com>
|
James Yeung <shunjiey@hotmail.com>
|
||||||
JamesYin <elantion@gmail.com>
|
JamesYin <elantion@gmail.com>
|
||||||
|
Jan Václavík <jvaclavik@gmail.com>
|
||||||
|
Janry <wangzhili56@126.com>
|
||||||
Jaroslav Bereza <github.com@bereza.cz>
|
Jaroslav Bereza <github.com@bereza.cz>
|
||||||
Jarret Moses <jarret.moses@gmail.com>
|
Jarret Moses <jarret.moses@gmail.com>
|
||||||
Jarvis1010 <travis.mair@gmail.com>
|
Jarvis1010 <travis.mair@gmail.com>
|
||||||
|
Jase Owens <jaseowens197@gmail.com>
|
||||||
Jase Pellerin <jasepellerin@gmail.com>
|
Jase Pellerin <jasepellerin@gmail.com>
|
||||||
Jason <ceocjy@vip.qq.com>
|
Jason <ceocjy@vip.qq.com>
|
||||||
Jason Chung <shiningjason1989@gmail.com>
|
Jason Chung <shiningjason1989@gmail.com>
|
||||||
Jason Yin <yinjiangsheng@gmail.com>
|
Jason Yin <yinjiangsheng@gmail.com>
|
||||||
Jay Fong <fjc0kb@gmail.com>
|
Jay Fong <fjc0kb@gmail.com>
|
||||||
Jean-Luc Sorak <jlsorak@icloud.com>
|
Jean-Luc Sorak <jlsorak@icloud.com>
|
||||||
|
Jean-Philippe Roy <ohnoesmyoreos@gmail.com>
|
||||||
Jeff Wen <sinchangwen@gmail.com>
|
Jeff Wen <sinchangwen@gmail.com>
|
||||||
Jeffrey Carl Faden <jeffreyatw@gmail.com>
|
Jeffrey Carl Faden <jeffreyatw@gmail.com>
|
||||||
Jehu <z_zhihao@foxmail.com>
|
Jehu <z_zhihao@foxmail.com>
|
||||||
@ -332,9 +388,11 @@ Jesper We <jesper@journeyman.se>
|
|||||||
Jesus The Hun <iletaitunefoisfenghuang@gmail.com>
|
Jesus The Hun <iletaitunefoisfenghuang@gmail.com>
|
||||||
Jiabin Peng <png.inside@gmail.com>
|
Jiabin Peng <png.inside@gmail.com>
|
||||||
Jiahao <jahowchen@outlook.com>
|
Jiahao <jahowchen@outlook.com>
|
||||||
|
Jiajun Chen <tychenjiajun@live.cn>
|
||||||
Jialei <jialeicui@126.com>
|
Jialei <jialeicui@126.com>
|
||||||
Jiawei Huang <hjiawei@gmail.com>
|
Jiawei Huang <hjiawei@gmail.com>
|
||||||
Jichao Zhong <felixjichao@gmail.com>
|
Jichao Zhong <felixjichao@gmail.com>
|
||||||
|
Jiehui <jeffylaiakanull@gmail.com>
|
||||||
Jieraaa <842533841@qq.com>
|
Jieraaa <842533841@qq.com>
|
||||||
Jin ZHANG <jz.zhangjin@gmail.com>
|
Jin ZHANG <jz.zhangjin@gmail.com>
|
||||||
JinXin <m18508218948@163.com>
|
JinXin <m18508218948@163.com>
|
||||||
@ -350,6 +408,8 @@ Joe <qiaolibo@126.com>
|
|||||||
Joe Hsu <jhsu.x1@gmail.com>
|
Joe Hsu <jhsu.x1@gmail.com>
|
||||||
Johannes Andersen <johannes.andersen@signifyd.com>
|
Johannes Andersen <johannes.andersen@signifyd.com>
|
||||||
Johannes Loewe <johannes@loewe.pm>
|
Johannes Loewe <johannes@loewe.pm>
|
||||||
|
John <John60676@qq.com>
|
||||||
|
John Carlo <johncarloaustria@pm.me>
|
||||||
John Johnson III <john@johnjohnson.cc>
|
John Johnson III <john@johnjohnson.cc>
|
||||||
John Nguyen <jtnguyen236@gmail.com>
|
John Nguyen <jtnguyen236@gmail.com>
|
||||||
Johnny Lim <izeye@naver.com>
|
Johnny Lim <izeye@naver.com>
|
||||||
@ -360,21 +420,29 @@ Jonathan Lee <1150974628@qq.com>
|
|||||||
Jonny Buchanan <jonathan.buchanan@gmail.com>
|
Jonny Buchanan <jonathan.buchanan@gmail.com>
|
||||||
Joo Wu <wuchu356@gmail.com>
|
Joo Wu <wuchu356@gmail.com>
|
||||||
Jordan Hornblow <jordan@jch254.com>
|
Jordan Hornblow <jordan@jch254.com>
|
||||||
|
Joshua Chen <sidachen2003@gmail.com>
|
||||||
Josue Peralta <jperal77@gmail.com>
|
Josue Peralta <jperal77@gmail.com>
|
||||||
Josué <ujosuegt@outlook.com>
|
Josué <ujosuegt@outlook.com>
|
||||||
|
JounQin <admin@1stg.me>
|
||||||
JribiBelhassen <belha9inzaghi@gmail.com>
|
JribiBelhassen <belha9inzaghi@gmail.com>
|
||||||
|
Jtree03 <wowns0903@gmail.com>
|
||||||
|
JuFeng Zhang <zjffun@gmail.com>
|
||||||
Juan Carlos Lloret H <juan.carlos.lloret@lansweeper.com>
|
Juan Carlos Lloret H <juan.carlos.lloret@lansweeper.com>
|
||||||
Juan Rodrigo Venegas Boesch <jrvboesch@gmail.com>
|
Juan Rodrigo Venegas Boesch <jrvboesch@gmail.com>
|
||||||
Julia Passynkova <ipassynk@hotmail.com>
|
Julia Passynkova <ipassynk@hotmail.com>
|
||||||
Julien Confetti <julien.confetti@ulg.ac.be>
|
Julien Confetti <julien.confetti@ulg.ac.be>
|
||||||
|
Jun Wooram <chatoo2412@gmail.com>
|
||||||
JuniorTour <juniortour@qq.com>
|
JuniorTour <juniortour@qq.com>
|
||||||
|
Junwoo Ji <jydrogen@gmail.com>
|
||||||
Junyu Zhan <irrigator@yeah.net>
|
Junyu Zhan <irrigator@yeah.net>
|
||||||
Juraj Carnogursky <durisvk2@gmail.com>
|
Juraj Carnogursky <durisvk2@gmail.com>
|
||||||
Justin Reich <reich.justin@gmail.com>
|
Justin Reich <reich.justin@gmail.com>
|
||||||
Justin Schuldt <justinschuldt@gmail.com>
|
Justin Schuldt <justinschuldt@gmail.com>
|
||||||
|
Jógvan Olsen <jogvanolsen@hotmail.com>
|
||||||
Kaan KÜÇÜK <kaankck@gmail.com>
|
Kaan KÜÇÜK <kaankck@gmail.com>
|
||||||
Kaien Liao <liaokaien@gmail.com>
|
Kaien Liao <liaokaien@gmail.com>
|
||||||
Kamal Mahmudi <kamalmahmudi@yahoo.co.id>
|
Kamal Mahmudi <kamalmahmudi@yahoo.co.id>
|
||||||
|
Karott Schu <karott7@gmail.com>
|
||||||
Kasra Bigdeli <kasra85@gmail.com>
|
Kasra Bigdeli <kasra85@gmail.com>
|
||||||
Kayson Wu <772663139@qq.com>
|
Kayson Wu <772663139@qq.com>
|
||||||
Kelvin Chu <chubillkelvin@gmail.com>
|
Kelvin Chu <chubillkelvin@gmail.com>
|
||||||
@ -421,6 +489,7 @@ LeoYang <LeoY.Dev@gmail.com>
|
|||||||
Leon Koole <leon@koole.io>
|
Leon Koole <leon@koole.io>
|
||||||
Leon Shi <superRaytin@163.com>
|
Leon Shi <superRaytin@163.com>
|
||||||
Leon Shi <superRaytin@gmail.com>
|
Leon Shi <superRaytin@gmail.com>
|
||||||
|
Lewis <lewisfidlers@gmail.com>
|
||||||
Li C. Pan <18306423262@163.com>
|
Li C. Pan <18306423262@163.com>
|
||||||
Li Chao <rftstars@qq.com>
|
Li Chao <rftstars@qq.com>
|
||||||
Li Ming <armyiljfe@gmail.com>
|
Li Ming <armyiljfe@gmail.com>
|
||||||
@ -428,18 +497,25 @@ LiPinghai <twopoles@163.com>
|
|||||||
LilyWakana <873435892@qq.com>
|
LilyWakana <873435892@qq.com>
|
||||||
Liming Jin <jinliming2@gmail.com>
|
Liming Jin <jinliming2@gmail.com>
|
||||||
Liming Jin <jinlm@knownsec.com>
|
Liming Jin <jinlm@knownsec.com>
|
||||||
|
Liron Lavy <liron.lavy@gmail.com>
|
||||||
|
Liu Bowen <Mr_lbw@outlook.com>
|
||||||
Liu Ya <liuya54892@gmail.com>
|
Liu Ya <liuya54892@gmail.com>
|
||||||
Liu Yang <zation1@gmail.com>
|
Liu Yang <zation1@gmail.com>
|
||||||
LongYinan <lynweklm@gmail.com>
|
LongYinan <lynweklm@gmail.com>
|
||||||
Loogeek <340017792@qq.com>
|
Loogeek <340017792@qq.com>
|
||||||
|
Loïc Huvé <loic.huve@protonmail.com>
|
||||||
|
Lu Yu <brantscube@hotmail.com>
|
||||||
Lucien Lee <lkiral7903@gmail.com>
|
Lucien Lee <lkiral7903@gmail.com>
|
||||||
Ludwig Bäcklund <ludli839@student.liu.se>
|
Ludwig Bäcklund <ludli839@student.liu.se>
|
||||||
Luke Vella <me@lukevella.com>
|
Luke Vella <me@lukevella.com>
|
||||||
Lyndon001 <lld207@126.com>
|
Lyndon001 <lld207@126.com>
|
||||||
M Mitchell <mail@megmitchell.ca>
|
M Mitchell <mail@megmitchell.ca>
|
||||||
|
M. Burak Kalkan <mburakkalkan@gmail.com>
|
||||||
|
MD. Ariful Alam <swazan.arif@gmail.com>
|
||||||
MG12 <wuzhao.mail@gmail.com>
|
MG12 <wuzhao.mail@gmail.com>
|
||||||
Ma Tianxiao <matx2215@outlook.com>
|
Ma Tianxiao <matx2215@outlook.com>
|
||||||
Maciej Czekaj <natanielcz@gmail.com>
|
Maciej Czekaj <natanielcz@gmail.com>
|
||||||
|
MadCcc <1075746765@qq.com>
|
||||||
Madis Väin <madisvain@gmail.com>
|
Madis Väin <madisvain@gmail.com>
|
||||||
Maksim Nesterenko <alendorff@gmail.com>
|
Maksim Nesterenko <alendorff@gmail.com>
|
||||||
Maksim Slotvinskij <m.slotvinskij@gmail.com>
|
Maksim Slotvinskij <m.slotvinskij@gmail.com>
|
||||||
@ -449,6 +525,7 @@ Manjit Kumar <manjit1727@gmail.com>
|
|||||||
Manoj Kumar <manoj.150283@gmail.com>
|
Manoj Kumar <manoj.150283@gmail.com>
|
||||||
Manweill <mic.liangwenwei@foxmail.com>
|
Manweill <mic.liangwenwei@foxmail.com>
|
||||||
MaoYiWei <137308365@qq.com>
|
MaoYiWei <137308365@qq.com>
|
||||||
|
Map1en_ <maplenagisa@gmail.com>
|
||||||
Marcel Jackwerth <marceljackwerth@gmail.com>
|
Marcel Jackwerth <marceljackwerth@gmail.com>
|
||||||
Marcela Bomfim <mbomfim@live.com>
|
Marcela Bomfim <mbomfim@live.com>
|
||||||
Marcio Pamplona <marciopamplona79@gmail.com>
|
Marcio Pamplona <marciopamplona79@gmail.com>
|
||||||
@ -469,6 +546,7 @@ Matt Lein <matt.lein@code42.com>
|
|||||||
Matt Wilkinson <mattwilki17@gmail.com>
|
Matt Wilkinson <mattwilki17@gmail.com>
|
||||||
Max <maksym.mosyura@kruschecompany.com>
|
Max <maksym.mosyura@kruschecompany.com>
|
||||||
Maximilian Meyer <Maximilian.Meyer@br.de>
|
Maximilian Meyer <Maximilian.Meyer@br.de>
|
||||||
|
Md_ZubairAhmed <m-zubairahmed@protonmail.com>
|
||||||
MeiLin <postget.me@gmail.com>
|
MeiLin <postget.me@gmail.com>
|
||||||
MengZhaoFly <1424254461@qq.com>
|
MengZhaoFly <1424254461@qq.com>
|
||||||
Meow-z <372086270@qq.com>
|
Meow-z <372086270@qq.com>
|
||||||
@ -476,6 +554,7 @@ Meowu <474384902@qq.com>
|
|||||||
Miaow <i@zfeng.net>
|
Miaow <i@zfeng.net>
|
||||||
Micah Guttman <memtech3@gmail.com>
|
Micah Guttman <memtech3@gmail.com>
|
||||||
Michael Adams <mtadams007@gmail.com>
|
Michael Adams <mtadams007@gmail.com>
|
||||||
|
Michael Crenshaw <michael@crenshaw.dev>
|
||||||
Michael Krog <mic@apaq.dk>
|
Michael Krog <mic@apaq.dk>
|
||||||
Michael Salaverry <michaels@axonize.com>
|
Michael Salaverry <michaels@axonize.com>
|
||||||
Michael Salaverry <barakplasma@gmail.com>
|
Michael Salaverry <barakplasma@gmail.com>
|
||||||
@ -493,6 +572,7 @@ Min <dicklwm@163.com>
|
|||||||
MinJeong Kim <min7859@gmail.com>
|
MinJeong Kim <min7859@gmail.com>
|
||||||
MinYuan <s1124yy@gmail.com>
|
MinYuan <s1124yy@gmail.com>
|
||||||
Ming Hann <eldy8888@gmail.com>
|
Ming Hann <eldy8888@gmail.com>
|
||||||
|
Minh Quy <sugiacupit@gmail.com>
|
||||||
Minqi Pan <pmq2001@gmail.com>
|
Minqi Pan <pmq2001@gmail.com>
|
||||||
Minsung Ryu <ryums0227@gmail.com>
|
Minsung Ryu <ryums0227@gmail.com>
|
||||||
Minwei Xu <faceswilliam@gmail.com>
|
Minwei Xu <faceswilliam@gmail.com>
|
||||||
@ -501,11 +581,14 @@ Misha Kav <misha.kav@gmail.com>
|
|||||||
Mitchell Demler <mitchell.demler@harcourts.net>
|
Mitchell Demler <mitchell.demler@harcourts.net>
|
||||||
Moein Alizadeh <truemoein@gmail.com>
|
Moein Alizadeh <truemoein@gmail.com>
|
||||||
Mohamed Seada <mohamed.seada.1994@gmail.com>
|
Mohamed Seada <mohamed.seada.1994@gmail.com>
|
||||||
|
Mohammad Anas <mohammad.anas190@gmail.com>
|
||||||
|
Mohammad Arsalan <a4arshi@yahoo.com>
|
||||||
Mohammad Faisal <faisalhmohd@gmail.com>
|
Mohammad Faisal <faisalhmohd@gmail.com>
|
||||||
Mohan Ban <banmohan@outlook.com>
|
Mohan Ban <banmohan@outlook.com>
|
||||||
Mohelm97 <mohelm97@gmail.com>
|
Mohelm97 <mohelm97@gmail.com>
|
||||||
Mongkii <mongkii@hotmail.com>
|
Mongkii <mongkii@hotmail.com>
|
||||||
Moni <usmoni@gmail.com>
|
Moni <usmoni@gmail.com>
|
||||||
|
Monty <montyma1207@163.com>
|
||||||
Mounish Sai <pvsmounish@gmail.com>
|
Mounish Sai <pvsmounish@gmail.com>
|
||||||
Mr.Biscuit <sunshuaiqi@gmail.com>
|
Mr.Biscuit <sunshuaiqi@gmail.com>
|
||||||
Mr.Tone <vector@malubei.com>
|
Mr.Tone <vector@malubei.com>
|
||||||
@ -523,12 +606,15 @@ Nathan Wells <nwwells@gmail.com>
|
|||||||
Naveen <mailtomassnaveen@gmail.com>
|
Naveen <mailtomassnaveen@gmail.com>
|
||||||
Neekey <ni184775761@gmail.com>
|
Neekey <ni184775761@gmail.com>
|
||||||
Nekron <nekron.hyt@gmail.com>
|
Nekron <nekron.hyt@gmail.com>
|
||||||
|
Neo Tan <neotan12@hotmail.com>
|
||||||
Neto Braghetto <netow93@gmail.com>
|
Neto Braghetto <netow93@gmail.com>
|
||||||
Neverland <chenjiahan@buaa.edu.cn>
|
Neverland <chenjiahan@buaa.edu.cn>
|
||||||
Nico <nicolas@freddelacompta.com>
|
Nico <nicolas@freddelacompta.com>
|
||||||
Nidhi Agarwal <nidhi.agarwal@zomato.com>
|
Nidhi Agarwal <nidhi.agarwal@zomato.com>
|
||||||
Nihal Saxena <saxenanihal95@gmail.com>
|
Nihal Saxena <saxenanihal95@gmail.com>
|
||||||
|
Nikesh <nikesh.ramnani@gmail.com>
|
||||||
Nikita Bystrov <arttsesoft@gmail.com>
|
Nikita Bystrov <arttsesoft@gmail.com>
|
||||||
|
Nikita Marinosyan <nikita.marinosyan@gmail.com>
|
||||||
Nikitenkova <katrin_7nes7@mail.ru>
|
Nikitenkova <katrin_7nes7@mail.ru>
|
||||||
Niko Autio <niko.autio@fenten.fi>
|
Niko Autio <niko.autio@fenten.fi>
|
||||||
Nikolay <veseliy07@gmail.com>
|
Nikolay <veseliy07@gmail.com>
|
||||||
@ -551,6 +637,8 @@ Oren Kosto <orenkosto86@gmail.com>
|
|||||||
Oren Kosto <oren@panda-os.com>
|
Oren Kosto <oren@panda-os.com>
|
||||||
Orkhan Huseynli <orkhan.huseyn@outlook.com>
|
Orkhan Huseynli <orkhan.huseyn@outlook.com>
|
||||||
OuYancey <ou.yancey@gmail.com>
|
OuYancey <ou.yancey@gmail.com>
|
||||||
|
PCCCCCCC <zpc.excel@foxmail.com>
|
||||||
|
Pablo Recalde <me@pablorecalde.com>
|
||||||
Panjie Setiawan Wicaksono <panjie@panjiesw.com>
|
Panjie Setiawan Wicaksono <panjie@panjiesw.com>
|
||||||
Patrick Gidich <patrick.gidich@simnova.com>
|
Patrick Gidich <patrick.gidich@simnova.com>
|
||||||
Patryk <longer44@gmail.com>
|
Patryk <longer44@gmail.com>
|
||||||
@ -564,12 +652,16 @@ Peter Berg <atticusberg@gmail.com>
|
|||||||
Phanupong Janthapoon <panupong.jtp@gmail.com>
|
Phanupong Janthapoon <panupong.jtp@gmail.com>
|
||||||
Philip Oliver <philipodev@gmail.com>
|
Philip Oliver <philipodev@gmail.com>
|
||||||
Phyllis <escapiststupor@gmail.com>
|
Phyllis <escapiststupor@gmail.com>
|
||||||
|
Picsong <312465087@qq.com>
|
||||||
Pierre <pierre@bazoge.com>
|
Pierre <pierre@bazoge.com>
|
||||||
Pierre Neter <pierreneter@gmail.com>
|
Pierre Neter <pierreneter@gmail.com>
|
||||||
Piotr Monwid-Olechnowicz <hasparus@gmail.com>
|
Piotr Monwid-Olechnowicz <hasparus@gmail.com>
|
||||||
Piper Chester <piperchester@gmail.com>
|
Piper Chester <piperchester@gmail.com>
|
||||||
Pixy Yuan <pixy.bupt@gmail.com>
|
Pixy Yuan <pixy.bupt@gmail.com>
|
||||||
|
PlayerWho <who.zhuang@gmail.com>
|
||||||
|
Pob Ch <590650@gmail.com>
|
||||||
Pooya Parsa <pyapar@gmail.com>
|
Pooya Parsa <pyapar@gmail.com>
|
||||||
|
Primlx <primulax@live.com>
|
||||||
Pubudu Kodikara <pubudu@leafycode.com>
|
Pubudu Kodikara <pubudu@leafycode.com>
|
||||||
Pyiner <lijiuyang1992@gmail.com>
|
Pyiner <lijiuyang1992@gmail.com>
|
||||||
Pyroboomka <qwaarty@mail.ru>
|
Pyroboomka <qwaarty@mail.ru>
|
||||||
@ -597,6 +689,7 @@ Regan Langford <regan.reihana@gmail.com>
|
|||||||
Renny Ren <rennyallen@hotmail.com>
|
Renny Ren <rennyallen@hotmail.com>
|
||||||
Renovate Bot <bot@renovateapp.com>
|
Renovate Bot <bot@renovateapp.com>
|
||||||
Rex <zhangzilong.zzl@163.com>
|
Rex <zhangzilong.zzl@163.com>
|
||||||
|
Ricardo Morais <moraispgsi@gmail.com>
|
||||||
Ricardo Raphael Joson <rrjoson08@gmail.com>
|
Ricardo Raphael Joson <rrjoson08@gmail.com>
|
||||||
Richard D. Worth <rdworth@gmail.com>
|
Richard D. Worth <rdworth@gmail.com>
|
||||||
Rick Zhou <rinick@gmail.com>
|
Rick Zhou <rinick@gmail.com>
|
||||||
@ -608,6 +701,7 @@ Rohan Malhotra <rohan.root@gmail.com>
|
|||||||
Rongjian Zhang <pd4d10@gmail.com>
|
Rongjian Zhang <pd4d10@gmail.com>
|
||||||
Rrrandom <emanonhere@gmail.com>
|
Rrrandom <emanonhere@gmail.com>
|
||||||
RunningCoderLee <sprint_l@aliyun.com>
|
RunningCoderLee <sprint_l@aliyun.com>
|
||||||
|
Ryan Lee <yigexbl@gmail.com>
|
||||||
RyanHui <ryanhui1996@gmail.com>
|
RyanHui <ryanhui1996@gmail.com>
|
||||||
Régis Foucault <regisfoucault@gmail.com>
|
Régis Foucault <regisfoucault@gmail.com>
|
||||||
SHEN Lin <shenlin192@gmail.com>
|
SHEN Lin <shenlin192@gmail.com>
|
||||||
@ -622,6 +716,7 @@ Sam Lanning <sam@samlanning.com>
|
|||||||
Sam Marks <sam@sammarks.me>
|
Sam Marks <sam@sammarks.me>
|
||||||
Sam Maxwell <sam@paybase.io>
|
Sam Maxwell <sam@paybase.io>
|
||||||
Samed Düzçay <samedduzcay@gmail.com>
|
Samed Düzçay <samedduzcay@gmail.com>
|
||||||
|
Sami Mäkinen <zakarfin@gmail.com>
|
||||||
Samuel Gaus <sam@gaus.co.uk>
|
Samuel Gaus <sam@gaus.co.uk>
|
||||||
Sanghyeon Lee <yongdamsh@gmail.com>
|
Sanghyeon Lee <yongdamsh@gmail.com>
|
||||||
Sangle <whb97@163.com>
|
Sangle <whb97@163.com>
|
||||||
@ -632,14 +727,18 @@ Scott Goci <scottjg@gmail.com>
|
|||||||
Scott Sturgeon <scott@tugboatlogic.com>
|
Scott Sturgeon <scott@tugboatlogic.com>
|
||||||
Sean Lin <sean@ejoy.com>
|
Sean Lin <sean@ejoy.com>
|
||||||
Sean Willis <sean.willis@incorta.com>
|
Sean Willis <sean.willis@incorta.com>
|
||||||
|
Seba Kerckhof <seba.kerckhof@gmail.com>
|
||||||
Sebastian Blade <blade254353074@hotmail.com>
|
Sebastian Blade <blade254353074@hotmail.com>
|
||||||
Sebastian Busch <s.busch@obg-gruppe.de>
|
Sebastian Busch <s.busch@obg-gruppe.de>
|
||||||
Sebastian Busch <mail@sebastian-bus.ch>
|
Sebastian Busch <mail@sebastian-bus.ch>
|
||||||
Sebastian Busch <s.busch@qbus-enet.de>
|
Sebastian Busch <s.busch@qbus-enet.de>
|
||||||
|
Sepush <sepush@outlook.com>
|
||||||
|
Sergey Kachanovskiy <sergey.kachanovskiy@gmx.de>
|
||||||
Sergey Levkovich <gosu.87@mail.ru>
|
Sergey Levkovich <gosu.87@mail.ru>
|
||||||
Sergey Volynkin <sergey.volynkin@akvelon.com>
|
Sergey Volynkin <sergey.volynkin@akvelon.com>
|
||||||
Sergio Crisostomo <sergiosbox@gmail.com>
|
Sergio Crisostomo <sergiosbox@gmail.com>
|
||||||
Sevak <shaderzak@gmail.com>
|
Sevak <shaderzak@gmail.com>
|
||||||
|
Shanjie Chen <cnzxcsj@outlook.com>
|
||||||
Shawn Sit <xueqingxiao@gmail.com>
|
Shawn Sit <xueqingxiao@gmail.com>
|
||||||
Shengnan <baxtergu@gmail.com>
|
Shengnan <baxtergu@gmail.com>
|
||||||
ShiTengFei <shitengfei@goyoo.com>
|
ShiTengFei <shitengfei@goyoo.com>
|
||||||
@ -656,35 +755,46 @@ Sivaraj <contact@sdev.in>
|
|||||||
SkyAo <csvwolf@qq.com>
|
SkyAo <csvwolf@qq.com>
|
||||||
Skylar艺璇 <mengxue.yx@gmail.com>
|
Skylar艺璇 <mengxue.yx@gmail.com>
|
||||||
Snyk bot <github+bot@snyk.io>
|
Snyk bot <github+bot@snyk.io>
|
||||||
|
Songhn <songhn233@gmail.com>
|
||||||
Sonjeet Paul <sonjeetcp.98@gmail.com>
|
Sonjeet Paul <sonjeetcp.98@gmail.com>
|
||||||
SoraYama <sorayamahou@gmail.com>
|
SoraYama <sorayamahou@gmail.com>
|
||||||
Spencer <spjy@hawaii.edu>
|
Spencer <spjy@hawaii.edu>
|
||||||
Stanley Thijssen <stanley.thijssen@energybox.com>
|
Stanley Thijssen <stanley.thijssen@energybox.com>
|
||||||
Stanley Thijssen <stanley.thijssen@gmail.com>
|
Stanley Thijssen <stanley.thijssen@gmail.com>
|
||||||
|
Stef Schenkelaars <stef.schenkelaars@gmail.com>
|
||||||
Stephen Esser <Stephen.Esser@gmail.com>
|
Stephen Esser <Stephen.Esser@gmail.com>
|
||||||
Stevche Radevski <sradevski@live.com>
|
Stevche Radevski <sradevski@live.com>
|
||||||
|
Steven.zhong <953665604@qq.com>
|
||||||
Subroto <shub1493biswas@gmail.com>
|
Subroto <shub1493biswas@gmail.com>
|
||||||
Suki小火车 <463355954@qq.com>
|
Suki小火车 <463355954@qq.com>
|
||||||
Sumit Vekariya <sumitvekariya7@gmail.com>
|
Sumit Vekariya <sumitvekariya7@gmail.com>
|
||||||
|
Sunny Luo <sunnylqm@gmail.com>
|
||||||
Sven Efftinge <sven.efftinge@typefox.io>
|
Sven Efftinge <sven.efftinge@typefox.io>
|
||||||
|
SyMind <dacongsama@live.com>
|
||||||
SylvanasGone <397009765@qq.com>
|
SylvanasGone <397009765@qq.com>
|
||||||
TTC <345866517@qq.com>
|
TTC <345866517@qq.com>
|
||||||
Tanmoy Bhowmik <tanmoy.openroot@gmail.com>
|
Tanmoy Bhowmik <tanmoy.openroot@gmail.com>
|
||||||
Tannmay S Gupta <tanmaygup123@gmail.com>
|
Tannmay S Gupta <tanmaygup123@gmail.com>
|
||||||
Tao <magicdawn@qq.com>
|
Tao <magicdawn@qq.com>
|
||||||
Tao Zhang <windse7en@gmail.com>
|
Tao Zhang <windse7en@gmail.com>
|
||||||
|
Taucher Christoph <taucher.ch@gmail.com>
|
||||||
Taylor Sabell <taylorsabell@gmail.com>
|
Taylor Sabell <taylorsabell@gmail.com>
|
||||||
|
Ted Shin <ted.m.shin@gmail.com>
|
||||||
Teng YANG <morenyang88@gmail.com>
|
Teng YANG <morenyang88@gmail.com>
|
||||||
Teng YANG <yangteng@me.com>
|
Teng YANG <yangteng@me.com>
|
||||||
Tengjiao Cai <caitengjiao1987@gmail.com>
|
Tengjiao Cai <caitengjiao1987@gmail.com>
|
||||||
Terence <trence320@163.com>
|
Terence <trence320@163.com>
|
||||||
The Rock <zhoguoxin@126.com>
|
The Rock <zhoguoxin@126.com>
|
||||||
|
Themi Tsiotas von Pfaler <themi1234@gmail.com>
|
||||||
Theo Satloff <1golfball@gmail.com>
|
Theo Satloff <1golfball@gmail.com>
|
||||||
Thibault Derousseaux <tde@activeviam.com>
|
Thibault Derousseaux <tde@activeviam.com>
|
||||||
Thiebaud Thomas <thiebaud.tom@gmail.com>
|
Thiebaud Thomas <thiebaud.tom@gmail.com>
|
||||||
Thomas <tom@axisj.com>
|
Thomas <tom@axisj.com>
|
||||||
Thomas Ladd <thomas.ladd@stackpath.com>
|
Thomas Ladd <thomas.ladd@stackpath.com>
|
||||||
|
Thomas Zipner <thomas.zipner@gmail.com>
|
||||||
|
Tianyuan Zhang <tianyuan233.zhang@gmail.com>
|
||||||
Tino D <ginodeis@gmail.com>
|
Tino D <ginodeis@gmail.com>
|
||||||
|
Tmk <i@tmk.im>
|
||||||
Tom Gao <tom@zoomsoft.cc>
|
Tom Gao <tom@zoomsoft.cc>
|
||||||
Tom Xu <ycxzhkx@gmail.com>
|
Tom Xu <ycxzhkx@gmail.com>
|
||||||
Tom Xu <tom.xu@antcosa.com>
|
Tom Xu <tom.xu@antcosa.com>
|
||||||
@ -699,10 +809,12 @@ TsesamLi <tsesamli17@gmail.com>
|
|||||||
Ty Mick <ty@tymick.me>
|
Ty Mick <ty@tymick.me>
|
||||||
Tyler <chaotyler@gmail.com>
|
Tyler <chaotyler@gmail.com>
|
||||||
Ubaldo Quintana <blkdr@hotmail.com>
|
Ubaldo Quintana <blkdr@hotmail.com>
|
||||||
|
Uladzimir Atroshchanka <Uladzimir.Atroshchanka@vertexinc.com>
|
||||||
Vadim Macagon <vadim.macagon@gmail.com>
|
Vadim Macagon <vadim.macagon@gmail.com>
|
||||||
Valentin Vichnal <valentin@vichnal.com>
|
Valentin Vichnal <valentin@vichnal.com>
|
||||||
Van Nguyen <vnguyen94@gmail.com>
|
Van Nguyen <vnguyen94@gmail.com>
|
||||||
Varun Dey <varundey20@gmail.com>
|
Varun Dey <varundey20@gmail.com>
|
||||||
|
Varun Sharma <varunsh@stepsecurity.io>
|
||||||
Vemund Santi <vemund@santi.no>
|
Vemund Santi <vemund@santi.no>
|
||||||
Vic <709147950@qq.com>
|
Vic <709147950@qq.com>
|
||||||
Victor <saptefrativictor@gmail.com>
|
Victor <saptefrativictor@gmail.com>
|
||||||
@ -714,6 +826,7 @@ Viorel Cojocaru <vio@beanon.com>
|
|||||||
Vitaliy Mazurenko <vitaliymazurenko@gmail.com>
|
Vitaliy Mazurenko <vitaliymazurenko@gmail.com>
|
||||||
Vitaly Budovski <vbudovski@gmail.com>
|
Vitaly Budovski <vbudovski@gmail.com>
|
||||||
ViviaRui <zr1450995198@163.com>
|
ViviaRui <zr1450995198@163.com>
|
||||||
|
Vlad Vovk <wolfykey@gmail.com>
|
||||||
Vu Hoang Minh <vuhminh@gmail.com>
|
Vu Hoang Minh <vuhminh@gmail.com>
|
||||||
Vyacheslav Kamenev <vy.kamenev@gmail.com>
|
Vyacheslav Kamenev <vy.kamenev@gmail.com>
|
||||||
Walter Barbagallo <brb.walter@gmail.com>
|
Walter Barbagallo <brb.walter@gmail.com>
|
||||||
@ -725,7 +838,9 @@ Wang yb <wangyibu123@gmail.com>
|
|||||||
Warren Seymour <warren@fountainhead.tech>
|
Warren Seymour <warren@fountainhead.tech>
|
||||||
Webber Takken <webber@takken.io>
|
Webber Takken <webber@takken.io>
|
||||||
Wei Zhu <yesmeck@gmail.com>
|
Wei Zhu <yesmeck@gmail.com>
|
||||||
|
WeijieChen <cwjTerrace@163.com>
|
||||||
Wenchao Hu <zjuhwc@gmail.com>
|
Wenchao Hu <zjuhwc@gmail.com>
|
||||||
|
Wendell <wendellhu95@outlook.com>
|
||||||
Wendell <wendzhue@gmail.com>
|
Wendell <wendzhue@gmail.com>
|
||||||
Wenqi Chen <1264578441@qq.com>
|
Wenqi Chen <1264578441@qq.com>
|
||||||
Wensheng Xu <xws@superid.cn>
|
Wensheng Xu <xws@superid.cn>
|
||||||
@ -737,6 +852,7 @@ William Stein <wstein@gmail.com>
|
|||||||
WingGao <wing.gao@live.com>
|
WingGao <wing.gao@live.com>
|
||||||
Wu Haotian <whtsky@gmail.com>
|
Wu Haotian <whtsky@gmail.com>
|
||||||
WuJiali <18767152447@163.com>
|
WuJiali <18767152447@163.com>
|
||||||
|
X-Jagger <xl.jagger@gmail.com>
|
||||||
XBTop1! <xbtop1@gmail.com>
|
XBTop1! <xbtop1@gmail.com>
|
||||||
XTY <^@xty.dev>
|
XTY <^@xty.dev>
|
||||||
Xiaoming <yokiming1994@gmail.com>
|
Xiaoming <yokiming1994@gmail.com>
|
||||||
@ -744,6 +860,7 @@ Xie Guanglei <xieguanglei@hotmail.com>
|
|||||||
Xinxing Li <lixinxing.2019@bytedance.com>
|
Xinxing Li <lixinxing.2019@bytedance.com>
|
||||||
Xinzhe Wang <me@imwxz.com>
|
Xinzhe Wang <me@imwxz.com>
|
||||||
Xiping.wang <527409987@qq.com>
|
Xiping.wang <527409987@qq.com>
|
||||||
|
Xu Zhiwei <gcdxuzhiwei@gmail.com>
|
||||||
XuMM_12 <owiatsq@sina.cn>
|
XuMM_12 <owiatsq@sina.cn>
|
||||||
Xudong Cai <fifsky@gmail.com>
|
Xudong Cai <fifsky@gmail.com>
|
||||||
Xudong Huang <me@xudong.dev>
|
Xudong Huang <me@xudong.dev>
|
||||||
@ -763,11 +880,13 @@ Yu <yutingzhao1991@sina.com>
|
|||||||
Yu Mao <maoyulore@outlook.com>
|
Yu Mao <maoyulore@outlook.com>
|
||||||
Yu Mao <maoyu960320@hotmail.com>
|
Yu Mao <maoyu960320@hotmail.com>
|
||||||
YuChao Liang <l.yuch@foxmail.com>
|
YuChao Liang <l.yuch@foxmail.com>
|
||||||
|
YuTao <yutao0818@vip.qq.com>
|
||||||
Yuan <1076849402@qq.com>
|
Yuan <1076849402@qq.com>
|
||||||
Yuhang Liu <644186735@qq.com>
|
Yuhang Liu <644186735@qq.com>
|
||||||
Yulia Maximova <juliam2007@mail.ru>
|
Yulia Maximova <juliam2007@mail.ru>
|
||||||
Yunfly <120562638@qq.com>
|
Yunfly <120562638@qq.com>
|
||||||
Yunus EŞ <yunus@yunuses.com>
|
Yunus EŞ <yunus@yunuses.com>
|
||||||
|
Yunwoo Ji <unu12073@gmail.com>
|
||||||
Yuri Pirola <yuri.pirola@unimi.it>
|
Yuri Pirola <yuri.pirola@unimi.it>
|
||||||
Yury Kozyrev <urakozz@me.com>
|
Yury Kozyrev <urakozz@me.com>
|
||||||
Yusuke Ito <novi.mad@gmail.com>
|
Yusuke Ito <novi.mad@gmail.com>
|
||||||
@ -776,32 +895,40 @@ Yuxuan Huo <yuxuan.huo2011@gmail.com>
|
|||||||
YuyingWu <wuyuying1128@gmail.com>
|
YuyingWu <wuyuying1128@gmail.com>
|
||||||
ZHANGYU <723156735@qq.com>
|
ZHANGYU <723156735@qq.com>
|
||||||
ZYSzys <zyszys98@gmail.com>
|
ZYSzys <zyszys98@gmail.com>
|
||||||
|
Zach Bird <546439325@qq.com>
|
||||||
|
Zack Amiton <zamiton@outlook.com>
|
||||||
Zack Craig <zack@zack6849.com>
|
Zack Craig <zack@zack6849.com>
|
||||||
Zap <a124116186@qq.com>
|
Zap <a124116186@qq.com>
|
||||||
ZeroToOne <igeeke@163.com>
|
ZeroToOne <igeeke@163.com>
|
||||||
Zester Quinn Albano <zesterquinn.albano@gmail.com>
|
Zester Quinn Albano <zesterquinn.albano@gmail.com>
|
||||||
Zgo <zguoby@gmail.com>
|
|
||||||
Zhang Zhi <fytriht@gmail.com>
|
Zhang Zhi <fytriht@gmail.com>
|
||||||
Zheeeng <hi@zheeeng.me>
|
Zheeeng <hi@zheeeng.me>
|
||||||
Zhiqiang Gong <elory0513@hotmail.com>
|
Zhiqiang Gong <elory0513@hotmail.com>
|
||||||
|
ZhouZhen <503633021@qq.com>
|
||||||
Zhuo Chen <chenzhuo@caicloud.io>
|
Zhuo Chen <chenzhuo@caicloud.io>
|
||||||
Ziluo <gyfzzu@gmail.com>
|
Ziluo <gyfzzu@gmail.com>
|
||||||
Zohaib Ijaz <mzohaib.qc@gmail.com>
|
Zohaib Ijaz <mzohaib.qc@gmail.com>
|
||||||
Zzzen <843968788@qq.com>
|
Zzzen <843968788@qq.com>
|
||||||
|
_XiaoTian <istianlei@qq.com>
|
||||||
aLIEzsss4 <15624958088@163.com>
|
aLIEzsss4 <15624958088@163.com>
|
||||||
aashutoshrathi <aashutoshrathi@gmail.com>
|
aashutoshrathi <aashutoshrathi@gmail.com>
|
||||||
|
acfasj <acfasj@gmail.com>
|
||||||
adam <adamwu1992@163.com>
|
adam <adamwu1992@163.com>
|
||||||
afc163 <afc163@gmail.com>
|
afc163 <afc163@gmail.com>
|
||||||
agent-z <1607291079@qq.com>
|
agent-z <1607291079@qq.com>
|
||||||
|
aghArdeshir <ardeshireo@gmail.com>
|
||||||
ahalimkara <ahalimkara@gmail.com>
|
ahalimkara <ahalimkara@gmail.com>
|
||||||
|
ajuner <106791576@qq.com>
|
||||||
alekslario <aleksandlario@gmail.com>
|
alekslario <aleksandlario@gmail.com>
|
||||||
alex89lj <379118572@qq.com>
|
alex89lj <379118572@qq.com>
|
||||||
alexchen <alexchen@easyops.cn>
|
alexchen <alexchen@easyops.cn>
|
||||||
amedora <americandragsterracing@gmail.com>
|
amedora <americandragsterracing@gmail.com>
|
||||||
|
aoxiang78 <ao_xiang@live.com>
|
||||||
appleshell <appleshell@outlook.com>
|
appleshell <appleshell@outlook.com>
|
||||||
arange <panpan2558@gmail.com>
|
arange <panpan2558@gmail.com>
|
||||||
arifemrecelik <ce.arifemre@gmail.com>
|
arifemrecelik <ce.arifemre@gmail.com>
|
||||||
arturpfb <arturpfb@gmail.com>
|
arturpfb <arturpfb@gmail.com>
|
||||||
|
ascodelife <394922886@qq.com>
|
||||||
ascoders <576625322@qq.com>
|
ascoders <576625322@qq.com>
|
||||||
ashishg-qburst <ashishg@qburst.com>
|
ashishg-qburst <ashishg@qburst.com>
|
||||||
atomoo <yangpein@gmail.com>
|
atomoo <yangpein@gmail.com>
|
||||||
@ -812,9 +939,11 @@ baidumap <460807394@qq.com>
|
|||||||
bang <sqibang@gmail.com>
|
bang <sqibang@gmail.com>
|
||||||
baozefeng <727751065@qq.com>
|
baozefeng <727751065@qq.com>
|
||||||
bcd337 <b.bcd337@gmail.com>
|
bcd337 <b.bcd337@gmail.com>
|
||||||
|
benben <jinwentao0914@dingtalk.com>
|
||||||
bigbigbo <zxb141242@163.com>
|
bigbigbo <zxb141242@163.com>
|
||||||
binyellow <571704908@qq.com>
|
binyellow <571704908@qq.com>
|
||||||
blankzust <450811238@qq.com>
|
blankzust <450811238@qq.com>
|
||||||
|
btea <2356281422@qq.com>
|
||||||
bukas <yhz1219@gmail.com>
|
bukas <yhz1219@gmail.com>
|
||||||
byuanama <byuan@ama.com.au>
|
byuanama <byuan@ama.com.au>
|
||||||
byzyk <bohdan.kh@gmail.com>
|
byzyk <bohdan.kh@gmail.com>
|
||||||
@ -827,6 +956,7 @@ cc189 <cc189dev@gmail.com>
|
|||||||
chaofeis <408067385@qq.com>
|
chaofeis <408067385@qq.com>
|
||||||
chchen <cc272309126@gmail.com>
|
chchen <cc272309126@gmail.com>
|
||||||
chen wen jun <731028571@qq.com>
|
chen wen jun <731028571@qq.com>
|
||||||
|
chen-jingjie <2383844893@qq.com>
|
||||||
chencheng (云谦) <sorrycc@gmail.com>
|
chencheng (云谦) <sorrycc@gmail.com>
|
||||||
chenlei <745512023@qq.com>
|
chenlei <745512023@qq.com>
|
||||||
chenlong <long.chen@abssqr.com>
|
chenlong <long.chen@abssqr.com>
|
||||||
@ -850,6 +980,7 @@ davidhatten <david.r.hatten@gmail.com>
|
|||||||
ddcat1115 <ddcat1115@gmail.com>
|
ddcat1115 <ddcat1115@gmail.com>
|
||||||
decade <decadef20@gmail.com>
|
decade <decadef20@gmail.com>
|
||||||
delesseps <andrewlessels@gmail.com>
|
delesseps <andrewlessels@gmail.com>
|
||||||
|
dengqing <1247748612@qq.com>
|
||||||
denzw <denzw@21cn.com>
|
denzw <denzw@21cn.com>
|
||||||
dependabot[bot] <support@dependabot.com>
|
dependabot[bot] <support@dependabot.com>
|
||||||
desperado <yuwei_149@163.com>
|
desperado <yuwei_149@163.com>
|
||||||
@ -861,6 +992,7 @@ djorkaeff <djorkae55@gmail.com>
|
|||||||
dolfje <nikosverschore@gmail.com>
|
dolfje <nikosverschore@gmail.com>
|
||||||
douxc <douxc512@gmail.com>
|
douxc <douxc512@gmail.com>
|
||||||
dpyzo0o <yang.xu940121@outlook.com>
|
dpyzo0o <yang.xu940121@outlook.com>
|
||||||
|
dujun <emolingzhu@126.com>
|
||||||
duzliang <duzliang@gmail.com>
|
duzliang <duzliang@gmail.com>
|
||||||
edgji <j.edgji@gmail.com>
|
edgji <j.edgji@gmail.com>
|
||||||
eidonjoe <806488716@qq.com>
|
eidonjoe <806488716@qq.com>
|
||||||
@ -877,11 +1009,14 @@ flashback313 <windmark2012@gmail.com>
|
|||||||
flyerH <hzw758@qq.com>
|
flyerH <hzw758@qq.com>
|
||||||
frezc <504021398@qq.com>
|
frezc <504021398@qq.com>
|
||||||
gaoryrt <gaoryrt@gmail.com>
|
gaoryrt <gaoryrt@gmail.com>
|
||||||
|
gaozhenqian <837856276@qq.com>
|
||||||
genie <genie88@163.com>
|
genie <genie88@163.com>
|
||||||
|
gepd <guillermoepd@hotmail.com>
|
||||||
godfather <greenday.wj@foxmail.com>
|
godfather <greenday.wj@foxmail.com>
|
||||||
gregahren <grega.hren@gmail.com>
|
gregahren <grega.hren@gmail.com>
|
||||||
gxvv <gaoxin18000@gmail.com>
|
gxvv <gaoxin18000@gmail.com>
|
||||||
gyh9457 <gyh9457@163.com>
|
gyh9457 <gyh9457@163.com>
|
||||||
|
gzq <zguoby@gmail.com>
|
||||||
haianweifeng <1531297152@qq.com>
|
haianweifeng <1531297152@qq.com>
|
||||||
haimrait <haimrait@gmail.com>
|
haimrait <haimrait@gmail.com>
|
||||||
handy <lihandi@gmail.com>
|
handy <lihandi@gmail.com>
|
||||||
@ -895,6 +1030,7 @@ hauwa123 <hauwa.aminu@outlook.com>
|
|||||||
hebingchang <hebingchang1@live.com>
|
hebingchang <hebingchang1@live.com>
|
||||||
hehe <xpc1993@gmail.com>
|
hehe <xpc1993@gmail.com>
|
||||||
hehe <xpc_kacl@163.com>
|
hehe <xpc_kacl@163.com>
|
||||||
|
hello-chinese <841030329@qq.com>
|
||||||
henryv0 <henryvo94@gmail.com>
|
henryv0 <henryvo94@gmail.com>
|
||||||
hi-caicai <hi@cai-cai.me>
|
hi-caicai <hi@cai-cai.me>
|
||||||
hicrystal <295247343@qq.com>
|
hicrystal <295247343@qq.com>
|
||||||
@ -904,6 +1040,8 @@ huangyan.py <huangyan.py@bytedance.com>
|
|||||||
hugorezende <hugorezendedev@gmail.com>
|
hugorezende <hugorezendedev@gmail.com>
|
||||||
huishiyi <zhou1maple@gmail.com>
|
huishiyi <zhou1maple@gmail.com>
|
||||||
huzzbuzz <huzzbuzz@outlook.com>
|
huzzbuzz <huzzbuzz@outlook.com>
|
||||||
|
hydraZty <670688667@qq.com>
|
||||||
|
i3web <itnote@qq.com>
|
||||||
iamcastelli <sowed@cyberdude.com>
|
iamcastelli <sowed@cyberdude.com>
|
||||||
iamkun <kunhello@outlook.com>
|
iamkun <kunhello@outlook.com>
|
||||||
ibrahim velinov <ibsukru@gmail.com>
|
ibrahim velinov <ibsukru@gmail.com>
|
||||||
@ -912,6 +1050,8 @@ int2d <int2d@qq.com>
|
|||||||
iojichervo <ioji@chervonagura.com.ar>
|
iojichervo <ioji@chervonagura.com.ar>
|
||||||
ioldfish <fish.wangl@gmail.com>
|
ioldfish <fish.wangl@gmail.com>
|
||||||
iorikingdom <iorikingdom@hotmail.com>
|
iorikingdom <iorikingdom@hotmail.com>
|
||||||
|
isakol <isakol@kth.se>
|
||||||
|
itibbers <jxn2014@gmail.com>
|
||||||
iugo <iugogogo@gmail.com>
|
iugo <iugogogo@gmail.com>
|
||||||
j3l11234 <297259024@qq.com>
|
j3l11234 <297259024@qq.com>
|
||||||
jasonslyvia <jasonslyvia@gmail.com>
|
jasonslyvia <jasonslyvia@gmail.com>
|
||||||
@ -925,11 +1065,11 @@ jieniu$ <jienius@outlook.com>
|
|||||||
jinouwuque <ee2win@gmail.com>
|
jinouwuque <ee2win@gmail.com>
|
||||||
jinyaqiao1102 <405782493@QQ.com>
|
jinyaqiao1102 <405782493@QQ.com>
|
||||||
jojoLockLock <miffyschou@sina.com>
|
jojoLockLock <miffyschou@sina.com>
|
||||||
|
jueinin <1014397160@qq.com>
|
||||||
junjing.zhang <zhangjunjing@gmail.com>
|
junjing.zhang <zhangjunjing@gmail.com>
|
||||||
kacjay <45483388@qq.com>
|
kacjay <45483388@qq.com>
|
||||||
kaifei <150641329@qq.com>
|
kaifei <150641329@qq.com>
|
||||||
kailunyao <kailunyao@163.com>
|
kailunyao <kailunyao@163.com>
|
||||||
kanweiwei <kwwnjujlc@sina.com>
|
|
||||||
kanweiwei <475801900@qq.com>
|
kanweiwei <475801900@qq.com>
|
||||||
kaoding <41830859@qq.com>
|
kaoding <41830859@qq.com>
|
||||||
kasinooya <kasinooya@gmail.com>
|
kasinooya <kasinooya@gmail.com>
|
||||||
@ -940,6 +1080,7 @@ kdepp <kdepp.cd@gmail.com>
|
|||||||
keng <keng@renderinghouse.com>
|
keng <keng@renderinghouse.com>
|
||||||
kenve <zwei.xie@gmail.com>
|
kenve <zwei.xie@gmail.com>
|
||||||
kermolaev <kermolaev@cloudally.com>
|
kermolaev <kermolaev@cloudally.com>
|
||||||
|
kily zhou <keeliizhou@gmail.com>
|
||||||
klouskingsley <harry_tse@163.com>
|
klouskingsley <harry_tse@163.com>
|
||||||
ko <git@yaksok.net>
|
ko <git@yaksok.net>
|
||||||
konakona <lovekonakona@gmail.com>
|
konakona <lovekonakona@gmail.com>
|
||||||
@ -962,6 +1103,7 @@ liekkas <zjq0717@163.com>
|
|||||||
lihqi <455711093@qq.com>
|
lihqi <455711093@qq.com>
|
||||||
lilun <lilun_cd@keruyun.com>
|
lilun <lilun_cd@keruyun.com>
|
||||||
limingxin <906529775@qq.com>
|
limingxin <906529775@qq.com>
|
||||||
|
lisenenkov <lisenenkov@mail.ru>
|
||||||
littleLane <857183384@qq.com>
|
littleLane <857183384@qq.com>
|
||||||
liuchuzhang <liuweiminer@hotmail.com>
|
liuchuzhang <liuweiminer@hotmail.com>
|
||||||
liuchuzhang <liuweiminer@126.com>
|
liuchuzhang <liuweiminer@126.com>
|
||||||
@ -975,6 +1117,7 @@ luyiming <luyimingchn@gmail.com>
|
|||||||
lvren <luren6049@qq.com>
|
lvren <luren6049@qq.com>
|
||||||
lxnxbnq <yuanddmail@163.com>
|
lxnxbnq <yuanddmail@163.com>
|
||||||
lyhper <lyhper@gmail.com>
|
lyhper <lyhper@gmail.com>
|
||||||
|
lyon.han <lyon.han.china@outlook.com>
|
||||||
mArker <252133226@qq.com>
|
mArker <252133226@qq.com>
|
||||||
maks <pine3ree@gmail.com>
|
maks <pine3ree@gmail.com>
|
||||||
maximest-pierre <me@maximest-pierre.me>
|
maximest-pierre <me@maximest-pierre.me>
|
||||||
@ -982,6 +1125,7 @@ melchior voidwolf <kmno4k2mno4@gmail.com>
|
|||||||
memoryza <jincai.wang@foxmail.com>
|
memoryza <jincai.wang@foxmail.com>
|
||||||
mgrdevport <mgrdevport@gmail.com>
|
mgrdevport <mgrdevport@gmail.com>
|
||||||
mingyan.yu <mingyan.yu@wormpex.com>
|
mingyan.yu <mingyan.yu@wormpex.com>
|
||||||
|
miracles1919 <516571350@qq.com>
|
||||||
mjfwebb <bugeyedboy@gmail.com>
|
mjfwebb <bugeyedboy@gmail.com>
|
||||||
mkermani144 <mkermani144@gmail.com>
|
mkermani144 <mkermani144@gmail.com>
|
||||||
mmmveggies <jakeselig@gmail.com>
|
mmmveggies <jakeselig@gmail.com>
|
||||||
@ -993,6 +1137,7 @@ mumiao <mumiao@dtstack.com>
|
|||||||
mushan0x0 <mushan0x0@gmail.com>
|
mushan0x0 <mushan0x0@gmail.com>
|
||||||
muzuiget <muzuiget@gmail.com>
|
muzuiget <muzuiget@gmail.com>
|
||||||
natergj <nater_nater@me.com>
|
natergj <nater_nater@me.com>
|
||||||
|
netcon <netcon@live.com>
|
||||||
ngolin <poodll@163.com>
|
ngolin <poodll@163.com>
|
||||||
nick-ChenZe <chenze2168@gmail.com>
|
nick-ChenZe <chenze2168@gmail.com>
|
||||||
niko <644506165@qq.com>
|
niko <644506165@qq.com>
|
||||||
@ -1003,6 +1148,7 @@ oldchicken <www.chao3208525@qq.com>
|
|||||||
paleface001 <liuye10@yahoo.com>
|
paleface001 <liuye10@yahoo.com>
|
||||||
paranoidjk <hust2012jiangkai@gmail.com>
|
paranoidjk <hust2012jiangkai@gmail.com>
|
||||||
parlop <parlop@gmail.com>
|
parlop <parlop@gmail.com>
|
||||||
|
paul <34345790@qq.com>
|
||||||
pbrink231 <pbrink231@gmail.com>
|
pbrink231 <pbrink231@gmail.com>
|
||||||
peiming <hyrijk@gmail.com>
|
peiming <hyrijk@gmail.com>
|
||||||
pengtikui <949828390@qq.com>
|
pengtikui <949828390@qq.com>
|
||||||
@ -1022,6 +1168,7 @@ qramilq <ramirez99@mail.ru>
|
|||||||
qubaoming <qubaoming@didichuxing.com>
|
qubaoming <qubaoming@didichuxing.com>
|
||||||
ravirambles <ravirambles@gmail.com>
|
ravirambles <ravirambles@gmail.com>
|
||||||
realEago <774855001@qq.com>
|
realEago <774855001@qq.com>
|
||||||
|
renzhao1113 <547249523@qq.com>
|
||||||
richardison <richard.ison@carleton.ca>
|
richardison <richard.ison@carleton.ca>
|
||||||
ryangun <ryangun@foxmail.com>
|
ryangun <ryangun@foxmail.com>
|
||||||
ryanhoho <hswacoal@gmail.com>
|
ryanhoho <hswacoal@gmail.com>
|
||||||
@ -1031,6 +1178,7 @@ sallen450 <jqh101@sina.com>
|
|||||||
samir elsharkawy <samir.elsharkawy@gmail.com>
|
samir elsharkawy <samir.elsharkawy@gmail.com>
|
||||||
sdli <1669375803@qq.com>
|
sdli <1669375803@qq.com>
|
||||||
seognil LC <seognil@gmail.com>
|
seognil LC <seognil@gmail.com>
|
||||||
|
serializedowen <wjh199455@gmail.com>
|
||||||
sfturing <sfturing@gmail.com>
|
sfturing <sfturing@gmail.com>
|
||||||
shangyuan.ning <shangyuan.ning@manaowan.com>
|
shangyuan.ning <shangyuan.ning@manaowan.com>
|
||||||
shawtung <shawtung@qq.com>
|
shawtung <shawtung@qq.com>
|
||||||
@ -1045,8 +1193,10 @@ snadn <snadn@snadn.cn>
|
|||||||
snail <120216220@qq.com>
|
snail <120216220@qq.com>
|
||||||
soeyi <sixinlei0927@gmail.com>
|
soeyi <sixinlei0927@gmail.com>
|
||||||
sojournerc <cmeyer@zvelo.com>
|
sojournerc <cmeyer@zvelo.com>
|
||||||
|
soso <ethdud1@gmail.com>
|
||||||
sosohime <theziming@126.com>
|
sosohime <theziming@126.com>
|
||||||
spideeee <spideeee@github.com>
|
spideeee <spideeee@github.com>
|
||||||
|
stefango <nankongyinan@gmail.com>
|
||||||
stevenyuysy <stevenyuysy@gmail.com>
|
stevenyuysy <stevenyuysy@gmail.com>
|
||||||
stickmy <stickmyc@gmail.com>
|
stickmy <stickmyc@gmail.com>
|
||||||
susiwen8 <susiwen8@gmail.com>
|
susiwen8 <susiwen8@gmail.com>
|
||||||
@ -1067,7 +1217,10 @@ toshi1127 <toshi.matsumoto.2n@stu.hosei.ac.jp>
|
|||||||
twobin <twobin@live.com>
|
twobin <twobin@live.com>
|
||||||
u3u <qwq@qwq.cat>
|
u3u <qwq@qwq.cat>
|
||||||
ubuntugod <adarshron@gmail.com>
|
ubuntugod <adarshron@gmail.com>
|
||||||
|
uchanlee <uchanlee.dev@gmail.com>
|
||||||
|
undefined <johann@objekt.stream>
|
||||||
undefined <undefined>
|
undefined <undefined>
|
||||||
|
unknown <tongsiyuan@corp.netease.com>
|
||||||
unknown <chenyizhongx@gmail.com>
|
unknown <chenyizhongx@gmail.com>
|
||||||
ustccjw <317713370@qq.com>
|
ustccjw <317713370@qq.com>
|
||||||
vagusX <vagusxl@gmail.com>
|
vagusX <vagusxl@gmail.com>
|
||||||
@ -1075,10 +1228,15 @@ valleykid <valleykiddy@gmail.com>
|
|||||||
vaytsel <vaytsel@gmail.com>
|
vaytsel <vaytsel@gmail.com>
|
||||||
veveue <veveue@dingtalk.com>
|
veveue <veveue@dingtalk.com>
|
||||||
vgeyi <vgeyiz@126.com>
|
vgeyi <vgeyiz@126.com>
|
||||||
|
vldh <lidahao@sisyphe.com.cn>
|
||||||
vldh <alwaysloseall@sina.com>
|
vldh <alwaysloseall@sina.com>
|
||||||
vouis <16nding@gmail.com>
|
vouis <16nding@gmail.com>
|
||||||
wa-ri <tztl1995@gmail.com>
|
wa-ri <tztl1995@gmail.com>
|
||||||
wadezhan <wadezhan@tencent.com>
|
wadezhan <wadezhan@tencent.com>
|
||||||
|
wan wan <wancihua@qq.com>
|
||||||
|
wangao <jameslahm17@gmail.com>
|
||||||
|
wangao <1366463855@qq.com>
|
||||||
|
wangao <wa17@mails.tsinghua.edu.cn>
|
||||||
wangshantao <605682551@qq.com>
|
wangshantao <605682551@qq.com>
|
||||||
wangshuai <wangshuai@momenta.ai>
|
wangshuai <wangshuai@momenta.ai>
|
||||||
wangtao0101 <yuecjn@gmail.com>
|
wangtao0101 <yuecjn@gmail.com>
|
||||||
@ -1093,6 +1251,7 @@ wendellhu <wendellhu95@gmail.com>
|
|||||||
wenhong <wenhong.zw@antfin.com>
|
wenhong <wenhong.zw@antfin.com>
|
||||||
whinc <whincwu@163.com>
|
whinc <whincwu@163.com>
|
||||||
whtang906 <whtang906@gmail.com>
|
whtang906 <whtang906@gmail.com>
|
||||||
|
whwangms <whwangms@outlook.com>
|
||||||
willc001 <will.c001@163.com>
|
willc001 <will.c001@163.com>
|
||||||
wizawu <wizawu@gmail.com>
|
wizawu <wizawu@gmail.com>
|
||||||
wleven <408493323@qq.com>
|
wleven <408493323@qq.com>
|
||||||
@ -1117,6 +1276,8 @@ y-take <y.takey@gmail.com>
|
|||||||
yanguoyu <841185308@qq.com>
|
yanguoyu <841185308@qq.com>
|
||||||
yangwukang <yangwukang@boco.com.cn>
|
yangwukang <yangwukang@boco.com.cn>
|
||||||
yangxiaolin <yangxiao2810279802@gmail.com>
|
yangxiaolin <yangxiao2810279802@gmail.com>
|
||||||
|
yanm1ng <644169721@qq.com>
|
||||||
|
yaoweiprc <yaoweiprc@hotmail.com>
|
||||||
ycjcl868 <45808948@qq.com>
|
ycjcl868 <45808948@qq.com>
|
||||||
ye4241 <ye4241@gmail.com>
|
ye4241 <ye4241@gmail.com>
|
||||||
yehq <yedi728@qq.com>
|
yehq <yedi728@qq.com>
|
||||||
@ -1125,7 +1286,9 @@ yeshan333 <1329441308@qq.com>
|
|||||||
yibu.wang <yibu.wang@orion.co.com>
|
yibu.wang <yibu.wang@orion.co.com>
|
||||||
yiminanci <yiminanci@gmail.com>
|
yiminanci <yiminanci@gmail.com>
|
||||||
yiminghe <yiminghe@gmail.com>
|
yiminghe <yiminghe@gmail.com>
|
||||||
|
yingxirz <inseeing@gmail.com>
|
||||||
youmoo <youmoo@vellichor.me>
|
youmoo <youmoo@vellichor.me>
|
||||||
|
youngz <chinayangzhan@126.com>
|
||||||
yuche <i@yuche.me>
|
yuche <i@yuche.me>
|
||||||
yuezk <yuezk001@gmail.com>
|
yuezk <yuezk001@gmail.com>
|
||||||
yui <1151815317@qq.com>
|
yui <1151815317@qq.com>
|
||||||
@ -1141,19 +1304,23 @@ zhangpc <zhangpc@tenxcloud.com>
|
|||||||
zhangyangxue <383632607@qq.com>
|
zhangyangxue <383632607@qq.com>
|
||||||
zhangyanling77 <18783226594@163.com>
|
zhangyanling77 <18783226594@163.com>
|
||||||
zhangzh <zhangzh@cnlemon.net>
|
zhangzh <zhangzh@cnlemon.net>
|
||||||
|
zhao-huo-long <lijiuyi1995@outlook.com>
|
||||||
zhaocai <lzc09008@gmail.com>
|
zhaocai <lzc09008@gmail.com>
|
||||||
zhaopeidong <lwindscar@gmail.com>
|
zhaopeidong <lwindscar@gmail.com>
|
||||||
|
zhenfan.yu <fanerge@qq.com>
|
||||||
zhuguibiao <505418722@qq.com>
|
zhuguibiao <505418722@qq.com>
|
||||||
zhujun24 <zhujun87654321@gmail.com>
|
zhujun24 <zhujun87654321@gmail.com>
|
||||||
|
zhyupe <zyp108421@gmail.com>
|
||||||
zilong <jzlxiaohei@163.com>
|
zilong <jzlxiaohei@163.com>
|
||||||
zinkey <yaya@uloveit.com.cn>
|
zinkey <yaya@uloveit.com.cn>
|
||||||
zj9495 <zj9495@gmail.com>
|
zj9495 <zj9495@gmail.com>
|
||||||
zjf <zjffun@gmail.com>
|
|
||||||
zkwolf <chenhao5866@gmail.com>
|
zkwolf <chenhao5866@gmail.com>
|
||||||
zlljqn <zlljqn@gmail.com>
|
zlljqn <zlljqn@gmail.com>
|
||||||
zollero <corona7@163.com>
|
zollero <corona7@163.com>
|
||||||
|
zombiej <smith3816@gmail.com>
|
||||||
zongzi531 <zongzi.xy@gmail.com>
|
zongzi531 <zongzi.xy@gmail.com>
|
||||||
zoomdong <1344492820@qq.com>
|
zoomdong <1344492820@qq.com>
|
||||||
|
zqran <uuxnet@gmail.com>
|
||||||
ztplz <mysticzt@gmail.com>
|
ztplz <mysticzt@gmail.com>
|
||||||
zuiidea <zuiiidea@gmail.com>
|
zuiidea <zuiiidea@gmail.com>
|
||||||
zx6658 <zx6658@naver.com>
|
zx6658 <zx6658@naver.com>
|
||||||
@ -1167,9 +1334,10 @@ zytjs <yitongzhao@163.com>
|
|||||||
不吃猫的鱼 <michael2ib1989@gmail.com>
|
不吃猫的鱼 <michael2ib1989@gmail.com>
|
||||||
丶尘殇 <sean.snow@live.com>
|
丶尘殇 <sean.snow@live.com>
|
||||||
乔奕轩 <qiao_yixuan@163.com>
|
乔奕轩 <qiao_yixuan@163.com>
|
||||||
|
九思⚡⚡⚡ <2228429150@qq.com>
|
||||||
二哲 <kodo@forchange.cn>
|
二哲 <kodo@forchange.cn>
|
||||||
二手掉包工程师 <rustin.liu@gmail.com>
|
二手掉包工程师 <rustin.liu@gmail.com>
|
||||||
二货机器人 <smith3816@gmail.com>
|
云剪者 <584518260@qq.com>
|
||||||
付引 <xxxquotes@gmail.com>
|
付引 <xxxquotes@gmail.com>
|
||||||
何乐 <work@imhele.com>
|
何乐 <work@imhele.com>
|
||||||
何志勇 <15988134176@163.com>
|
何志勇 <15988134176@163.com>
|
||||||
@ -1199,25 +1367,31 @@ zytjs <yitongzhao@163.com>
|
|||||||
廖应龙 <vigossliao@gmail.com>
|
廖应龙 <vigossliao@gmail.com>
|
||||||
廖星 <liaoxing.lx@bytedance.com>
|
廖星 <liaoxing.lx@bytedance.com>
|
||||||
张大大 <249812928@qq.com>
|
张大大 <249812928@qq.com>
|
||||||
|
张威 <1051127659@qq.com>
|
||||||
张秀玲 <18811794335@163.com>
|
张秀玲 <18811794335@163.com>
|
||||||
徐坤龙 <272992168@qq.com>
|
徐坤龙 <272992168@qq.com>
|
||||||
徐新航 <xuxinhang@bytedance.com>
|
徐新航 <xuxinhang@bytedance.com>
|
||||||
愚道 <tingzhao.ytz@antfin.com>
|
愚道 <tingzhao.ytz@antfin.com>
|
||||||
曾凯 <zengkai2009@foxmail.com>
|
曾凯 <zengkai2009@foxmail.com>
|
||||||
|
期贤 <qixian.cs@antgroup.com>
|
||||||
朮厃 <cn.ah.liu@gmail.com>
|
朮厃 <cn.ah.liu@gmail.com>
|
||||||
李环冀 <158757774@qq.com>
|
李环冀 <158757774@qq.com>
|
||||||
|
杨兴洲 <dr2009.china@gmail.com>
|
||||||
杨哲迪 <yangzhedi@yidian-inc.com>
|
杨哲迪 <yangzhedi@yidian-inc.com>
|
||||||
杨小事er <Uiryzd@163.com>
|
杨小事er <Uiryzd@163.com>
|
||||||
松子 <window.pibarr@gmail.com>
|
松子 <window.pibarr@gmail.com>
|
||||||
|
林煌东 <10543563@qq.com>
|
||||||
柚子男 <yozman@sina.com>
|
柚子男 <yozman@sina.com>
|
||||||
沐霖 <304647173@qq.com>
|
沐霖 <304647173@qq.com>
|
||||||
爱but的苍蝇 <354788473@qq.com>
|
爱but的苍蝇 <354788473@qq.com>
|
||||||
王林涛 <hzwanglintao@corp.netease.com>
|
王林涛 <hzwanglintao@corp.netease.com>
|
||||||
|
王浩 <boomler@hotmail.com>
|
||||||
王集鹄 <wjhu111@21cn.com>
|
王集鹄 <wjhu111@21cn.com>
|
||||||
琚致远 <juzhiyuan@apache.org>
|
琚致远 <juzhiyuan@apache.org>
|
||||||
白羊座小葛 <abeyuhang@gmail.com>
|
白羊座小葛 <abeyuhang@gmail.com>
|
||||||
砖家 <brickspert.fjl@antfin.com>
|
砖家 <brickspert.fjl@antfin.com>
|
||||||
砖家 <576679268@qq.com>
|
砖家 <576679268@qq.com>
|
||||||
|
章鱼 <ryker.zy@gmail.com>
|
||||||
竹尔 <Juelchiang@gmail.com>
|
竹尔 <Juelchiang@gmail.com>
|
||||||
米老朱 <laozhu.me@gmail.com>
|
米老朱 <laozhu.me@gmail.com>
|
||||||
精武陈真 <546369005@qq.com>
|
精武陈真 <546369005@qq.com>
|
||||||
@ -1232,11 +1406,12 @@ zytjs <yitongzhao@163.com>
|
|||||||
蔡伦 <sliuqin@gmail.com>
|
蔡伦 <sliuqin@gmail.com>
|
||||||
薛定谔的猫 <weiran.zsd@outlook.com>
|
薛定谔的猫 <weiran.zsd@outlook.com>
|
||||||
薛定谔的猫 <hh_2013@foxmail.com>
|
薛定谔的猫 <hh_2013@foxmail.com>
|
||||||
诸岳 <fuping.dfp@antgroup.com>
|
|
||||||
诸岳 <fuping.dfp@antfin.com>
|
诸岳 <fuping.dfp@antfin.com>
|
||||||
|
诸岳 <fuping.dfp@antgroup.com>
|
||||||
诸岳 <dengfuping_private@163.com>
|
诸岳 <dengfuping_private@163.com>
|
||||||
诸岳 <dengfuping_develop@163.com>
|
诸岳 <dengfuping_develop@163.com>
|
||||||
诸葛龙 <158362530@qq.com>
|
诸葛龙 <158362530@qq.com>
|
||||||
|
谭真 <736420282@qq.com>
|
||||||
超能刚哥 <margox@foxmail.com>
|
超能刚哥 <margox@foxmail.com>
|
||||||
迷渡 <justjavac@gmail.com>
|
迷渡 <justjavac@gmail.com>
|
||||||
郑旭 <332171564@qq.com>
|
郑旭 <332171564@qq.com>
|
||||||
@ -1254,7 +1429,9 @@ zytjs <yitongzhao@163.com>
|
|||||||
骗你是小猫咪 <darryshaw@gmail.com>
|
骗你是小猫咪 <darryshaw@gmail.com>
|
||||||
高力 <3071730@qq.com>
|
高力 <3071730@qq.com>
|
||||||
鬼厉 <shawdanon@qq.com>
|
鬼厉 <shawdanon@qq.com>
|
||||||
|
麦谷 <1141453778@qq.com>
|
||||||
黄俊亮 <jayhuang@easyops.cn>
|
黄俊亮 <jayhuang@easyops.cn>
|
||||||
黄文鉴 <concefly@foxmail.com>
|
黄文鉴 <concefly@foxmail.com>
|
||||||
黄斌 <bin.huang02@hand-china.com>
|
黄斌 <bin.huang02@hand-china.com>
|
||||||
|
黑雨 <wangning4567@163.com>
|
||||||
龚方闻 <fangwen.gong@baishancloud.com>
|
龚方闻 <fangwen.gong@baishancloud.com>
|
@ -15,6 +15,96 @@ timeline: true
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 4.20.2
|
||||||
|
|
||||||
|
`2022-04-30`
|
||||||
|
|
||||||
|
- Segmented
|
||||||
|
- 🐞 Fix Segmented inconsisit height with other controls. [#35281](https://github.com/ant-design/ant-design/pull/35281)
|
||||||
|
- 🐞 Fix Segmented animation not working correct in StrictMode mode. [#35281](https://github.com/ant-design/ant-design/pull/35281)
|
||||||
|
- 🆕 Segmented `options` now supports `icon` property. [#35256](https://github.com/ant-design/ant-design/pull/35256)
|
||||||
|
- Table
|
||||||
|
- ⌨️ Improve Table columns sorter a11y experience. [#35269](https://github.com/ant-design/ant-design/pull/35269)
|
||||||
|
- 🇪🇸 Added Table filter localization for es_ES. [#35309](https://github.com/ant-design/ant-design/pull/35309) [@agarciaguillo](https://github.com/agarciaguillo)
|
||||||
|
- 💄 Fix Switch color in dark theme. [#35332](https://github.com/ant-design/ant-design/pull/35332)
|
||||||
|
- 💄 Tweak Breadcrumb link hover color. [#35324](https://github.com/ant-design/ant-design/pull/35324)
|
||||||
|
- 🐞 Fix Space throws `Encountered two children with the same key` warning in some cases. [#35311](https://github.com/ant-design/ant-design/pull/35311)
|
||||||
|
- 🐞 Fix Select tag remove icon position issue. [#35336](https://github.com/ant-design/ant-design/pull/35336) [@walidcherhane](https://github.com/walidcherhane)
|
||||||
|
|
||||||
|
## 4.20.1
|
||||||
|
|
||||||
|
`2022-04-26`
|
||||||
|
|
||||||
|
- 🐞 Fix Breadcrumb extra padding and margin style. [#35235](https://github.com/ant-design/ant-design/pull/35235)
|
||||||
|
- 🐞 Fix Input.Seach inconsistent behavior of triggering `onSearch` when press enter using Chinese inputting method. [#35164](https://github.com/ant-design/ant-design/pull/35164) [@qyzzzz](https://github.com/qyzzzz)
|
||||||
|
- 🐞 Fix circle reference between Upload and Dragger. [#34379](https://github.com/ant-design/ant-design/pull/34379) [@kanweiwei](https://github.com/kanweiwei)
|
||||||
|
|
||||||
|
## 4.20.0
|
||||||
|
|
||||||
|
`2022-04-24`
|
||||||
|
|
||||||
|
- 🔥 React 18 Support. Fix related known issue.
|
||||||
|
- 🐞 Fix Form with React 18 StrictMode missing error message update. [#35096](https://github.com/ant-design/ant-design/pull/35096)
|
||||||
|
- 🐞 Fix Notification and Message throw `createRoot` warning in React 18. [#35030](https://github.com/ant-design/ant-design/pull/35030)
|
||||||
|
- 🐞 Fix BackTop not working in StrictMode. [#34858](https://github.com/ant-design/ant-design/pull/34858) [@tmkx](https://github.com/tmkx)
|
||||||
|
- 🔥 New component Segmented. [#34319](https://github.com/ant-design/ant-design/pull/34319)
|
||||||
|
- 🛠 Since v4.20.0 `Segemented` props `onChange` callback function parameter adjusted from `ChangeEvent` (v4.20.0-alpha.0, v4.20.0-alpha.1) to `value` to simplify API. [#35187](https://github.com/ant-design/ant-design/pull/35187) [@vagusX](https://github.com/vagusX)
|
||||||
|
- Form
|
||||||
|
- 🔥 Form support `useWatch` to get current field value. [#35036](https://github.com/ant-design/ant-design/pull/35036)
|
||||||
|
- 🆕 Form support `useFormInstance` to get current context form instance. [#35039](https://github.com/ant-design/ant-design/pull/35039)
|
||||||
|
- 💄 Fix Form broken layout when set `labelCol={{ sm: 24 }}` and `wrapperCol={{ sm: 24 }}`. [#34907](https://github.com/ant-design/ant-design/pull/34907)
|
||||||
|
- 🛎 Menu support `items` for perf prepare, and `children` will be removed in next major version. [#34559](https://github.com/ant-design/ant-design/pull/34559)
|
||||||
|
- 🆕 Image PreviewGroup Support top progress rendering. [#35038](https://github.com/ant-design/ant-design/pull/35038) [@zpc7](https://github.com/zpc7)
|
||||||
|
- Upload
|
||||||
|
- 🆕 Upload support `crossOrigin` for images in `picture-card` mode. [#34981](https://github.com/ant-design/ant-design/pull/34981) [@dragmove](https://github.com/dragmove)
|
||||||
|
- 🐞 Fix Upload `prefixCls` don't work on file list. [#34944](https://github.com/ant-design/ant-design/pull/34944) [@swchen](https://github.com/swchen)
|
||||||
|
- 💄 Improve Upload action styles. [#35052](https://github.com/ant-design/ant-design/pull/35052)
|
||||||
|
- Table
|
||||||
|
- 🆕 Support reset to the default value rather than empty, when click reset in Table column filter. [#34355](https://github.com/ant-design/ant-design/pull/34355) [@heiyu4585](https://github.com/heiyu4585)
|
||||||
|
- 💄 Fix Table head background and selection column width styling issues when `size="small"`. [#34963](https://github.com/ant-design/ant-design/pull/34963)
|
||||||
|
- 🇩🇪 Improve German translations for Table. [#34836](https://github.com/ant-design/ant-design/pull/34836) [@pfedan](https://github.com/pfedan)
|
||||||
|
- ⚡️ Optimize Table filter calculation perfromance. [#35064](https://github.com/ant-design/ant-design/pull/35064) [@nieyuyao](https://github.com/nieyuyao)
|
||||||
|
- 💄 Improve small and middle size Table selection dropdown margin style. [#35173](https://github.com/ant-design/ant-design/pull/35173)
|
||||||
|
- Tree
|
||||||
|
- 🆕 Tree `switcherIcon` prop support render-prop. [#34470](https://github.com/ant-design/ant-design/pull/34470) [@zqran](https://github.com/zqran)
|
||||||
|
- 🆕 Tree support `rootClassName` and `rootStyle`. [#34578](https://github.com/ant-design/ant-design/pull/34578)
|
||||||
|
- Breadcrumb
|
||||||
|
- 🐞 Fix Breadcrumb deprecated warning of Dropdown `placement`. [#35162](https://github.com/ant-design/ant-design/pull/35162)
|
||||||
|
- 🐞 Fix Breadcrumb show the number when is unexpected. [#35123](https://github.com/ant-design/ant-design/pull/35123)
|
||||||
|
- ⌨️ Make structure of Breadcrumb be accessible. [#34082](https://github.com/ant-design/ant-design/pull/34082) [@VladimirOtroshchenko](https://github.com/VladimirOtroshchenko)
|
||||||
|
- Anchor
|
||||||
|
- 🆕 Anchor `getCurrentAnchor` has active link as argument. [#34799](https://github.com/ant-design/ant-design/pull/34799)
|
||||||
|
- 🛠 Refactor Anchor to Function component. [#35073](https://github.com/ant-design/ant-design/pull/35073) [@LongHaoo](https://github.com/LongHaoo)
|
||||||
|
- Cascader
|
||||||
|
- 🆕 Cascader supports `showCheckedStrategy ` for value display strategy. [#34568](https://github.com/ant-design/ant-design/pull/34568) [@heiyu4585](https://github.com/heiyu4585)
|
||||||
|
- 🐞 Fix Cascader search result do not fill the entrie panel. [#35019](https://github.com/ant-design/ant-design/pull/35019) [@boomler](https://github.com/boomler)
|
||||||
|
- 🆕 Click event object can be accessed in `onCopy` function of Typography. [#34655](https://github.com/ant-design/ant-design/pull/34655) [@yzwxk](https://github.com/yzwxk)
|
||||||
|
- 🆕 Grid supports `justify="space-evenly"`. [#34606](https://github.com/ant-design/ant-design/pull/34606) [@gp5251](https://github.com/gp5251)
|
||||||
|
- 🆕 Support `rootClassName` property for Dialog and Image. [#34574](https://github.com/ant-design/ant-design/pull/34574) [@heiyu4585](https://github.com/heiyu4585)
|
||||||
|
- 🐞 Fix error `Nothing was returned from render` when Skeleton use falsy `loading` props without `children`. [#34872](https://github.com/ant-design/ant-design/pull/34872) [@AlbertAZ1992](https://github.com/AlbertAZ1992)
|
||||||
|
- 💄 Optimize Switch disabled color to fit colorful background. [#35103](https://github.com/ant-design/ant-design/pull/35103)
|
||||||
|
- 💄 Remove Tabs `overflow: hidden` style to fix Select and sticky Table display problem inside Tabs. [#35195](https://github.com/ant-design/ant-design/pull/35195)
|
||||||
|
- 💄 Fix Steps style issues in RTL mode. [#35088](https://github.com/ant-design/ant-design/pull/35088) [@zpc7](https://github.com/zpc7)
|
||||||
|
- 💄 Fix animation for standalone Badge in RTL mode. [#34899](https://github.com/ant-design/ant-design/pull/34899) [@hmz22](https://github.com/hmz22)
|
||||||
|
- 🛠 Optimize Modal id generate logic to improve accessibility experience. [#35072](https://github.com/ant-design/ant-design/pull/35072)
|
||||||
|
- 🐞 Fix Select and AutoComplete scroll abnormal behavior when navigate via keyboard.。[#35025](https://github.com/ant-design/ant-design/pull/35025)
|
||||||
|
- Spin
|
||||||
|
- 💄 Fix Spin animation style being abnormally parsed in Parcel. [#35005](https://github.com/ant-design/ant-design/pull/35005)
|
||||||
|
- ⌨️ Spin add `aria` attribute to improve accessibility. [#34408](https://github.com/ant-design/ant-design/pull/34408) [@heiyu4585](https://github.com/heiyu4585)
|
||||||
|
- ⌨️ Dropdown support select option by keyboard. [#34738](https://github.com/ant-design/ant-design/pull/34738)
|
||||||
|
- 🐞 Fix Title, Text, Paragraph components cannot get `ref` bug. [#34847](https://github.com/ant-design/ant-design/pull/34847) [@MQuy](https://github.com/MQuy)
|
||||||
|
- Input
|
||||||
|
- 💄 Input.Group prevent components from getting style from Form.Item. [#34764](https://github.com/ant-design/ant-design/pull/34764)
|
||||||
|
- 💄 Adjust TextArea style in Form. [#34714](https://github.com/ant-design/ant-design/pull/34714)
|
||||||
|
- ⌨️ Fix `aria-checked` attribute for Checkbox, to avoid screen reader getting an incorrect status. [#34862](https://github.com/ant-design/ant-design/pull/34862) [@SpaNb4](https://github.com/SpaNb4)
|
||||||
|
- Less
|
||||||
|
- 💄 Replace less html selector with related variable. [#35186](https://github.com/ant-design/ant-design/pull/35186) [@jeffdrumgod](https://github.com/jeffdrumgod)
|
||||||
|
- 💄 Modify less `danger` value from the function to variable. [#35113](https://github.com/ant-design/ant-design/pull/35113) [@TrickyPi](https://github.com/TrickyPi)
|
||||||
|
- 🐞 Arrow border radius variable use fixed value. [#35086](https://github.com/ant-design/ant-design/pull/35086) [@MadCcc](https://github.com/MadCcc)
|
||||||
|
- TypeScript
|
||||||
|
- 🤖 Fixed `Upload` component `UploadChangeParam<T>` internal `fileList` not using generics. [#35158](https://github.com/ant-design/ant-design/pull/35158) [@rendaoer](https://github.com/rendaoer)
|
||||||
|
- 🤖 Update TypeScript definition for `@types/react@18` compatible. [#35075](https://github.com/ant-design/ant-design/pull/35075) [@AliRezaBeigy](https://github.com/AliRezaBeigy) [#35076](https://github.com/ant-design/ant-design/pull/35076) [@littledian](https://github.com/littledian)
|
||||||
|
|
||||||
## 4.19.5
|
## 4.19.5
|
||||||
|
|
||||||
`2022-04-02`
|
`2022-04-02`
|
||||||
|
@ -15,6 +15,96 @@ timeline: true
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 4.20.2
|
||||||
|
|
||||||
|
`2022-04-30`
|
||||||
|
|
||||||
|
- Segmented
|
||||||
|
- 🐞 修复 Segmented 组件高度和其他控件不一致的问题。[#35281](https://github.com/ant-design/ant-design/pull/35281)
|
||||||
|
- 🐞 修复 React StrictMode 下 Segmented 动画丢失的问题。[#35281](https://github.com/ant-design/ant-design/pull/35281)
|
||||||
|
- 🆕 Segmented `options` 支持设置 `icon` 属性。[#35256](https://github.com/ant-design/ant-design/pull/35256)
|
||||||
|
- Table
|
||||||
|
- ⌨️ 优化 Table 排序按钮的键盘可访问性。[#35269](https://github.com/ant-design/ant-design/pull/35269)
|
||||||
|
- 🇪🇸 补充 Table 西班牙语筛选文案。[#35309](https://github.com/ant-design/ant-design/pull/35309) [@agarciaguillo](https://github.com/agarciaguillo)
|
||||||
|
- 🐞 修复 Switch 在暗黑主题下关闭时的颜色问题。[#35332](https://github.com/ant-design/ant-design/pull/35332)
|
||||||
|
- 💄 微调 Breadcrumb 链接 hover 色为中性色。[#35324](https://github.com/ant-design/ant-design/pull/35324)
|
||||||
|
- 🐞 修复 Space 在某些情况下抛出 `Encountered two children with the same key` 警告的问题。[#35311](https://github.com/ant-design/ant-design/pull/35311)
|
||||||
|
- 🐞 修复 Select 多选标签移除图标位置偏下的问题。[#35336](https://github.com/ant-design/ant-design/pull/35336) [@walidcherhane](https://github.com/walidcherhane)
|
||||||
|
|
||||||
|
## 4.20.1
|
||||||
|
|
||||||
|
`2022-04-26`
|
||||||
|
|
||||||
|
- 🐞 修复 Breadcrumb 多余的 `padding` 和 `margin` 样式。[#35235](https://github.com/ant-design/ant-design/pull/35235)
|
||||||
|
- 🐞 修复 Input.Search 在中文输入法下回车键触发 `onSearch` 的行为不一致的问题。[#35164](https://github.com/ant-design/ant-design/pull/35164) [@qyzzzz](https://github.com/qyzzzz)
|
||||||
|
- 🐞 修复 Upload 和 Upload.Dragger 之间循环依赖的问题。[#34379](https://github.com/ant-design/ant-design/pull/34379) [@kanweiwei](https://github.com/kanweiwei)
|
||||||
|
|
||||||
|
## 4.20.0
|
||||||
|
|
||||||
|
`2022-04-24`
|
||||||
|
|
||||||
|
- 🔥 支持 React 18 以及严格模式,修复了相关已知问题。
|
||||||
|
- 🐞 修复 Form 在 React 18 的 StrictMode 下,错误信息无法更新的问题。[#35096](https://github.com/ant-design/ant-design/pull/35096)
|
||||||
|
- 🐞 修复 Notification 和 Message 在 React 18 下抛出使用 `createRoot` 的警告信息。[#35030](https://github.com/ant-design/ant-design/pull/35030)
|
||||||
|
- 🐞 修复 BackTop 组件在严格模式下不能正常工作的问题。[#34858](https://github.com/ant-design/ant-design/pull/34858) [@tmkx](https://github.com/tmkx)
|
||||||
|
- 🔥 新增 Segmented 分段控制器组件。[#34319](https://github.com/ant-design/ant-design/pull/34319)
|
||||||
|
- 🛠 4.20.0 正式版后,Segemented 的 `onChange` 回调函数的参数从 `ChangeEvent` 调整为 `value`。如果你使用了 `4.20.0-alpha.0` `4.20.0-alpha.1`,请注意这个变化。[#35187](https://github.com/ant-design/ant-design/pull/35187) [@vagusX](https://github.com/vagusX)
|
||||||
|
- Form
|
||||||
|
- 🔥 Form 添加 `useWatch` 支持获取当前字段值。[#35036](https://github.com/ant-design/ant-design/pull/35036)
|
||||||
|
- 🆕 Form 支持 `useFormInstance` 以获取当前上下文中的 Form 实例。[#35039](https://github.com/ant-design/ant-design/pull/35039)
|
||||||
|
- 💄 修复 Form `labelCol={{ sm: 24 }}` 和 `wrapperCol={{ sm: 24 }}` 时样式错乱的问题。[#34907](https://github.com/ant-design/ant-design/pull/34907)
|
||||||
|
- 🛎 Menu 添加 `items` 数据化菜单项支持以为将来性能提升做准备,并且 `children` 将会在下个大版本中废弃。[#34559](https://github.com/ant-design/ant-design/pull/34559)
|
||||||
|
- 🆕 Image PreviewGroup 支持顶部进度渲染。[#35038](https://github.com/ant-design/ant-design/pull/35038) [@zpc7](https://github.com/zpc7)
|
||||||
|
- Upload
|
||||||
|
- 🆕 Upload `picture-card` 模式支持配置图片的 `crossOrigin` 属性。[#34981](https://github.com/ant-design/ant-design/pull/34981) [@dragmove](https://github.com/dragmove)
|
||||||
|
- 🐞 修复 Upload `prefixCls` 对列表不生效的问题。[#34944](https://github.com/ant-design/ant-design/pull/34944) [@swchen](https://github.com/swchen)
|
||||||
|
- 💄 优化 Upload 操作按钮的样式细节。[#35052](https://github.com/ant-design/ant-design/pull/35052)
|
||||||
|
- Table
|
||||||
|
- 🆕 Table 列筛选条件重置时,支持重置为默认值而非空值。[#34355](https://github.com/ant-design/ant-design/pull/34355) [@heiyu4585](https://github.com/heiyu4585)
|
||||||
|
- 💄 修复 Table `size="small"` 时列头背景色和选择列宽度的样式问题。[#34963](https://github.com/ant-design/ant-design/pull/34963)
|
||||||
|
- 🇩🇪 补全 Table 的德语国际化文案。[#34836](https://github.com/ant-design/ant-design/pull/34836) [@pfedan](https://github.com/pfedan)
|
||||||
|
- ⚡️ 优化 Table 过滤列表的计算性能。[#35064](https://github.com/ant-design/ant-design/pull/35064) [@nieyuyao](https://github.com/nieyuyao)
|
||||||
|
- 💄 优化 Table `size="small"` 和 `size="middle"` 时选择下拉菜单的边距样式。[#35173](https://github.com/ant-design/ant-design/pull/35173)
|
||||||
|
- Tree
|
||||||
|
- 🆕 Tree 组件的 `switcherIcon` 属性支持 render-prop。[#34470](https://github.com/ant-design/ant-design/pull/34470) [@zqran](https://github.com/zqran)
|
||||||
|
- 🆕 Tree 支持 `rootClassName` and `rootStyle`。[#34578](https://github.com/ant-design/ant-design/pull/34578)
|
||||||
|
- Breadcrumb
|
||||||
|
- 🐞 修复 Breadcrumb 抛出 `placement` 废弃警告的问题。[#35162](https://github.com/ant-design/ant-design/pull/35162)
|
||||||
|
- 🐞 修复 Breadcrumb 展示非预期的数字符号的样式问题。[#35123](https://github.com/ant-design/ant-design/pull/35123)
|
||||||
|
- ⌨️ 为 Breadcrumb 层次结构增加可访问性支持。[#34082](https://github.com/ant-design/ant-design/pull/34082) [@VladimirOtroshchenko](https://github.com/VladimirOtroshchenko)
|
||||||
|
- Anchor
|
||||||
|
- 🆕 Anchor `getCurrentAnchor` 参数中返回默认高亮项。[#34799](https://github.com/ant-design/ant-design/pull/34799)
|
||||||
|
- 🛠 重构 Anchor 为函数组件。[#35073](https://github.com/ant-design/ant-design/pull/35073) [@LongHaoo](https://github.com/LongHaoo)
|
||||||
|
- Cascader
|
||||||
|
- 🆕 Cascader 添加 `showCheckedStrategy` 用于配置回填方式。[#34568](https://github.com/ant-design/ant-design/pull/34568) [@heiyu4585](https://github.com/heiyu4585)
|
||||||
|
- 🐞 修复 Cascader 的搜索结果未占满整个面板的问题。[#35019](https://github.com/ant-design/ant-design/pull/35019) [@boomler](https://github.com/boomler)
|
||||||
|
- 🆕 Typography 的 `onCopy` 方法支持获取点击事件对象。[#34655](https://github.com/ant-design/ant-design/pull/34655) [@yzwxk](https://github.com/yzwxk)
|
||||||
|
- 🆕 Grid 支持 `justify="space-evenly"`。[#34606](https://github.com/ant-design/ant-design/pull/34606) [@gp5251](https://github.com/gp5251)
|
||||||
|
- 🆕 Dialog 及 Image 支持 `rootClassName` 属性。[#34574](https://github.com/ant-design/ant-design/pull/34574) [@heiyu4585](https://github.com/heiyu4585)
|
||||||
|
- 🐞 修复 Skeleton 在没有 `children` 并设置 `loading` 为 false 时提示 `Nothing was returned from render` 的问题。[#34872](https://github.com/ant-design/ant-design/pull/34872) [@AlbertAZ1992](https://github.com/AlbertAZ1992)
|
||||||
|
- 💄 优化 Switch 禁用色以更好适应非白底背景。[#35103](https://github.com/ant-design/ant-design/pull/35103)
|
||||||
|
- 💄 移除 Tabs `overflow: hidden` 样式以修复 Select 和 sticky Table 在 Tabs 中的展现问题。[#35195](https://github.com/ant-design/ant-design/pull/35195)
|
||||||
|
- 💄 修正 Steps 在 RTL 模式下样式问题。[#35088](https://github.com/ant-design/ant-design/pull/35088) [@zpc7](https://github.com/zpc7)
|
||||||
|
- 💄 修复 Badge 在 RTL 模式下、独立使用时的动画效果。[#34899](https://github.com/ant-design/ant-design/pull/34899) [@hmz22](https://github.com/hmz22)
|
||||||
|
- 🛠 优化 Modal id 生成逻辑,以优化无障碍体验。[#35072](https://github.com/ant-design/ant-design/pull/35072)
|
||||||
|
- 🐞 修复 Select 和 AutoComplete 使用键盘向下滚动时行为异常的问题。[#35025](https://github.com/ant-design/ant-design/pull/35025)
|
||||||
|
- Spin
|
||||||
|
- 💄 修复 Spin 动画样式在 Parcel 解析异常的问题。[#35005](https://github.com/ant-design/ant-design/pull/35005)
|
||||||
|
- ⌨️ Spin 添加 `aria` 属性以提升可访问性。[#34408](https://github.com/ant-design/ant-design/pull/34408) [@heiyu4585](https://github.com/heiyu4585)
|
||||||
|
- ⌨️ Dropdown 支持方向键切换选项。[#34738](https://github.com/ant-design/ant-design/pull/34738)
|
||||||
|
- 🐞 修复 Title、Text、Paragraph 组件不支持 `ref` 的问题。[#34847](https://github.com/ant-design/ant-design/pull/34847) [@MQuy](https://github.com/MQuy)
|
||||||
|
- Input
|
||||||
|
- 💄 Input.Group 对子组件屏蔽 Form.Item 的样式。[#34764](https://github.com/ant-design/ant-design/pull/34764)
|
||||||
|
- 💄 调整 Form 下 TextArea 的样式。[#34714](https://github.com/ant-design/ant-design/pull/34714) [@MadCcc](https://github.com/MadCcc)
|
||||||
|
- ⌨️ 修复 Checkbox 缺少 `aria-checked` 属性导致屏幕阅读器识别错误的问题。[#34862](https://github.com/ant-design/ant-design/pull/34862) [@SpaNb4](https://github.com/SpaNb4)
|
||||||
|
- Less
|
||||||
|
- 💄 替换 less 中的 html 选择器为对应变量。[#35186](https://github.com/ant-design/ant-design/pull/35186) [@jeffdrumgod](https://github.com/jeffdrumgod)
|
||||||
|
- 💄 修改 less 中 `danger` 值从函数改为变量。[#35113](https://github.com/ant-design/ant-design/pull/35113) [@TrickyPi](https://github.com/TrickyPi)
|
||||||
|
- 🐞 箭头圆角使用固定值 2px 变量。[#35086](https://github.com/ant-design/ant-design/pull/35086) [@MadCcc](https://github.com/MadCcc)
|
||||||
|
- TypeScript
|
||||||
|
- 🤖 修正 Upload 组件中 `UploadChangeParam<T>` 内部 `fileList` 不使用泛型问题。[#35158](https://github.com/ant-design/ant-design/pull/35158) [@rendaoer](https://github.com/rendaoer)
|
||||||
|
- 🤖 更新 TypeScript 定义以兼容 `@types/react@18`。[#35075](https://github.com/ant-design/ant-design/pull/35075) [@AliRezaBeigy](https://github.com/AliRezaBeigy) [#35076](https://github.com/ant-design/ant-design/pull/35076) [@littledian](https://github.com/littledian)
|
||||||
|
|
||||||
## 4.19.5
|
## 4.19.5
|
||||||
|
|
||||||
`2022-04-02`
|
`2022-04-02`
|
||||||
|
12
CODEOWNERS
12
CODEOWNERS
@ -1,12 +0,0 @@
|
|||||||
# CODEOWNERS syntax
|
|
||||||
# A CODEOWNERS file uses a pattern that follows the same rules used in gitignore files.
|
|
||||||
# The pattern is followed by one or more GitHub usernames or team names using the standard @username or @org/team-name format.
|
|
||||||
# You can also refer to a user by an email address that has been added to their GitHub account, for example user@example.com.
|
|
||||||
|
|
||||||
# no default file owner
|
|
||||||
#/* @afc163
|
|
||||||
/components/tree/* @zombieJ
|
|
||||||
/components/tree-select/* @zombieJ
|
|
||||||
|
|
||||||
# ...
|
|
||||||
# other components
|
|
@ -12,7 +12,7 @@ Uma solução empresarial de design e biblioteca UI para React.
|
|||||||
|
|
||||||
[![CI status][github-action-image]][github-action-url] [![codecov][codecov-image]][codecov-url] [![NPM version][npm-image]][npm-url] [![NPM downloads][download-image]][download-url]
|
[![CI status][github-action-image]][github-action-url] [![codecov][codecov-image]][codecov-url] [![NPM version][npm-image]][npm-url] [![NPM downloads][download-image]][download-url]
|
||||||
|
|
||||||
[![david deps][david-image]][david-url] [![david devDeps][david-dev-image]][david-dev-url] [![Total alerts][lgtm-image]][lgtm-url] [![][bundlesize-js-image]][unpkg-js-url] [![][bundlesize-css-image]][unpkg-css-url]
|
[![Renovate status][renovate-image]][renovate-dashboard-url] [![Total alerts][lgtm-image]][lgtm-url] [![][bundlesize-js-image]][unpkg-js-url] [![][bundlesize-css-image]][unpkg-css-url]
|
||||||
|
|
||||||
[![Follow Twitter][twitter-image]][twitter-url] [![FOSSA Status][fossa-image]][fossa-url] [![Discussions][discussions-image]][discussions-url] [![][issues-helper-image]][issues-helper-url] [![Issues need help][help-wanted-image]][help-wanted-url]
|
[![Follow Twitter][twitter-image]][twitter-url] [![FOSSA Status][fossa-image]][fossa-url] [![Discussions][discussions-image]][discussions-url] [![][issues-helper-image]][issues-helper-url] [![Issues need help][help-wanted-image]][help-wanted-url]
|
||||||
|
|
||||||
@ -22,10 +22,6 @@ Uma solução empresarial de design e biblioteca UI para React.
|
|||||||
[github-action-url]: https://github.com/ant-design/ant-design/actions?query=workflow%3A%22%E2%9C%85+test%22
|
[github-action-url]: https://github.com/ant-design/ant-design/actions?query=workflow%3A%22%E2%9C%85+test%22
|
||||||
[codecov-image]: https://img.shields.io/codecov/c/github/ant-design/ant-design/master.svg?style=flat-square
|
[codecov-image]: https://img.shields.io/codecov/c/github/ant-design/ant-design/master.svg?style=flat-square
|
||||||
[codecov-url]: https://codecov.io/gh/ant-design/ant-design/branch/master
|
[codecov-url]: https://codecov.io/gh/ant-design/ant-design/branch/master
|
||||||
[david-image]: https://img.shields.io/david/ant-design/ant-design?style=flat-square
|
|
||||||
[david-dev-url]: https://david-dm.org/ant-design/ant-design?type=dev
|
|
||||||
[david-dev-image]: https://img.shields.io/david/dev/ant-design/ant-design?style=flat-square
|
|
||||||
[david-url]: https://david-dm.org/ant-design/ant-design
|
|
||||||
[download-image]: https://img.shields.io/npm/dm/antd.svg?style=flat-square
|
[download-image]: https://img.shields.io/npm/dm/antd.svg?style=flat-square
|
||||||
[download-url]: https://npmjs.org/package/antd
|
[download-url]: https://npmjs.org/package/antd
|
||||||
[lgtm-image]: https://flat.badgen.net/lgtm/alerts/g/ant-design/ant-design
|
[lgtm-image]: https://flat.badgen.net/lgtm/alerts/g/ant-design/ant-design
|
||||||
@ -44,6 +40,8 @@ Uma solução empresarial de design e biblioteca UI para React.
|
|||||||
[unpkg-css-url]: https://unpkg.com/browse/antd/dist/antd.min.css
|
[unpkg-css-url]: https://unpkg.com/browse/antd/dist/antd.min.css
|
||||||
[issues-helper-image]: https://img.shields.io/badge/using-issues--helper-orange?style=flat-square
|
[issues-helper-image]: https://img.shields.io/badge/using-issues--helper-orange?style=flat-square
|
||||||
[issues-helper-url]: https://github.com/actions-cool/issues-helper
|
[issues-helper-url]: https://github.com/actions-cool/issues-helper
|
||||||
|
[renovate-image]: https://img.shields.io/badge/renovate-enabled-brightgreen.svg?style=flat-square
|
||||||
|
[renovate-dashboard-url]: https://github.com/ant-design/ant-design/issues/32498
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
[![CI status][github-action-image]][github-action-url] [![codecov][codecov-image]][codecov-url] [![NPM version][npm-image]][npm-url] [![NPM downloads][download-image]][download-url]
|
[![CI status][github-action-image]][github-action-url] [![codecov][codecov-image]][codecov-url] [![NPM version][npm-image]][npm-url] [![NPM downloads][download-image]][download-url]
|
||||||
|
|
||||||
[![david deps][david-image]][david-url] [![david devDeps][david-dev-image]][david-dev-url] [![Total alerts][lgtm-image]][lgtm-url] [![][bundlesize-js-image]][unpkg-js-url] [![][bundlesize-css-image]][unpkg-css-url]
|
[![Renovate status][renovate-image]][renovate-dashboard-url] [![Total alerts][lgtm-image]][lgtm-url] [![][bundlesize-js-image]][unpkg-js-url] [![][bundlesize-css-image]][unpkg-css-url]
|
||||||
|
|
||||||
[![Follow Twitter][twitter-image]][twitter-url] [![FOSSA Status][fossa-image]][fossa-url] [![Discussions][discussions-image]][discussions-url] [![][issues-helper-image]][issues-helper-url] [![Issues need help][help-wanted-image]][help-wanted-url]
|
[![Follow Twitter][twitter-image]][twitter-url] [![FOSSA Status][fossa-image]][fossa-url] [![Discussions][discussions-image]][discussions-url] [![][issues-helper-image]][issues-helper-url] [![Issues need help][help-wanted-image]][help-wanted-url]
|
||||||
|
|
||||||
@ -22,10 +22,6 @@
|
|||||||
[github-action-url]: https://github.com/ant-design/ant-design/actions?query=workflow%3A%22%E2%9C%85+test%22
|
[github-action-url]: https://github.com/ant-design/ant-design/actions?query=workflow%3A%22%E2%9C%85+test%22
|
||||||
[codecov-image]: https://img.shields.io/codecov/c/github/ant-design/ant-design/master.svg?style=flat-square
|
[codecov-image]: https://img.shields.io/codecov/c/github/ant-design/ant-design/master.svg?style=flat-square
|
||||||
[codecov-url]: https://codecov.io/gh/ant-design/ant-design/branch/master
|
[codecov-url]: https://codecov.io/gh/ant-design/ant-design/branch/master
|
||||||
[david-image]: https://img.shields.io/david/ant-design/ant-design?style=flat-square
|
|
||||||
[david-dev-url]: https://david-dm.org/ant-design/ant-design?type=dev
|
|
||||||
[david-dev-image]: https://img.shields.io/david/dev/ant-design/ant-design?style=flat-square
|
|
||||||
[david-url]: https://david-dm.org/ant-design/ant-design
|
|
||||||
[download-image]: https://img.shields.io/npm/dm/antd.svg?style=flat-square
|
[download-image]: https://img.shields.io/npm/dm/antd.svg?style=flat-square
|
||||||
[download-url]: https://npmjs.org/package/antd
|
[download-url]: https://npmjs.org/package/antd
|
||||||
[lgtm-image]: https://flat.badgen.net/lgtm/alerts/g/ant-design/ant-design
|
[lgtm-image]: https://flat.badgen.net/lgtm/alerts/g/ant-design/ant-design
|
||||||
@ -44,6 +40,8 @@
|
|||||||
[unpkg-css-url]: https://unpkg.com/browse/antd/dist/antd.min.css
|
[unpkg-css-url]: https://unpkg.com/browse/antd/dist/antd.min.css
|
||||||
[issues-helper-image]: https://img.shields.io/badge/using-issues--helper-orange?style=flat-square
|
[issues-helper-image]: https://img.shields.io/badge/using-issues--helper-orange?style=flat-square
|
||||||
[issues-helper-url]: https://github.com/actions-cool/issues-helper
|
[issues-helper-url]: https://github.com/actions-cool/issues-helper
|
||||||
|
[renovate-image]: https://img.shields.io/badge/renovate-enabled-brightgreen.svg?style=flat-square
|
||||||
|
[renovate-dashboard-url]: https://github.com/ant-design/ant-design/issues/32498
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
[![CI status][github-action-image]][github-action-url] [![codecov][codecov-image]][codecov-url] [![NPM version][npm-image]][npm-url] [![NPM downloads][download-image]][download-url]
|
[![CI status][github-action-image]][github-action-url] [![codecov][codecov-image]][codecov-url] [![NPM version][npm-image]][npm-url] [![NPM downloads][download-image]][download-url]
|
||||||
|
|
||||||
[![david deps][david-image]][david-url] [![david devDeps][david-dev-image]][david-dev-url] [![Total alerts][lgtm-image]][lgtm-url] [![][bundlesize-js-image]][unpkg-js-url] [![][bundlesize-css-image]][unpkg-css-url]
|
[![Renovate status][renovate-image]][renovate-dashboard-url] [![Total alerts][lgtm-image]][lgtm-url] [![][bundlesize-js-image]][unpkg-js-url] [![][bundlesize-css-image]][unpkg-css-url]
|
||||||
|
|
||||||
[![Follow Twitter][twitter-image]][twitter-url] [![FOSSA Status][fossa-image]][fossa-url] [![Discussions][discussions-image]][discussions-url] [![][issues-helper-image]][issues-helper-url] [![Issues need help][help-wanted-image]][help-wanted-url]
|
[![Follow Twitter][twitter-image]][twitter-url] [![FOSSA Status][fossa-image]][fossa-url] [![Discussions][discussions-image]][discussions-url] [![][issues-helper-image]][issues-helper-url] [![Issues need help][help-wanted-image]][help-wanted-url]
|
||||||
|
|
||||||
@ -22,10 +22,6 @@
|
|||||||
[github-action-url]: https://github.com/ant-design/ant-design/actions?query=workflow%3A%22%E2%9C%85+test%22
|
[github-action-url]: https://github.com/ant-design/ant-design/actions?query=workflow%3A%22%E2%9C%85+test%22
|
||||||
[codecov-image]: https://img.shields.io/codecov/c/github/ant-design/ant-design/master.svg?style=flat-square
|
[codecov-image]: https://img.shields.io/codecov/c/github/ant-design/ant-design/master.svg?style=flat-square
|
||||||
[codecov-url]: https://codecov.io/gh/ant-design/ant-design/branch/master
|
[codecov-url]: https://codecov.io/gh/ant-design/ant-design/branch/master
|
||||||
[david-image]: https://img.shields.io/david/ant-design/ant-design?style=flat-square
|
|
||||||
[david-dev-url]: https://david-dm.org/ant-design/ant-design?type=dev
|
|
||||||
[david-dev-image]: https://img.shields.io/david/dev/ant-design/ant-design?style=flat-square
|
|
||||||
[david-url]: https://david-dm.org/ant-design/ant-design
|
|
||||||
[download-image]: https://img.shields.io/npm/dm/antd.svg?style=flat-square
|
[download-image]: https://img.shields.io/npm/dm/antd.svg?style=flat-square
|
||||||
[download-url]: https://npmjs.org/package/antd
|
[download-url]: https://npmjs.org/package/antd
|
||||||
[lgtm-image]: https://flat.badgen.net/lgtm/alerts/g/ant-design/ant-design
|
[lgtm-image]: https://flat.badgen.net/lgtm/alerts/g/ant-design/ant-design
|
||||||
@ -44,6 +40,8 @@
|
|||||||
[unpkg-css-url]: https://unpkg.com/browse/antd/dist/antd.min.css
|
[unpkg-css-url]: https://unpkg.com/browse/antd/dist/antd.min.css
|
||||||
[issues-helper-image]: https://img.shields.io/badge/using-issues--helper-orange?style=flat-square
|
[issues-helper-image]: https://img.shields.io/badge/using-issues--helper-orange?style=flat-square
|
||||||
[issues-helper-url]: https://github.com/actions-cool/issues-helper
|
[issues-helper-url]: https://github.com/actions-cool/issues-helper
|
||||||
|
[renovate-image]: https://img.shields.io/badge/renovate-enabled-brightgreen.svg?style=flat-square
|
||||||
|
[renovate-dashboard-url]: https://github.com/ant-design/ant-design/issues/32498
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
import UnreachableException from '../unreachableException';
|
|
||||||
|
|
||||||
describe('UnreachableException', () => {
|
|
||||||
it('error thrown matches snapshot', () => {
|
|
||||||
const exception = new UnreachableException('some value');
|
|
||||||
expect(exception.error.message).toMatchInlineSnapshot(`"unreachable case: \\"some value\\""`);
|
|
||||||
});
|
|
||||||
});
|
|
@ -148,7 +148,9 @@ describe('Test utils function', () => {
|
|||||||
button
|
button
|
||||||
</button>
|
</button>
|
||||||
</Wave>,
|
</Wave>,
|
||||||
).instance();
|
)
|
||||||
|
.find(Wave)
|
||||||
|
.instance();
|
||||||
expect(wrapper.bindAnimationEvent()).toBe(undefined);
|
expect(wrapper.bindAnimationEvent()).toBe(undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -159,7 +161,9 @@ describe('Test utils function', () => {
|
|||||||
button
|
button
|
||||||
</button>
|
</button>
|
||||||
</Wave>,
|
</Wave>,
|
||||||
).instance();
|
)
|
||||||
|
.find(Wave)
|
||||||
|
.instance();
|
||||||
expect(wrapper.bindAnimationEvent()).toBe(undefined);
|
expect(wrapper.bindAnimationEvent()).toBe(undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -168,7 +172,9 @@ describe('Test utils function', () => {
|
|||||||
<Wave>
|
<Wave>
|
||||||
<input />
|
<input />
|
||||||
</Wave>,
|
</Wave>,
|
||||||
).instance();
|
)
|
||||||
|
.find(Wave)
|
||||||
|
.instance();
|
||||||
expect(wrapper.bindAnimationEvent()).toBe(undefined);
|
expect(wrapper.bindAnimationEvent()).toBe(undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -4,4 +4,9 @@ export { resetWarned };
|
|||||||
|
|
||||||
export default (valid: boolean, component: string, message: string): void => {
|
export default (valid: boolean, component: string, message: string): void => {
|
||||||
devWarning(valid, `[antd: ${component}] ${message}`);
|
devWarning(valid, `[antd: ${component}] ${message}`);
|
||||||
|
|
||||||
|
// StrictMode will inject console which will not throw warning in React 17.
|
||||||
|
if (process.env.NODE_ENV === 'test') {
|
||||||
|
resetWarned();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@ -3,20 +3,9 @@ import { CSSInterpolation, Theme, useCacheToken, useStyleRegister } from '@ant-d
|
|||||||
import genComponentStyleHook from './util/genComponentStyleHook';
|
import genComponentStyleHook from './util/genComponentStyleHook';
|
||||||
import defaultSeedToken, { derivative as defaultDerivative } from './themes/default';
|
import defaultSeedToken, { derivative as defaultDerivative } from './themes/default';
|
||||||
import version from '../../version';
|
import version from '../../version';
|
||||||
import { resetComponent, resetIcon, clearFix, roundedArrow } from './util';
|
import { resetComponent, resetIcon, clearFix, roundedArrow, operationUnit } from './util';
|
||||||
import formatToken from './util/alias';
|
import formatToken from './util/alias';
|
||||||
import {
|
import statisticToken, { merge as mergeToken, statistic } from './util/statistic';
|
||||||
initSlideMotion,
|
|
||||||
slideUpIn,
|
|
||||||
slideUpOut,
|
|
||||||
slideDownIn,
|
|
||||||
slideDownOut,
|
|
||||||
slideLeftIn,
|
|
||||||
slideLeftOut,
|
|
||||||
slideRightIn,
|
|
||||||
slideRightOut,
|
|
||||||
} from './util/slide';
|
|
||||||
import statisticToken, { merge as mergeToken } from './util/statistic';
|
|
||||||
import { GlobalToken, PresetColors } from './interface';
|
import { GlobalToken, PresetColors } from './interface';
|
||||||
import type {
|
import type {
|
||||||
SeedToken,
|
SeedToken,
|
||||||
@ -28,25 +17,20 @@ import type {
|
|||||||
import type { FullToken } from './util/genComponentStyleHook';
|
import type { FullToken } from './util/genComponentStyleHook';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
PresetColors,
|
// css utils
|
||||||
resetComponent,
|
resetComponent,
|
||||||
resetIcon,
|
resetIcon,
|
||||||
clearFix,
|
clearFix,
|
||||||
roundedArrow,
|
roundedArrow,
|
||||||
initSlideMotion,
|
operationUnit,
|
||||||
slideUpIn,
|
// colors
|
||||||
slideUpOut,
|
PresetColors,
|
||||||
slideDownIn,
|
|
||||||
slideDownOut,
|
|
||||||
slideLeftIn,
|
|
||||||
slideLeftOut,
|
|
||||||
slideRightIn,
|
|
||||||
slideRightOut,
|
|
||||||
useStyleRegister,
|
|
||||||
// Statistic
|
// Statistic
|
||||||
|
statistic,
|
||||||
statisticToken,
|
statisticToken,
|
||||||
mergeToken,
|
mergeToken,
|
||||||
// GenComponentStyleHook
|
// hooks
|
||||||
|
useStyleRegister,
|
||||||
genComponentStyleHook,
|
genComponentStyleHook,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -73,6 +57,11 @@ export const DesignTokenContext = React.createContext<{
|
|||||||
});
|
});
|
||||||
|
|
||||||
// ================================== Hook ==================================
|
// ================================== Hook ==================================
|
||||||
|
// In dev env, we refresh salt per hour to avoid user use this
|
||||||
|
// Note: Do not modify this to real time update which will make debug harder
|
||||||
|
const saltPrefix =
|
||||||
|
process.env.NODE_ENV === 'production' ? version : `${version}-${new Date().getHours()}`;
|
||||||
|
|
||||||
export function useToken(): [Theme<SeedToken, DerivativeToken>, GlobalToken, string] {
|
export function useToken(): [Theme<SeedToken, DerivativeToken>, GlobalToken, string] {
|
||||||
const {
|
const {
|
||||||
token: rootDesignToken,
|
token: rootDesignToken,
|
||||||
@ -81,7 +70,7 @@ export function useToken(): [Theme<SeedToken, DerivativeToken>, GlobalToken, str
|
|||||||
hashed,
|
hashed,
|
||||||
} = React.useContext(DesignTokenContext);
|
} = React.useContext(DesignTokenContext);
|
||||||
|
|
||||||
const salt = `${version}-${hashed || ''}`;
|
const salt = `${saltPrefix}-${hashed || ''}`;
|
||||||
|
|
||||||
const [token, hashId] = useCacheToken<GlobalToken, SeedToken>(
|
const [token, hashId] = useCacheToken<GlobalToken, SeedToken>(
|
||||||
theme,
|
theme,
|
||||||
@ -100,5 +89,4 @@ export type UseComponentStyleResult = [(node: React.ReactNode) => React.ReactEle
|
|||||||
|
|
||||||
export type GenerateStyle<ComponentToken extends object, ReturnType = CSSInterpolation> = (
|
export type GenerateStyle<ComponentToken extends object, ReturnType = CSSInterpolation> = (
|
||||||
token: ComponentToken,
|
token: ComponentToken,
|
||||||
hashId?: string,
|
|
||||||
) => ReturnType;
|
) => ReturnType;
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import type * as React from 'react';
|
import type * as React from 'react';
|
||||||
|
import type { ComponentToken as AnchorComponentToken } from '../../anchor/style';
|
||||||
import type { ComponentToken as ButtonComponentToken } from '../../button/style';
|
import type { ComponentToken as ButtonComponentToken } from '../../button/style';
|
||||||
import type { ComponentToken as DividerComponentToken } from '../../divider/style';
|
import type { ComponentToken as DividerComponentToken } from '../../divider/style';
|
||||||
|
import type { ComponentToken as DropdownComponentToken } from '../../dropdown/style';
|
||||||
import type { ComponentToken as EmptyComponentToken } from '../../empty/style';
|
import type { ComponentToken as EmptyComponentToken } from '../../empty/style';
|
||||||
import type { ComponentToken as CascaderComponentToken } from '../../cascader/style';
|
import type { ComponentToken as CascaderComponentToken } from '../../cascader/style';
|
||||||
import type { ComponentToken as InputNumberComponentToken } from '../../input-number/style';
|
import type { ComponentToken as InputNumberComponentToken } from '../../input-number/style';
|
||||||
@ -8,7 +10,13 @@ import type { ComponentToken as MentionsComponentToken } from '../../mentions/st
|
|||||||
import type { ComponentToken as SelectComponentToken } from '../../select/style';
|
import type { ComponentToken as SelectComponentToken } from '../../select/style';
|
||||||
import type { ComponentToken as SliderComponentToken } from '../../slider/style';
|
import type { ComponentToken as SliderComponentToken } from '../../slider/style';
|
||||||
import type { ComponentToken as TypographyComponentToken } from '../../typography/style';
|
import type { ComponentToken as TypographyComponentToken } from '../../typography/style';
|
||||||
|
import type { ComponentToken as BackTopComponentToken } from '../../back-top/style';
|
||||||
|
import type { ComponentToken as DatePickerComponentToken } from '../../date-picker/style';
|
||||||
import type { ComponentToken as TimelineComponentToken } from '../../timeline/style';
|
import type { ComponentToken as TimelineComponentToken } from '../../timeline/style';
|
||||||
|
import type { ComponentToken as MenuComponentToken } from '../../menu/style';
|
||||||
|
import type { ComponentToken as UploadComponentToken } from '../../upload/style';
|
||||||
|
import type { ComponentToken as CarouselComponentToken } from '../../carousel/style';
|
||||||
|
import type { ComponentToken as SpaceComponentToken } from '../../space/style';
|
||||||
|
|
||||||
export const PresetColors = [
|
export const PresetColors = [
|
||||||
'blue',
|
'blue',
|
||||||
@ -42,15 +50,20 @@ export interface OverrideToken {
|
|||||||
// Customize component
|
// Customize component
|
||||||
Affix?: {};
|
Affix?: {};
|
||||||
Alert?: {};
|
Alert?: {};
|
||||||
|
Anchor?: AnchorComponentToken;
|
||||||
Avatar?: {};
|
Avatar?: {};
|
||||||
|
BackTop?: BackTopComponentToken;
|
||||||
Badge?: {};
|
Badge?: {};
|
||||||
Button?: ButtonComponentToken;
|
Button?: ButtonComponentToken;
|
||||||
Carousel?: {};
|
Carousel?: CarouselComponentToken;
|
||||||
Cascader?: CascaderComponentToken;
|
Cascader?: CascaderComponentToken;
|
||||||
Checkbox?: {};
|
Checkbox?: {};
|
||||||
|
Collapse?: {};
|
||||||
|
DatePicker?: DatePickerComponentToken;
|
||||||
Descriptions?: {};
|
Descriptions?: {};
|
||||||
Divider?: DividerComponentToken;
|
Divider?: DividerComponentToken;
|
||||||
Drawer?: {};
|
Drawer?: {};
|
||||||
|
Dropdown?: DropdownComponentToken;
|
||||||
Empty?: EmptyComponentToken;
|
Empty?: EmptyComponentToken;
|
||||||
Form?: {};
|
Form?: {};
|
||||||
Grid?: {};
|
Grid?: {};
|
||||||
@ -75,6 +88,13 @@ export interface OverrideToken {
|
|||||||
Typography?: TypographyComponentToken;
|
Typography?: TypographyComponentToken;
|
||||||
Timeline?: TimelineComponentToken;
|
Timeline?: TimelineComponentToken;
|
||||||
Tabs?: {};
|
Tabs?: {};
|
||||||
|
Card?: {};
|
||||||
|
Steps?: {};
|
||||||
|
Menu?: MenuComponentToken;
|
||||||
|
Layout?: {};
|
||||||
|
Upload?: UploadComponentToken;
|
||||||
|
Tooltip?: {};
|
||||||
|
Space?: SpaceComponentToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Final token which contains the components level override */
|
/** Final token which contains the components level override */
|
||||||
@ -123,6 +143,7 @@ export interface SeedToken extends PresetColorType {
|
|||||||
// Size
|
// Size
|
||||||
sizeUnit: number;
|
sizeUnit: number;
|
||||||
sizeBaseStep: number;
|
sizeBaseStep: number;
|
||||||
|
sizePopupArrow: number;
|
||||||
|
|
||||||
// Control Base
|
// Control Base
|
||||||
controlHeight: number;
|
controlHeight: number;
|
||||||
@ -287,6 +308,8 @@ export interface AliasToken extends Omit<DerivativeToken, OmitDerivativeKey> {
|
|||||||
colorBgComponentDisabled: string;
|
colorBgComponentDisabled: string;
|
||||||
|
|
||||||
// =============== Legacy: should be remove ===============
|
// =============== Legacy: should be remove ===============
|
||||||
|
colorLoadingOpacity: number;
|
||||||
|
|
||||||
padding: number;
|
padding: number;
|
||||||
margin: number;
|
margin: number;
|
||||||
|
|
||||||
|
@ -73,9 +73,9 @@ export function derivative(token: SeedToken): DerivativeToken {
|
|||||||
...colorPalettes,
|
...colorPalettes,
|
||||||
|
|
||||||
// motion
|
// motion
|
||||||
motionDurationFast: `${motionBase + motionUnit * 1}s`,
|
motionDurationFast: `${(motionBase + motionUnit * 1).toFixed(1)}s`,
|
||||||
motionDurationMid: `${motionBase + motionUnit * 2}s`,
|
motionDurationMid: `${(motionBase + motionUnit * 2).toFixed(1)}s`,
|
||||||
motionDurationSlow: `${motionBase + motionUnit * 3}s`,
|
motionDurationSlow: `${(motionBase + motionUnit * 3).toFixed(1)}s`,
|
||||||
|
|
||||||
// font
|
// font
|
||||||
fontSizes: fontSizes.map(fs => fs.size),
|
fontSizes: fontSizes.map(fs => fs.size),
|
||||||
@ -189,6 +189,7 @@ const seedToken: SeedToken = {
|
|||||||
// Size
|
// Size
|
||||||
sizeUnit: 4,
|
sizeUnit: 4,
|
||||||
sizeBaseStep: 4,
|
sizeBaseStep: 4,
|
||||||
|
sizePopupArrow: 8 * Math.sqrt(2),
|
||||||
|
|
||||||
// Control Base
|
// Control Base
|
||||||
controlHeight: 32,
|
controlHeight: 32,
|
||||||
|
@ -99,6 +99,8 @@ export default function formatToken(derivativeToken: RawMergedToken): AliasToken
|
|||||||
// warningColors,
|
// warningColors,
|
||||||
// errorColors,
|
// errorColors,
|
||||||
|
|
||||||
|
colorLoadingOpacity: 0.65,
|
||||||
|
|
||||||
colorSuccessSecondary: successColors[2],
|
colorSuccessSecondary: successColors[2],
|
||||||
colorWarningSecondary: warningColors[2],
|
colorWarningSecondary: warningColors[2],
|
||||||
colorErrorSecondary: errorColors[2],
|
colorErrorSecondary: errorColors[2],
|
||||||
|
@ -9,16 +9,22 @@ export type OverrideTokenWithoutDerivative = Omit<OverrideToken, 'derivative'>;
|
|||||||
export type OverrideComponent = keyof OverrideTokenWithoutDerivative;
|
export type OverrideComponent = keyof OverrideTokenWithoutDerivative;
|
||||||
export type GlobalTokenWithComponent<ComponentName extends OverrideComponent> = GlobalToken &
|
export type GlobalTokenWithComponent<ComponentName extends OverrideComponent> = GlobalToken &
|
||||||
OverrideToken[ComponentName];
|
OverrideToken[ComponentName];
|
||||||
export type StyleInfo = {
|
|
||||||
|
export interface StyleInfo {
|
||||||
hashId: string;
|
hashId: string;
|
||||||
prefixCls: string;
|
prefixCls: string;
|
||||||
rootPrefixCls: string;
|
rootPrefixCls: string;
|
||||||
iconPrefixCls: string;
|
iconPrefixCls: string;
|
||||||
};
|
}
|
||||||
|
|
||||||
export type TokenWithCommonCls<T> = T & {
|
export type TokenWithCommonCls<T> = T & {
|
||||||
|
/** Wrap component class with `.` prefix */
|
||||||
componentCls: string;
|
componentCls: string;
|
||||||
|
/** Origin prefix which do not have `.` prefix */
|
||||||
prefixCls: string;
|
prefixCls: string;
|
||||||
|
/** Wrap icon class with `.` prefix */
|
||||||
iconCls: string;
|
iconCls: string;
|
||||||
|
/** Wrap ant prefixCls class with `.` prefix */
|
||||||
antCls: string;
|
antCls: string;
|
||||||
};
|
};
|
||||||
export type FullToken<ComponentName extends OverrideComponent> = TokenWithCommonCls<
|
export type FullToken<ComponentName extends OverrideComponent> = TokenWithCommonCls<
|
||||||
@ -38,7 +44,7 @@ function genComponentStyleHook<ComponentName extends OverrideComponent>(
|
|||||||
const rootPrefixCls = getPrefixCls();
|
const rootPrefixCls = getPrefixCls();
|
||||||
|
|
||||||
return [
|
return [
|
||||||
useStyleRegister({ theme, token, hashId, path: [prefixCls] }, () => {
|
useStyleRegister({ theme, token, hashId, path: [component, prefixCls] }, () => {
|
||||||
const { token: proxyToken, flush } = statisticToken(token);
|
const { token: proxyToken, flush } = statisticToken(token);
|
||||||
|
|
||||||
const defaultComponentToken =
|
const defaultComponentToken =
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
import { CSSObject } from '@ant-design/cssinjs';
|
import { CSSObject } from '@ant-design/cssinjs';
|
||||||
import type { DerivativeToken } from '..';
|
import type { DerivativeToken } from '..';
|
||||||
|
|
||||||
|
export { operationUnit } from './operationUnit';
|
||||||
export { roundedArrow } from './roundedArrow';
|
export { roundedArrow } from './roundedArrow';
|
||||||
|
|
||||||
export const resetComponent = (token: DerivativeToken): CSSObject => ({
|
export const resetComponent = (token: DerivativeToken): CSSObject => ({
|
||||||
|
@ -20,7 +20,7 @@ export const roundedArrow = (width: number, outerRadius: number, bgColor: string
|
|||||||
const ey = fy + outerRadius * (1 / Math.sqrt(2));
|
const ey = fy + outerRadius * (1 / Math.sqrt(2));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
borderRadius: `0 0 ${radiusBase}px 0`,
|
borderRadius: { _skip_check_: true, value: `0 0 2px` },
|
||||||
pointerEvents: 'none',
|
pointerEvents: 'none',
|
||||||
|
|
||||||
'&::before': {
|
'&::before': {
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
export default class UnreachableException {
|
|
||||||
error: Error;
|
|
||||||
|
|
||||||
constructor(value: never) {
|
|
||||||
this.error = new Error(`unreachable case: ${JSON.stringify(value)}`);
|
|
||||||
}
|
|
||||||
}
|
|
@ -5,7 +5,7 @@ import { getObserverEntities } from '../utils';
|
|||||||
import Button from '../../button';
|
import Button from '../../button';
|
||||||
import rtlTest from '../../../tests/shared/rtlTest';
|
import rtlTest from '../../../tests/shared/rtlTest';
|
||||||
import accessibilityTest from '../../../tests/shared/accessibilityTest';
|
import accessibilityTest from '../../../tests/shared/accessibilityTest';
|
||||||
import { sleep } from '../../../tests/utils';
|
import { sleep, render } from '../../../tests/utils';
|
||||||
|
|
||||||
const events: Partial<Record<keyof HTMLElementEventMap, (ev: Partial<Event>) => void>> = {};
|
const events: Partial<Record<keyof HTMLElementEventMap, (ev: Partial<Event>) => void>> = {};
|
||||||
|
|
||||||
@ -97,57 +97,47 @@ describe('Affix Render', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
it('Anchor render perfectly', async () => {
|
it('Anchor render perfectly', async () => {
|
||||||
document.body.innerHTML = '<div id="mounter" />';
|
const { container } = render(<AffixMounter />);
|
||||||
|
|
||||||
affixMounterWrapper = mount(<AffixMounter />, { attachTo: document.getElementById('mounter') });
|
|
||||||
await sleep(20);
|
await sleep(20);
|
||||||
|
|
||||||
await movePlaceholder(0);
|
await movePlaceholder(0);
|
||||||
expect(affixMounterWrapper.instance().affix.state.affixStyle).toBeFalsy();
|
expect(container.querySelector('.ant-affix')).toBeFalsy();
|
||||||
|
|
||||||
await movePlaceholder(-100);
|
await movePlaceholder(-100);
|
||||||
expect(affixMounterWrapper.instance().affix.state.affixStyle).toBeTruthy();
|
expect(container.querySelector('.ant-affix')).toBeTruthy();
|
||||||
|
|
||||||
await movePlaceholder(0);
|
await movePlaceholder(0);
|
||||||
expect(affixMounterWrapper.instance().affix.state.affixStyle).toBeFalsy();
|
expect(container.querySelector('.ant-affix')).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('support offsetBottom', async () => {
|
it('support offsetBottom', async () => {
|
||||||
document.body.innerHTML = '<div id="mounter" />';
|
const { container } = render(<AffixMounter offsetBottom={0} />);
|
||||||
|
|
||||||
affixMounterWrapper = mount(<AffixMounter offsetBottom={0} />, {
|
|
||||||
attachTo: document.getElementById('mounter'),
|
|
||||||
});
|
|
||||||
|
|
||||||
await sleep(20);
|
await sleep(20);
|
||||||
|
|
||||||
await movePlaceholder(300);
|
await movePlaceholder(300);
|
||||||
expect(affixMounterWrapper.instance().affix.state.affixStyle).toBeTruthy();
|
expect(container.querySelector('.ant-affix')).toBeTruthy();
|
||||||
|
|
||||||
await movePlaceholder(0);
|
await movePlaceholder(0);
|
||||||
expect(affixMounterWrapper.instance().affix.state.affixStyle).toBeFalsy();
|
expect(container.querySelector('.ant-affix')).toBeFalsy();
|
||||||
|
|
||||||
await movePlaceholder(300);
|
await movePlaceholder(300);
|
||||||
expect(affixMounterWrapper.instance().affix.state.affixStyle).toBeTruthy();
|
expect(container.querySelector('.ant-affix')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('updatePosition when offsetTop changed', async () => {
|
it('updatePosition when offsetTop changed', async () => {
|
||||||
document.body.innerHTML = '<div id="mounter" />';
|
|
||||||
const onChange = jest.fn();
|
const onChange = jest.fn();
|
||||||
|
|
||||||
affixMounterWrapper = mount(<AffixMounter offsetTop={0} onChange={onChange} />, {
|
const { container, rerender } = render(<AffixMounter offsetTop={0} onChange={onChange} />);
|
||||||
attachTo: document.getElementById('mounter'),
|
|
||||||
});
|
|
||||||
await sleep(20);
|
await sleep(20);
|
||||||
|
|
||||||
await movePlaceholder(-100);
|
await movePlaceholder(-100);
|
||||||
expect(onChange).toHaveBeenLastCalledWith(true);
|
expect(onChange).toHaveBeenLastCalledWith(true);
|
||||||
expect(affixMounterWrapper.instance().affix.state.affixStyle?.top).toBe(0);
|
expect(container.querySelector('.ant-affix')).toHaveStyle({ top: 0 });
|
||||||
affixMounterWrapper.setProps({
|
|
||||||
offsetTop: 10,
|
rerender(<AffixMounter offsetTop={10} onChange={onChange} />);
|
||||||
});
|
|
||||||
await sleep(20);
|
await sleep(20);
|
||||||
expect(affixMounterWrapper.instance().affix.state.affixStyle?.top).toBe(10);
|
expect(container.querySelector('.ant-affix')).toHaveStyle({ top: `10px` });
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('updatePosition when target changed', () => {
|
describe('updatePosition when target changed', () => {
|
||||||
@ -201,7 +191,9 @@ describe('Affix Render', () => {
|
|||||||
await sleep(20);
|
await sleep(20);
|
||||||
|
|
||||||
await movePlaceholder(300);
|
await movePlaceholder(300);
|
||||||
expect(affixMounterWrapper.instance().affix.state.affixStyle).toBeTruthy();
|
expect(
|
||||||
|
(affixMounterWrapper.find(AffixMounter).instance() as any).affix.state.affixStyle,
|
||||||
|
).toBeTruthy();
|
||||||
await sleep(20);
|
await sleep(20);
|
||||||
affixMounterWrapper.update();
|
affixMounterWrapper.update();
|
||||||
|
|
||||||
|
@ -38,5 +38,5 @@ const Demo: React.FC = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default () => <Demo />;
|
export default Demo;
|
||||||
```
|
```
|
||||||
|
@ -35,5 +35,5 @@ const Demo: React.FC = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default () => <Demo />;
|
export default Demo;
|
||||||
```
|
```
|
||||||
|
@ -30,7 +30,7 @@ const Demo: React.FC = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default () => <Demo />;
|
export default Demo;
|
||||||
```
|
```
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -32,5 +32,5 @@ const App: React.FC = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default () => <App />;
|
export default App;
|
||||||
```
|
```
|
||||||
|
@ -3,12 +3,13 @@ import classNames from 'classnames';
|
|||||||
import memoizeOne from 'memoize-one';
|
import memoizeOne from 'memoize-one';
|
||||||
import addEventListener from 'rc-util/lib/Dom/addEventListener';
|
import addEventListener from 'rc-util/lib/Dom/addEventListener';
|
||||||
import Affix from '../affix';
|
import Affix from '../affix';
|
||||||
import AnchorLink from './AnchorLink';
|
|
||||||
import { ConfigContext, ConfigConsumerProps } from '../config-provider';
|
import { ConfigContext, ConfigConsumerProps } from '../config-provider';
|
||||||
import scrollTo from '../_util/scrollTo';
|
import scrollTo from '../_util/scrollTo';
|
||||||
import getScroll from '../_util/getScroll';
|
import getScroll from '../_util/getScroll';
|
||||||
import AnchorContext from './context';
|
import AnchorContext from './context';
|
||||||
|
|
||||||
|
import useStyle from './style';
|
||||||
|
|
||||||
export type AnchorContainer = HTMLElement | Window;
|
export type AnchorContainer = HTMLElement | Window;
|
||||||
|
|
||||||
function getDefaultContainer() {
|
function getDefaultContainer() {
|
||||||
@ -62,6 +63,11 @@ export interface AnchorProps {
|
|||||||
onChange?: (currentActiveLink: string) => void;
|
onChange?: (currentActiveLink: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface InternalAnchorProps extends AnchorProps {
|
||||||
|
anchorPrefixCls: string;
|
||||||
|
rootClassName: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface AnchorState {
|
export interface AnchorState {
|
||||||
activeLink: null | string;
|
activeLink: null | string;
|
||||||
}
|
}
|
||||||
@ -84,9 +90,7 @@ export interface AntAnchor {
|
|||||||
) => void;
|
) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Anchor extends React.Component<AnchorProps, AnchorState, ConfigConsumerProps> {
|
class Anchor extends React.Component<InternalAnchorProps, AnchorState, ConfigConsumerProps> {
|
||||||
static Link: typeof AnchorLink;
|
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
affix: true,
|
affix: true,
|
||||||
showInkInFixed: false,
|
showInkInFixed: false,
|
||||||
@ -268,9 +272,9 @@ export default class Anchor extends React.Component<AnchorProps, AnchorState, Co
|
|||||||
);
|
);
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { getPrefixCls, direction } = this.context;
|
const { direction } = this.context;
|
||||||
const {
|
const {
|
||||||
prefixCls: customizePrefixCls,
|
anchorPrefixCls: prefixCls,
|
||||||
className = '',
|
className = '',
|
||||||
style,
|
style,
|
||||||
offsetTop,
|
offsetTop,
|
||||||
@ -278,11 +282,10 @@ export default class Anchor extends React.Component<AnchorProps, AnchorState, Co
|
|||||||
showInkInFixed,
|
showInkInFixed,
|
||||||
children,
|
children,
|
||||||
onClick,
|
onClick,
|
||||||
|
rootClassName,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const { activeLink } = this.state;
|
const { activeLink } = this.state;
|
||||||
|
|
||||||
const prefixCls = getPrefixCls('anchor', customizePrefixCls);
|
|
||||||
|
|
||||||
// To support old version react.
|
// To support old version react.
|
||||||
// Have to add prefixCls on the instance.
|
// Have to add prefixCls on the instance.
|
||||||
// https://github.com/facebook/react/issues/12397
|
// https://github.com/facebook/react/issues/12397
|
||||||
@ -293,6 +296,7 @@ export default class Anchor extends React.Component<AnchorProps, AnchorState, Co
|
|||||||
});
|
});
|
||||||
|
|
||||||
const wrapperClass = classNames(
|
const wrapperClass = classNames(
|
||||||
|
rootClassName,
|
||||||
`${prefixCls}-wrapper`,
|
`${prefixCls}-wrapper`,
|
||||||
{
|
{
|
||||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||||
@ -335,3 +339,25 @@ export default class Anchor extends React.Component<AnchorProps, AnchorState, Co
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// just use in test
|
||||||
|
export type InternalAnchorClass = Anchor;
|
||||||
|
|
||||||
|
const AnchorFC = React.forwardRef<Anchor, AnchorProps>((props, ref) => {
|
||||||
|
const { prefixCls: customizePrefixCls } = props;
|
||||||
|
const { getPrefixCls } = React.useContext(ConfigContext);
|
||||||
|
|
||||||
|
const anchorPrefixCls = getPrefixCls('anchor', customizePrefixCls);
|
||||||
|
|
||||||
|
const [wrapSSR, hashId] = useStyle(anchorPrefixCls);
|
||||||
|
|
||||||
|
const anchorProps: InternalAnchorProps = {
|
||||||
|
...props,
|
||||||
|
|
||||||
|
anchorPrefixCls,
|
||||||
|
rootClassName: hashId,
|
||||||
|
};
|
||||||
|
|
||||||
|
return wrapSSR(<Anchor {...anchorProps} ref={ref} />);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default AnchorFC;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { mount } from 'enzyme';
|
|
||||||
import Anchor from '..';
|
import Anchor from '..';
|
||||||
import { sleep } from '../../../tests/utils';
|
import type { InternalAnchorClass } from '../Anchor';
|
||||||
|
import { sleep, render, fireEvent } from '../../../tests/utils';
|
||||||
|
|
||||||
const { Link } = Anchor;
|
const { Link } = Anchor;
|
||||||
|
|
||||||
@ -47,41 +47,54 @@ describe('Anchor Render', () => {
|
|||||||
|
|
||||||
it('Anchor render perfectly', () => {
|
it('Anchor render perfectly', () => {
|
||||||
const hash = getHashUrl();
|
const hash = getHashUrl();
|
||||||
const wrapper = mount<Anchor>(
|
let anchorInstance: InternalAnchorClass;
|
||||||
<Anchor>
|
const { container } = render(
|
||||||
|
<Anchor
|
||||||
|
ref={node => {
|
||||||
|
anchorInstance = node as InternalAnchorClass;
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Link href={`#${hash}`} title={hash} />
|
<Link href={`#${hash}`} title={hash} />
|
||||||
</Anchor>,
|
</Anchor>,
|
||||||
);
|
);
|
||||||
|
|
||||||
wrapper.find(`a[href="#${hash}"]`).simulate('click');
|
fireEvent.click(container.querySelector(`a[href="#${hash}"]`)!);
|
||||||
|
anchorInstance!.handleScroll();
|
||||||
wrapper.instance().handleScroll();
|
expect(anchorInstance!.state).not.toBe(null);
|
||||||
expect(wrapper.instance().state).not.toBe(null);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Anchor render perfectly for complete href - click', () => {
|
it('Anchor render perfectly for complete href - click', () => {
|
||||||
const hash = getHashUrl();
|
const hash = getHashUrl();
|
||||||
const wrapper = mount<Anchor>(
|
let anchorInstance: InternalAnchorClass;
|
||||||
<Anchor>
|
const { container } = render(
|
||||||
|
<Anchor
|
||||||
|
ref={node => {
|
||||||
|
anchorInstance = node as InternalAnchorClass;
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Link href={`http://www.example.com/#${hash}`} title={hash} />
|
<Link href={`http://www.example.com/#${hash}`} title={hash} />
|
||||||
</Anchor>,
|
</Anchor>,
|
||||||
);
|
);
|
||||||
wrapper.find(`a[href="http://www.example.com/#${hash}"]`).simulate('click');
|
fireEvent.click(container.querySelector(`a[href="http://www.example.com/#${hash}"]`)!);
|
||||||
expect(wrapper.instance().state.activeLink).toBe(`http://www.example.com/#${hash}`);
|
expect(anchorInstance!.state!.activeLink).toBe(`http://www.example.com/#${hash}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Anchor render perfectly for complete href - hash router', async () => {
|
it('Anchor render perfectly for complete href - hash router', async () => {
|
||||||
const root = createDiv();
|
const root = createDiv();
|
||||||
const scrollToSpy = jest.spyOn(window, 'scrollTo');
|
const scrollToSpy = jest.spyOn(window, 'scrollTo');
|
||||||
mount(<div id="/faq?locale=en#Q1">Q1</div>, { attachTo: root });
|
render(<div id="/faq?locale=en#Q1">Q1</div>, { container: root });
|
||||||
const wrapper = mount<Anchor>(
|
let anchorInstance: InternalAnchorClass;
|
||||||
<Anchor>
|
render(
|
||||||
|
<Anchor
|
||||||
|
ref={node => {
|
||||||
|
anchorInstance = node as InternalAnchorClass;
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Link href="/#/faq?locale=en#Q1" title="Q1" />
|
<Link href="/#/faq?locale=en#Q1" title="Q1" />
|
||||||
</Anchor>,
|
</Anchor>,
|
||||||
);
|
);
|
||||||
|
anchorInstance!.handleScrollTo('/#/faq?locale=en#Q1');
|
||||||
wrapper.instance().handleScrollTo('/#/faq?locale=en#Q1');
|
expect(anchorInstance!.state.activeLink).toBe('/#/faq?locale=en#Q1');
|
||||||
expect(wrapper.instance().state.activeLink).toBe('/#/faq?locale=en#Q1');
|
|
||||||
expect(scrollToSpy).not.toHaveBeenCalled();
|
expect(scrollToSpy).not.toHaveBeenCalled();
|
||||||
await sleep(1000);
|
await sleep(1000);
|
||||||
expect(scrollToSpy).toHaveBeenCalled();
|
expect(scrollToSpy).toHaveBeenCalled();
|
||||||
@ -90,28 +103,39 @@ describe('Anchor Render', () => {
|
|||||||
it('Anchor render perfectly for complete href - scroll', () => {
|
it('Anchor render perfectly for complete href - scroll', () => {
|
||||||
const hash = getHashUrl();
|
const hash = getHashUrl();
|
||||||
const root = createDiv();
|
const root = createDiv();
|
||||||
mount(<div id={hash}>Hello</div>, { attachTo: root });
|
render(<div id={hash}>Hello</div>, { container: root });
|
||||||
const wrapper = mount<Anchor>(
|
let anchorInstance: InternalAnchorClass;
|
||||||
<Anchor>
|
render(
|
||||||
|
<Anchor
|
||||||
|
ref={node => {
|
||||||
|
anchorInstance = node as InternalAnchorClass;
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Link href={`http://www.example.com/#${hash}`} title={hash} />
|
<Link href={`http://www.example.com/#${hash}`} title={hash} />
|
||||||
</Anchor>,
|
</Anchor>,
|
||||||
);
|
);
|
||||||
wrapper.instance().handleScroll();
|
anchorInstance!.handleScroll();
|
||||||
expect(wrapper.instance().state.activeLink).toBe(`http://www.example.com/#${hash}`);
|
expect(anchorInstance!.state!.activeLink).toBe(`http://www.example.com/#${hash}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Anchor render perfectly for complete href - scrollTo', async () => {
|
it('Anchor render perfectly for complete href - scrollTo', async () => {
|
||||||
const hash = getHashUrl();
|
const hash = getHashUrl();
|
||||||
const scrollToSpy = jest.spyOn(window, 'scrollTo');
|
const scrollToSpy = jest.spyOn(window, 'scrollTo');
|
||||||
const root = createDiv();
|
const root = createDiv();
|
||||||
mount(<div id={`#${hash}`}>Hello</div>, { attachTo: root });
|
render(<div id={`#${hash}`}>Hello</div>, { container: root });
|
||||||
const wrapper = mount<Anchor>(
|
let anchorInstance: InternalAnchorClass;
|
||||||
<Anchor>
|
render(
|
||||||
|
<Anchor
|
||||||
|
ref={node => {
|
||||||
|
anchorInstance = node as InternalAnchorClass;
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Link href={`##${hash}`} title={hash} />
|
<Link href={`##${hash}`} title={hash} />
|
||||||
</Anchor>,
|
</Anchor>,
|
||||||
);
|
);
|
||||||
wrapper.instance().handleScrollTo(`##${hash}`);
|
|
||||||
expect(wrapper.instance().state.activeLink).toBe(`##${hash}`);
|
anchorInstance!.handleScrollTo(`##${hash}`);
|
||||||
|
expect(anchorInstance!.state.activeLink).toBe(`##${hash}`);
|
||||||
const calls = scrollToSpy.mock.calls.length;
|
const calls = scrollToSpy.mock.calls.length;
|
||||||
await sleep(1000);
|
await sleep(1000);
|
||||||
expect(scrollToSpy.mock.calls.length).toBeGreaterThan(calls);
|
expect(scrollToSpy.mock.calls.length).toBeGreaterThan(calls);
|
||||||
@ -119,50 +143,60 @@ describe('Anchor Render', () => {
|
|||||||
|
|
||||||
it('should remove listener when unmount', async () => {
|
it('should remove listener when unmount', async () => {
|
||||||
const hash = getHashUrl();
|
const hash = getHashUrl();
|
||||||
const wrapper = mount<Anchor>(
|
let anchorInstance: InternalAnchorClass;
|
||||||
<Anchor>
|
const { unmount } = render(
|
||||||
|
<Anchor
|
||||||
|
ref={node => {
|
||||||
|
anchorInstance = node as InternalAnchorClass;
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Link href={`#${hash}`} title={hash} />
|
<Link href={`#${hash}`} title={hash} />
|
||||||
</Anchor>,
|
</Anchor>,
|
||||||
);
|
);
|
||||||
const removeListenerSpy = jest.spyOn((wrapper.instance() as any).scrollEvent, 'remove');
|
|
||||||
wrapper.unmount();
|
const removeListenerSpy = jest.spyOn((anchorInstance! as any).scrollEvent, 'remove');
|
||||||
|
unmount();
|
||||||
expect(removeListenerSpy).toHaveBeenCalled();
|
expect(removeListenerSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should unregister link when unmount children', async () => {
|
it('should unregister link when unmount children', () => {
|
||||||
const hash = getHashUrl();
|
const hash = getHashUrl();
|
||||||
const wrapper = mount<Anchor>(
|
const { container, rerender } = render(
|
||||||
<Anchor>
|
<Anchor>
|
||||||
<Link href={`#${hash}`} title={hash} />
|
<Link href={`#${hash}`} title={hash} />
|
||||||
</Anchor>,
|
</Anchor>,
|
||||||
);
|
);
|
||||||
expect((wrapper.instance() as any).links).toEqual([`#${hash}`]);
|
|
||||||
wrapper.setProps({ children: null });
|
expect(container.querySelectorAll('.ant-anchor-link-title')).toHaveLength(1);
|
||||||
expect((wrapper.instance() as any).links).toEqual([]);
|
expect(container.querySelector('.ant-anchor-link-title')).toHaveAttribute('href', `#${hash}`);
|
||||||
|
|
||||||
|
rerender(<Anchor />);
|
||||||
|
expect(container.querySelector('.ant-anchor-link-title')).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update links when link href update', async () => {
|
it('should update links when link href update', async () => {
|
||||||
const hash = getHashUrl();
|
const hash = getHashUrl();
|
||||||
let anchorInstance: Anchor | null = null;
|
let anchorInstance: InternalAnchorClass;
|
||||||
function AnchorUpdate({ href }: { href: string }) {
|
function AnchorUpdate({ href }: { href: string }) {
|
||||||
return (
|
return (
|
||||||
<Anchor
|
<Anchor
|
||||||
ref={c => {
|
ref={node => {
|
||||||
anchorInstance = c;
|
anchorInstance = node as InternalAnchorClass;
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Link href={href} title={hash} />
|
<Link href={href} title={hash} />
|
||||||
</Anchor>
|
</Anchor>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const wrapper = mount(<AnchorUpdate href={`#${hash}`} />);
|
const { rerender } = render(<AnchorUpdate href={`#${hash}`} />);
|
||||||
|
|
||||||
if (anchorInstance == null) {
|
if (anchorInstance! == null) {
|
||||||
throw new Error('anchorInstance should not be null');
|
throw new Error('anchorInstance should not be null');
|
||||||
}
|
}
|
||||||
expect((anchorInstance as any).links).toEqual([`#${hash}`]);
|
|
||||||
wrapper.setProps({ href: `#${hash}_1` });
|
expect((anchorInstance as any)!.links).toEqual([`#${hash}`]);
|
||||||
expect((anchorInstance as any).links).toEqual([`#${hash}_1`]);
|
rerender(<AnchorUpdate href={`#${hash}_1`} />);
|
||||||
|
expect((anchorInstance as any)!.links).toEqual([`#${hash}_1`]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Anchor onClick event', () => {
|
it('Anchor onClick event', () => {
|
||||||
@ -179,16 +213,20 @@ describe('Anchor Render', () => {
|
|||||||
|
|
||||||
const href = `#${hash}`;
|
const href = `#${hash}`;
|
||||||
const title = hash;
|
const title = hash;
|
||||||
|
let anchorInstance: InternalAnchorClass;
|
||||||
const wrapper = mount<Anchor>(
|
const { container } = render(
|
||||||
<Anchor onClick={handleClick}>
|
<Anchor
|
||||||
|
onClick={handleClick}
|
||||||
|
ref={node => {
|
||||||
|
anchorInstance = node as InternalAnchorClass;
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Link href={href} title={title} />
|
<Link href={href} title={title} />
|
||||||
</Anchor>,
|
</Anchor>,
|
||||||
);
|
);
|
||||||
|
|
||||||
wrapper.find(`a[href="${href}"]`).simulate('click');
|
fireEvent.click(container.querySelector(`a[href="${href}"]`)!);
|
||||||
|
anchorInstance!.handleScroll();
|
||||||
wrapper.instance().handleScroll();
|
|
||||||
expect(event).not.toBe(undefined);
|
expect(event).not.toBe(undefined);
|
||||||
expect(link).toEqual({ href, title });
|
expect(link).toEqual({ href, title });
|
||||||
});
|
});
|
||||||
@ -196,18 +234,28 @@ describe('Anchor Render', () => {
|
|||||||
it('Different function returns the same DOM', async () => {
|
it('Different function returns the same DOM', async () => {
|
||||||
const hash = getHashUrl();
|
const hash = getHashUrl();
|
||||||
const root = createDiv();
|
const root = createDiv();
|
||||||
mount(<div id={hash}>Hello</div>, { attachTo: root });
|
render(<div id={hash}>Hello</div>, { container: root });
|
||||||
const getContainerA = createGetContainer(hash);
|
const getContainerA = createGetContainer(hash);
|
||||||
const getContainerB = createGetContainer(hash);
|
const getContainerB = createGetContainer(hash);
|
||||||
|
let anchorInstance: InternalAnchorClass;
|
||||||
const wrapper = mount<Anchor>(
|
const { rerender } = render(
|
||||||
<Anchor getContainer={getContainerA}>
|
<Anchor
|
||||||
|
getContainer={getContainerA}
|
||||||
|
ref={node => {
|
||||||
|
anchorInstance = node as InternalAnchorClass;
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Link href={`#${hash}`} title={hash} />
|
<Link href={`#${hash}`} title={hash} />
|
||||||
</Anchor>,
|
</Anchor>,
|
||||||
);
|
);
|
||||||
const removeListenerSpy = jest.spyOn((wrapper.instance() as any).scrollEvent, 'remove');
|
|
||||||
|
const removeListenerSpy = jest.spyOn((anchorInstance! as any).scrollEvent, 'remove');
|
||||||
await sleep(1000);
|
await sleep(1000);
|
||||||
wrapper.setProps({ getContainer: getContainerB });
|
rerender(
|
||||||
|
<Anchor getContainer={getContainerB}>
|
||||||
|
<Link href={`#${hash}`} title={hash} />
|
||||||
|
</Anchor>,
|
||||||
|
);
|
||||||
expect(removeListenerSpy).not.toHaveBeenCalled();
|
expect(removeListenerSpy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -215,53 +263,73 @@ describe('Anchor Render', () => {
|
|||||||
const hash1 = getHashUrl();
|
const hash1 = getHashUrl();
|
||||||
const hash2 = getHashUrl();
|
const hash2 = getHashUrl();
|
||||||
const root = createDiv();
|
const root = createDiv();
|
||||||
mount(
|
render(
|
||||||
<div>
|
<div>
|
||||||
<div id={hash1}>Hello</div>
|
<div id={hash1}>Hello</div>
|
||||||
<div id={hash2}>World</div>
|
<div id={hash2}>World</div>
|
||||||
</div>,
|
</div>,
|
||||||
{ attachTo: root },
|
{ container: root },
|
||||||
);
|
);
|
||||||
const getContainerA = createGetContainer(hash1);
|
const getContainerA = createGetContainer(hash1);
|
||||||
const getContainerB = createGetContainer(hash2);
|
const getContainerB = createGetContainer(hash2);
|
||||||
const wrapper = mount<Anchor>(
|
let anchorInstance: InternalAnchorClass;
|
||||||
<Anchor getContainer={getContainerA}>
|
const { rerender } = render(
|
||||||
|
<Anchor
|
||||||
|
getContainer={getContainerA}
|
||||||
|
ref={node => {
|
||||||
|
anchorInstance = node as InternalAnchorClass;
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Link href={`#${hash1}`} title={hash1} />
|
<Link href={`#${hash1}`} title={hash1} />
|
||||||
<Link href={`#${hash2}`} title={hash2} />
|
<Link href={`#${hash2}`} title={hash2} />
|
||||||
</Anchor>,
|
</Anchor>,
|
||||||
);
|
);
|
||||||
const removeListenerSpy = jest.spyOn((wrapper.instance() as any).scrollEvent, 'remove');
|
|
||||||
|
const removeListenerSpy = jest.spyOn((anchorInstance! as any).scrollEvent, 'remove');
|
||||||
expect(removeListenerSpy).not.toHaveBeenCalled();
|
expect(removeListenerSpy).not.toHaveBeenCalled();
|
||||||
await sleep(1000);
|
await sleep(1000);
|
||||||
wrapper.setProps({ getContainer: getContainerB });
|
rerender(
|
||||||
|
<Anchor getContainer={getContainerB}>
|
||||||
|
<Link href={`#${hash1}`} title={hash1} />
|
||||||
|
<Link href={`#${hash2}`} title={hash2} />
|
||||||
|
</Anchor>,
|
||||||
|
);
|
||||||
expect(removeListenerSpy).toHaveBeenCalled();
|
expect(removeListenerSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Same function returns the same DOM', () => {
|
it('Same function returns the same DOM', () => {
|
||||||
const hash = getHashUrl();
|
const hash = getHashUrl();
|
||||||
const root = createDiv();
|
const root = createDiv();
|
||||||
mount(<div id={hash}>Hello</div>, { attachTo: root });
|
render(<div id={hash}>Hello</div>, { container: root });
|
||||||
const getContainer = createGetContainer(hash);
|
const getContainer = createGetContainer(hash);
|
||||||
const wrapper = mount(
|
let anchorInstance: InternalAnchorClass;
|
||||||
<Anchor getContainer={getContainer}>
|
const { container } = render(
|
||||||
|
<Anchor
|
||||||
|
getContainer={getContainer}
|
||||||
|
ref={node => {
|
||||||
|
anchorInstance = node as InternalAnchorClass;
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Link href={`#${hash}`} title={hash} />
|
<Link href={`#${hash}`} title={hash} />
|
||||||
</Anchor>,
|
</Anchor>,
|
||||||
);
|
);
|
||||||
wrapper.find(`a[href="#${hash}"]`).simulate('click');
|
|
||||||
(wrapper.instance() as any).handleScroll();
|
fireEvent.click(container.querySelector(`a[href="#${hash}"]`)!);
|
||||||
expect(wrapper.instance().state).not.toBe(null);
|
|
||||||
|
anchorInstance!.handleScroll();
|
||||||
|
expect(anchorInstance!.state).not.toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Same function returns different DOM', async () => {
|
it('Same function returns different DOM', async () => {
|
||||||
const hash1 = getHashUrl();
|
const hash1 = getHashUrl();
|
||||||
const hash2 = getHashUrl();
|
const hash2 = getHashUrl();
|
||||||
const root = createDiv();
|
const root = createDiv();
|
||||||
mount(
|
render(
|
||||||
<div>
|
<div>
|
||||||
<div id={hash1}>Hello</div>
|
<div id={hash1}>Hello</div>
|
||||||
<div id={hash2}>World</div>
|
<div id={hash2}>World</div>
|
||||||
</div>,
|
</div>,
|
||||||
{ attachTo: root },
|
{ container: root },
|
||||||
);
|
);
|
||||||
const holdContainer = {
|
const holdContainer = {
|
||||||
container: document.getElementById(hash1),
|
container: document.getElementById(hash1),
|
||||||
@ -272,17 +340,28 @@ describe('Anchor Render', () => {
|
|||||||
}
|
}
|
||||||
return holdContainer.container;
|
return holdContainer.container;
|
||||||
};
|
};
|
||||||
const wrapper = mount(
|
let anchorInstance: InternalAnchorClass;
|
||||||
|
const { rerender } = render(
|
||||||
|
<Anchor
|
||||||
|
getContainer={getContainer}
|
||||||
|
ref={node => {
|
||||||
|
anchorInstance = node as InternalAnchorClass;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Link href={`#${hash1}`} title={hash1} />
|
||||||
|
<Link href={`#${hash2}`} title={hash2} />
|
||||||
|
</Anchor>,
|
||||||
|
);
|
||||||
|
const removeListenerSpy = jest.spyOn((anchorInstance! as any).scrollEvent, 'remove');
|
||||||
|
expect(removeListenerSpy).not.toHaveBeenCalled();
|
||||||
|
await sleep(1000);
|
||||||
|
holdContainer.container = document.getElementById(hash2);
|
||||||
|
rerender(
|
||||||
<Anchor getContainer={getContainer}>
|
<Anchor getContainer={getContainer}>
|
||||||
<Link href={`#${hash1}`} title={hash1} />
|
<Link href={`#${hash1}`} title={hash1} />
|
||||||
<Link href={`#${hash2}`} title={hash2} />
|
<Link href={`#${hash2}`} title={hash2} />
|
||||||
</Anchor>,
|
</Anchor>,
|
||||||
);
|
);
|
||||||
const removeListenerSpy = jest.spyOn((wrapper.instance() as any).scrollEvent, 'remove');
|
|
||||||
expect(removeListenerSpy).not.toHaveBeenCalled();
|
|
||||||
await sleep(1000);
|
|
||||||
holdContainer.container = document.getElementById(hash2);
|
|
||||||
wrapper.setProps({ 'data-only-trigger-re-render': true });
|
|
||||||
expect(removeListenerSpy).toHaveBeenCalled();
|
expect(removeListenerSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -305,25 +384,45 @@ describe('Anchor Render', () => {
|
|||||||
|
|
||||||
const scrollToSpy = jest.spyOn(window, 'scrollTo');
|
const scrollToSpy = jest.spyOn(window, 'scrollTo');
|
||||||
const root = createDiv();
|
const root = createDiv();
|
||||||
mount(<h1 id={hash}>Hello</h1>, { attachTo: root });
|
render(<h1 id={hash}>Hello</h1>, { container: root });
|
||||||
const wrapper = mount<Anchor>(
|
let anchorInstance: InternalAnchorClass;
|
||||||
<Anchor>
|
const { rerender } = render(
|
||||||
|
<Anchor
|
||||||
|
ref={node => {
|
||||||
|
anchorInstance = node as InternalAnchorClass;
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Link href={`#${hash}`} title={hash} />
|
<Link href={`#${hash}`} title={hash} />
|
||||||
</Anchor>,
|
</Anchor>,
|
||||||
);
|
);
|
||||||
wrapper.instance().handleScrollTo(`#${hash}`);
|
|
||||||
|
const setProps = (props: Record<string, any>) =>
|
||||||
|
rerender(
|
||||||
|
<Anchor
|
||||||
|
ref={node => {
|
||||||
|
anchorInstance = node as InternalAnchorClass;
|
||||||
|
}}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<Link href={`#${hash}`} title={hash} />
|
||||||
|
</Anchor>,
|
||||||
|
);
|
||||||
|
|
||||||
|
anchorInstance!.handleScrollTo(`#${hash}`);
|
||||||
await sleep(30);
|
await sleep(30);
|
||||||
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 1000);
|
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 1000);
|
||||||
dateNowMock = dataNowMockFn();
|
dateNowMock = dataNowMockFn();
|
||||||
|
|
||||||
wrapper.setProps({ offsetTop: 100 });
|
setProps({ offsetTop: 100 });
|
||||||
wrapper.instance().handleScrollTo(`#${hash}`);
|
|
||||||
|
anchorInstance!.handleScrollTo(`#${hash}`);
|
||||||
await sleep(30);
|
await sleep(30);
|
||||||
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 900);
|
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 900);
|
||||||
dateNowMock = dataNowMockFn();
|
dateNowMock = dataNowMockFn();
|
||||||
|
|
||||||
wrapper.setProps({ targetOffset: 200 });
|
setProps({ targetOffset: 200 });
|
||||||
wrapper.instance().handleScrollTo(`#${hash}`);
|
|
||||||
|
anchorInstance!.handleScrollTo(`#${hash}`);
|
||||||
await sleep(30);
|
await sleep(30);
|
||||||
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 800);
|
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 800);
|
||||||
|
|
||||||
@ -350,25 +449,43 @@ describe('Anchor Render', () => {
|
|||||||
|
|
||||||
const scrollToSpy = jest.spyOn(window, 'scrollTo');
|
const scrollToSpy = jest.spyOn(window, 'scrollTo');
|
||||||
const root = createDiv();
|
const root = createDiv();
|
||||||
mount(<h1 id={hash}>Hello</h1>, { attachTo: root });
|
render(<h1 id={hash}>Hello</h1>, { container: root });
|
||||||
const wrapper = mount<Anchor>(
|
let anchorInstance: InternalAnchorClass;
|
||||||
<Anchor>
|
const { rerender } = render(
|
||||||
|
<Anchor
|
||||||
|
ref={node => {
|
||||||
|
anchorInstance = node as InternalAnchorClass;
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Link href={`#${hash}`} title={hash} />
|
<Link href={`#${hash}`} title={hash} />
|
||||||
</Anchor>,
|
</Anchor>,
|
||||||
);
|
);
|
||||||
wrapper.instance().handleScrollTo(`#${hash}`);
|
|
||||||
|
const setProps = (props: Record<string, any>) =>
|
||||||
|
rerender(
|
||||||
|
<Anchor
|
||||||
|
ref={node => {
|
||||||
|
anchorInstance = node as InternalAnchorClass;
|
||||||
|
}}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<Link href={`#${hash}`} title={hash} />
|
||||||
|
</Anchor>,
|
||||||
|
);
|
||||||
|
|
||||||
|
anchorInstance!.handleScrollTo(`#${hash}`);
|
||||||
await sleep(30);
|
await sleep(30);
|
||||||
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 1000);
|
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 1000);
|
||||||
dateNowMock = dataNowMockFn();
|
dateNowMock = dataNowMockFn();
|
||||||
|
|
||||||
wrapper.setProps({ offsetTop: 100 });
|
setProps({ offsetTop: 100 });
|
||||||
wrapper.instance().handleScrollTo(`#${hash}`);
|
anchorInstance!.handleScrollTo(`#${hash}`);
|
||||||
await sleep(30);
|
await sleep(30);
|
||||||
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 900);
|
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 900);
|
||||||
dateNowMock = dataNowMockFn();
|
dateNowMock = dataNowMockFn();
|
||||||
|
|
||||||
wrapper.setProps({ targetOffset: 200 });
|
setProps({ targetOffset: 200 });
|
||||||
wrapper.instance().handleScrollTo(`#${hash}`);
|
anchorInstance!.handleScrollTo(`#${hash}`);
|
||||||
await sleep(30);
|
await sleep(30);
|
||||||
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 800);
|
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 800);
|
||||||
|
|
||||||
@ -379,29 +496,44 @@ describe('Anchor Render', () => {
|
|||||||
const hash1 = getHashUrl();
|
const hash1 = getHashUrl();
|
||||||
const hash2 = getHashUrl();
|
const hash2 = getHashUrl();
|
||||||
const onChange = jest.fn();
|
const onChange = jest.fn();
|
||||||
const wrapper = mount<Anchor>(
|
let anchorInstance: InternalAnchorClass;
|
||||||
<Anchor onChange={onChange}>
|
render(
|
||||||
|
<Anchor
|
||||||
|
onChange={onChange}
|
||||||
|
ref={node => {
|
||||||
|
anchorInstance = node as InternalAnchorClass;
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Link href={`#${hash1}`} title={hash1} />
|
<Link href={`#${hash1}`} title={hash1} />
|
||||||
<Link href={`#${hash2}`} title={hash2} />
|
<Link href={`#${hash2}`} title={hash2} />
|
||||||
</Anchor>,
|
</Anchor>,
|
||||||
|
// https://github.com/testing-library/react-testing-library/releases/tag/v13.0.0
|
||||||
|
// @ts-ignore
|
||||||
|
{ legacyRoot: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(onChange).toHaveBeenCalledTimes(1);
|
expect(onChange).toHaveBeenCalledTimes(1);
|
||||||
wrapper.instance().handleScrollTo(hash2);
|
anchorInstance!.handleScrollTo(hash2);
|
||||||
expect(onChange).toHaveBeenCalledTimes(2);
|
expect(onChange).toHaveBeenCalledTimes(2);
|
||||||
expect(onChange).toHaveBeenCalledWith(hash2);
|
expect(onChange).toHaveBeenCalledWith(hash2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('invalid hash', async () => {
|
it('invalid hash', async () => {
|
||||||
const wrapper = mount<Anchor>(
|
let anchorInstance: InternalAnchorClass;
|
||||||
<Anchor>
|
const { container } = render(
|
||||||
|
<Anchor
|
||||||
|
ref={node => {
|
||||||
|
anchorInstance = node as InternalAnchorClass;
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Link href="notexsited" title="title" />
|
<Link href="notexsited" title="title" />
|
||||||
</Anchor>,
|
</Anchor>,
|
||||||
);
|
);
|
||||||
|
|
||||||
wrapper.find(`a[href="notexsited"]`).simulate('click');
|
fireEvent.click(container.querySelector(`a[href="notexsited"]`)!);
|
||||||
|
|
||||||
wrapper.instance().handleScrollTo('notexsited');
|
anchorInstance!.handleScrollTo('notexsited');
|
||||||
expect(wrapper.instance().state).not.toBe(null);
|
expect(anchorInstance!.state).not.toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('test edge case when getBoundingClientRect return zero size', async () => {
|
it('test edge case when getBoundingClientRect return zero size', async () => {
|
||||||
@ -428,25 +560,42 @@ describe('Anchor Render', () => {
|
|||||||
|
|
||||||
const scrollToSpy = jest.spyOn(window, 'scrollTo');
|
const scrollToSpy = jest.spyOn(window, 'scrollTo');
|
||||||
const root = createDiv();
|
const root = createDiv();
|
||||||
mount(<h1 id={hash}>Hello</h1>, { attachTo: root });
|
render(<h1 id={hash}>Hello</h1>, { container: root });
|
||||||
const wrapper = mount<Anchor>(
|
let anchorInstance: InternalAnchorClass;
|
||||||
<Anchor>
|
const { rerender } = render(
|
||||||
|
<Anchor
|
||||||
|
ref={node => {
|
||||||
|
anchorInstance = node as InternalAnchorClass;
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Link href={`#${hash}`} title={hash} />
|
<Link href={`#${hash}`} title={hash} />
|
||||||
</Anchor>,
|
</Anchor>,
|
||||||
);
|
);
|
||||||
wrapper.instance().handleScrollTo(`#${hash}`);
|
|
||||||
|
const setProps = (props: Record<string, any>) =>
|
||||||
|
rerender(
|
||||||
|
<Anchor
|
||||||
|
ref={node => {
|
||||||
|
anchorInstance = node as InternalAnchorClass;
|
||||||
|
}}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<Link href={`#${hash}`} title={hash} />
|
||||||
|
</Anchor>,
|
||||||
|
);
|
||||||
|
anchorInstance!.handleScrollTo(`#${hash}`);
|
||||||
await sleep(30);
|
await sleep(30);
|
||||||
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 1000);
|
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 1000);
|
||||||
dateNowMock = dataNowMockFn();
|
dateNowMock = dataNowMockFn();
|
||||||
|
|
||||||
wrapper.setProps({ offsetTop: 100 });
|
setProps({ offsetTop: 100 });
|
||||||
wrapper.instance().handleScrollTo(`#${hash}`);
|
anchorInstance!.handleScrollTo(`#${hash}`);
|
||||||
await sleep(30);
|
await sleep(30);
|
||||||
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 900);
|
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 900);
|
||||||
dateNowMock = dataNowMockFn();
|
dateNowMock = dataNowMockFn();
|
||||||
|
|
||||||
wrapper.setProps({ targetOffset: 200 });
|
setProps({ targetOffset: 200 });
|
||||||
wrapper.instance().handleScrollTo(`#${hash}`);
|
anchorInstance!.handleScrollTo(`#${hash}`);
|
||||||
await sleep(30);
|
await sleep(30);
|
||||||
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 800);
|
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 800);
|
||||||
|
|
||||||
@ -477,25 +626,44 @@ describe('Anchor Render', () => {
|
|||||||
|
|
||||||
const scrollToSpy = jest.spyOn(window, 'scrollTo');
|
const scrollToSpy = jest.spyOn(window, 'scrollTo');
|
||||||
const root = createDiv();
|
const root = createDiv();
|
||||||
mount(<h1 id={hash}>Hello</h1>, { attachTo: root });
|
render(<h1 id={hash}>Hello</h1>, { container: root });
|
||||||
const wrapper = mount<Anchor>(
|
|
||||||
<Anchor getContainer={() => document.body}>
|
let anchorInstance: InternalAnchorClass;
|
||||||
|
const { rerender } = render(
|
||||||
|
<Anchor
|
||||||
|
getContainer={() => document.body}
|
||||||
|
ref={node => {
|
||||||
|
anchorInstance = node as InternalAnchorClass;
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Link href={`#${hash}`} title={hash} />
|
<Link href={`#${hash}`} title={hash} />
|
||||||
</Anchor>,
|
</Anchor>,
|
||||||
);
|
);
|
||||||
wrapper.instance().handleScrollTo(`#${hash}`);
|
|
||||||
|
const setProps = (props: Record<string, any>) =>
|
||||||
|
rerender(
|
||||||
|
<Anchor
|
||||||
|
getContainer={() => document.body}
|
||||||
|
ref={node => {
|
||||||
|
anchorInstance = node as InternalAnchorClass;
|
||||||
|
}}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<Link href={`#${hash}`} title={hash} />
|
||||||
|
</Anchor>,
|
||||||
|
);
|
||||||
|
anchorInstance!.handleScrollTo(`#${hash}`);
|
||||||
await sleep(30);
|
await sleep(30);
|
||||||
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 800);
|
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 800);
|
||||||
dateNowMock = dataNowMockFn();
|
dateNowMock = dataNowMockFn();
|
||||||
|
|
||||||
wrapper.setProps({ offsetTop: 100 });
|
setProps({ offsetTop: 100 });
|
||||||
wrapper.instance().handleScrollTo(`#${hash}`);
|
anchorInstance!.handleScrollTo(`#${hash}`);
|
||||||
await sleep(30);
|
await sleep(30);
|
||||||
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 800);
|
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 800);
|
||||||
dateNowMock = dataNowMockFn();
|
dateNowMock = dataNowMockFn();
|
||||||
|
setProps({ targetOffset: 200 });
|
||||||
wrapper.setProps({ targetOffset: 200 });
|
anchorInstance!.handleScrollTo(`#${hash}`);
|
||||||
wrapper.instance().handleScrollTo(`#${hash}`);
|
|
||||||
await sleep(30);
|
await sleep(30);
|
||||||
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 800);
|
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 800);
|
||||||
|
|
||||||
@ -507,13 +675,20 @@ describe('Anchor Render', () => {
|
|||||||
const hash1 = getHashUrl();
|
const hash1 = getHashUrl();
|
||||||
const hash2 = getHashUrl();
|
const hash2 = getHashUrl();
|
||||||
const getCurrentAnchor = () => `#${hash2}`;
|
const getCurrentAnchor = () => `#${hash2}`;
|
||||||
const wrapper = mount<Anchor>(
|
let anchorInstance: InternalAnchorClass;
|
||||||
<Anchor getCurrentAnchor={getCurrentAnchor}>
|
render(
|
||||||
|
<Anchor
|
||||||
|
getCurrentAnchor={getCurrentAnchor}
|
||||||
|
ref={node => {
|
||||||
|
anchorInstance = node as InternalAnchorClass;
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Link href={`#${hash1}`} title={hash1} />
|
<Link href={`#${hash1}`} title={hash1} />
|
||||||
<Link href={`#${hash2}`} title={hash2} />
|
<Link href={`#${hash2}`} title={hash2} />
|
||||||
</Anchor>,
|
</Anchor>,
|
||||||
);
|
);
|
||||||
expect(wrapper.instance().state.activeLink).toBe(`#${hash2}`);
|
|
||||||
|
expect(anchorInstance!.state.activeLink).toBe(`#${hash2}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
// https://github.com/ant-design/ant-design/issues/30584
|
// https://github.com/ant-design/ant-design/issues/30584
|
||||||
@ -521,14 +696,25 @@ describe('Anchor Render', () => {
|
|||||||
const hash1 = getHashUrl();
|
const hash1 = getHashUrl();
|
||||||
const hash2 = getHashUrl();
|
const hash2 = getHashUrl();
|
||||||
const onChange = jest.fn();
|
const onChange = jest.fn();
|
||||||
const wrapper = mount<Anchor>(
|
let anchorInstance: InternalAnchorClass;
|
||||||
<Anchor onChange={onChange} getCurrentAnchor={() => hash1}>
|
render(
|
||||||
|
<Anchor
|
||||||
|
onChange={onChange}
|
||||||
|
getCurrentAnchor={() => hash1}
|
||||||
|
ref={node => {
|
||||||
|
anchorInstance = node as InternalAnchorClass;
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Link href={`#${hash1}`} title={hash1} />
|
<Link href={`#${hash1}`} title={hash1} />
|
||||||
<Link href={`#${hash2}`} title={hash2} />
|
<Link href={`#${hash2}`} title={hash2} />
|
||||||
</Anchor>,
|
</Anchor>,
|
||||||
|
// https://github.com/testing-library/react-testing-library/releases/tag/v13.0.0
|
||||||
|
// @ts-ignore
|
||||||
|
{ legacyRoot: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(onChange).toHaveBeenCalledTimes(1);
|
expect(onChange).toHaveBeenCalledTimes(1);
|
||||||
wrapper.instance().handleScrollTo(hash2);
|
anchorInstance!.handleScrollTo(hash2);
|
||||||
expect(onChange).toHaveBeenCalledTimes(2);
|
expect(onChange).toHaveBeenCalledTimes(2);
|
||||||
expect(onChange).toHaveBeenCalledWith(hash2);
|
expect(onChange).toHaveBeenCalledWith(hash2);
|
||||||
});
|
});
|
||||||
@ -538,16 +724,16 @@ describe('Anchor Render', () => {
|
|||||||
const hash1 = getHashUrl();
|
const hash1 = getHashUrl();
|
||||||
const hash2 = getHashUrl();
|
const hash2 = getHashUrl();
|
||||||
const getCurrentAnchor = jest.fn();
|
const getCurrentAnchor = jest.fn();
|
||||||
const wrapper = mount<Anchor>(
|
const { container } = render(
|
||||||
<Anchor getCurrentAnchor={getCurrentAnchor}>
|
<Anchor getCurrentAnchor={getCurrentAnchor}>
|
||||||
<Link href={`#${hash1}`} title={hash1} />
|
<Link href={`#${hash1}`} title={hash1} />
|
||||||
<Link href={`#${hash2}`} title={hash2} />
|
<Link href={`#${hash2}`} title={hash2} />
|
||||||
</Anchor>,
|
</Anchor>,
|
||||||
);
|
);
|
||||||
|
|
||||||
wrapper.find(`a[href="#${hash1}"]`).simulate('click');
|
fireEvent.click(container.querySelector(`a[href="#${hash1}"]`)!);
|
||||||
expect(getCurrentAnchor).toHaveBeenCalledWith(`#${hash1}`);
|
expect(getCurrentAnchor).toHaveBeenCalledWith(`#${hash1}`);
|
||||||
wrapper.find(`a[href="#${hash2}"]`).simulate('click');
|
fireEvent.click(container.querySelector(`a[href="#${hash2}"]`)!);
|
||||||
expect(getCurrentAnchor).toHaveBeenCalledWith(`#${hash2}`);
|
expect(getCurrentAnchor).toHaveBeenCalledWith(`#${hash2}`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { memo, useState, useRef, useContext } from 'react';
|
import React, { memo, useState, useRef, useContext } from 'react';
|
||||||
import { mount } from 'enzyme';
|
|
||||||
import Anchor from '../Anchor';
|
import Anchor from '../Anchor';
|
||||||
import AnchorContext from '../context';
|
import AnchorContext from '../context';
|
||||||
|
import { getNodeText, render, fireEvent } from '../../../tests/utils';
|
||||||
|
|
||||||
// we use'memo' here in order to only render inner component while context changed.
|
// we use'memo' here in order to only render inner component while context changed.
|
||||||
const CacheInner = memo(() => {
|
const CacheInner = memo(() => {
|
||||||
@ -38,14 +38,16 @@ const CacheOuter = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
it("Rendering on Anchor without changed AnchorContext won't trigger rendering on child component.", () => {
|
it("Rendering on Anchor without changed AnchorContext won't trigger rendering on child component.", () => {
|
||||||
const wrapper = mount(<CacheOuter />);
|
const { container } = render(<CacheOuter />);
|
||||||
const childCount = wrapper.find('#child_count').text();
|
const childCount = getNodeText(container.querySelector('#child_count')!);
|
||||||
wrapper.find('#parent_btn').at(0).simulate('click');
|
|
||||||
expect(wrapper.find('#parent_count').text()).toBe('2');
|
fireEvent.click(container.querySelector('#parent_btn')!);
|
||||||
|
|
||||||
|
expect(getNodeText(container.querySelector('#parent_count')!)).toBe('2');
|
||||||
// child component won't rerender
|
// child component won't rerender
|
||||||
expect(wrapper.find('#child_count').text()).toBe(childCount);
|
expect(getNodeText(container.querySelector('#child_count')!)).toBe(childCount);
|
||||||
wrapper.find('#parent_btn').at(0).simulate('click');
|
fireEvent.click(container.querySelector('#parent_btn')!);
|
||||||
expect(wrapper.find('#parent_count').text()).toBe('3');
|
expect(getNodeText(container.querySelector('#parent_count')!)).toBe('3');
|
||||||
// child component won't rerender
|
// child component won't rerender
|
||||||
expect(wrapper.find('#child_count').text()).toBe(childCount);
|
expect(getNodeText(container.querySelector('#child_count')!)).toBe(childCount);
|
||||||
});
|
});
|
||||||
|
@ -1,8 +1,16 @@
|
|||||||
import Anchor from './Anchor';
|
import InternalAnchor from './Anchor';
|
||||||
import AnchorLink from './AnchorLink';
|
import AnchorLink from './AnchorLink';
|
||||||
|
|
||||||
export { AnchorProps } from './Anchor';
|
export { AnchorProps } from './Anchor';
|
||||||
export { AnchorLinkProps } from './AnchorLink';
|
export { AnchorLinkProps } from './AnchorLink';
|
||||||
|
|
||||||
|
type InternalAnchorType = typeof InternalAnchor;
|
||||||
|
|
||||||
|
interface AnchorInterface extends InternalAnchorType {
|
||||||
|
Link: typeof AnchorLink;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Anchor = InternalAnchor as AnchorInterface;
|
||||||
|
|
||||||
Anchor.Link = AnchorLink;
|
Anchor.Link = AnchorLink;
|
||||||
export default Anchor;
|
export default Anchor;
|
||||||
|
@ -1,87 +1,87 @@
|
|||||||
@import '../../style/themes/index';
|
// @import '../../style/themes/index';
|
||||||
@import '../../style/mixins/index';
|
// @import '../../style/mixins/index';
|
||||||
|
|
||||||
@anchor-border-width: 2px;
|
// @anchor-border-width: 2px;
|
||||||
|
|
||||||
.@{ant-prefix}-anchor {
|
// .@{ant-prefix}-anchor {
|
||||||
.reset-component();
|
// .reset-component();
|
||||||
|
|
||||||
position: relative;
|
// position: relative;
|
||||||
padding-left: @anchor-border-width;
|
// padding-left: @anchor-border-width;
|
||||||
|
|
||||||
&-wrapper {
|
// &-wrapper {
|
||||||
margin-left: -4px;
|
// margin-left: -4px;
|
||||||
padding-left: 4px;
|
// padding-left: 4px;
|
||||||
overflow: auto;
|
// overflow: auto;
|
||||||
background-color: @anchor-bg;
|
// background-color: @anchor-bg;
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-ink {
|
// &-ink {
|
||||||
position: absolute;
|
// position: absolute;
|
||||||
top: 0;
|
// top: 0;
|
||||||
left: 0;
|
// left: 0;
|
||||||
height: 100%;
|
// height: 100%;
|
||||||
|
|
||||||
&::before {
|
// &::before {
|
||||||
position: relative;
|
// position: relative;
|
||||||
display: block;
|
// display: block;
|
||||||
width: @anchor-border-width;
|
// width: @anchor-border-width;
|
||||||
height: 100%;
|
// height: 100%;
|
||||||
margin: 0 auto;
|
// margin: 0 auto;
|
||||||
background-color: @anchor-border-color;
|
// background-color: @anchor-border-color;
|
||||||
content: ' ';
|
// content: ' ';
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-ball {
|
// &-ball {
|
||||||
position: absolute;
|
// position: absolute;
|
||||||
left: 50%;
|
// left: 50%;
|
||||||
display: none;
|
// display: none;
|
||||||
width: 8px;
|
// width: 8px;
|
||||||
height: 8px;
|
// height: 8px;
|
||||||
background-color: @component-background;
|
// background-color: @component-background;
|
||||||
border: 2px solid @primary-color;
|
// border: 2px solid @primary-color;
|
||||||
border-radius: 8px;
|
// border-radius: 8px;
|
||||||
transform: translateX(-50%);
|
// transform: translateX(-50%);
|
||||||
transition: top 0.3s ease-in-out;
|
// transition: top 0.3s ease-in-out;
|
||||||
|
|
||||||
&.visible {
|
// &.visible {
|
||||||
display: inline-block;
|
// display: inline-block;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-fixed &-ink &-ink-ball {
|
// &-fixed &-ink &-ink-ball {
|
||||||
display: none;
|
// display: none;
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-link {
|
// &-link {
|
||||||
padding: @anchor-link-padding;
|
// padding: @anchor-link-padding;
|
||||||
line-height: 1.143;
|
// line-height: 1.143;
|
||||||
|
|
||||||
&-title {
|
// &-title {
|
||||||
position: relative;
|
// position: relative;
|
||||||
display: block;
|
// display: block;
|
||||||
margin-bottom: 6px;
|
// margin-bottom: 6px;
|
||||||
overflow: hidden;
|
// overflow: hidden;
|
||||||
color: @text-color;
|
// color: @text-color;
|
||||||
white-space: nowrap;
|
// white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
// text-overflow: ellipsis;
|
||||||
transition: all 0.3s;
|
// transition: all 0.3s;
|
||||||
|
|
||||||
&:only-child {
|
// &:only-child {
|
||||||
margin-bottom: 0;
|
// margin-bottom: 0;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-active > &-title {
|
// &-active > &-title {
|
||||||
color: @primary-color;
|
// color: @primary-color;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-link &-link {
|
// &-link &-link {
|
||||||
padding-top: 5px;
|
// padding-top: 5px;
|
||||||
padding-bottom: 5px;
|
// padding-bottom: 5px;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
@import './rtl';
|
// @import './rtl';
|
||||||
|
@ -1,5 +1,124 @@
|
|||||||
import '../../style/index.less';
|
// deps-lint-skip-all
|
||||||
import './index.less';
|
import { CSSObject } from '@ant-design/cssinjs';
|
||||||
|
import { genComponentStyleHook, mergeToken, resetComponent } from '../../_util/theme';
|
||||||
|
import type { GenerateStyle, FullToken } from '../../_util/theme';
|
||||||
|
|
||||||
// style dependencies
|
export interface ComponentToken {}
|
||||||
import '../../affix/style';
|
interface AnchorToken extends FullToken<'Anchor'> {
|
||||||
|
anchorLinkTop: number;
|
||||||
|
anchorLinkLeft: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================== Shared ==============================
|
||||||
|
const genSharedAnchorStyle: GenerateStyle<AnchorToken> = (token): CSSObject => {
|
||||||
|
const { componentCls } = token;
|
||||||
|
|
||||||
|
return {
|
||||||
|
[`${componentCls}-wrapper`]: {
|
||||||
|
// FIX ME
|
||||||
|
marginBlockStart: -4,
|
||||||
|
// FIX ME
|
||||||
|
paddingBlockStart: 4,
|
||||||
|
|
||||||
|
// delete overflow: auto
|
||||||
|
// overflow: 'auto',
|
||||||
|
|
||||||
|
// @anchor-bg
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
|
||||||
|
[componentCls]: {
|
||||||
|
...resetComponent(token),
|
||||||
|
position: 'relative',
|
||||||
|
// FIX ME @anchor-border-width
|
||||||
|
paddingInlineStart: 2,
|
||||||
|
|
||||||
|
[`${componentCls}-ink`]: {
|
||||||
|
position: 'absolute',
|
||||||
|
// top: 0
|
||||||
|
insetBlockStart: 0,
|
||||||
|
// left: 0
|
||||||
|
insetInlineStart: 0,
|
||||||
|
height: '100%',
|
||||||
|
|
||||||
|
'&::before': {
|
||||||
|
position: 'relative',
|
||||||
|
display: 'block',
|
||||||
|
// FIX ME
|
||||||
|
width: 2,
|
||||||
|
height: '100%',
|
||||||
|
margin: '0 auto',
|
||||||
|
// FIX ME @border-color-split
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.06)',
|
||||||
|
content: '" "',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-ink-ball`]: {
|
||||||
|
position: 'absolute',
|
||||||
|
// left 50%
|
||||||
|
insetInlineStart: '50%',
|
||||||
|
display: 'none',
|
||||||
|
// FIX ME
|
||||||
|
width: 8,
|
||||||
|
// FIX ME
|
||||||
|
height: 8,
|
||||||
|
// FIX '@component-background'
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
border: `2px solid ${token.colorPrimary}`,
|
||||||
|
borderRadius: 8,
|
||||||
|
transform: 'translateX(-50%)',
|
||||||
|
transition: `top ${token.motionDurationSlow} ease-in-out`,
|
||||||
|
|
||||||
|
'&.visible': {
|
||||||
|
display: 'inline-block',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-link`]: {
|
||||||
|
// FIX ME @anchor-link-padding
|
||||||
|
paddingBlock: token.anchorLinkTop,
|
||||||
|
paddingInline: `${token.anchorLinkLeft}px 0`,
|
||||||
|
lineHeight: '1.143',
|
||||||
|
|
||||||
|
'&-title': {
|
||||||
|
position: 'relative',
|
||||||
|
display: 'block',
|
||||||
|
// FIX ME margin-bottom
|
||||||
|
marginBlockEnd: 6,
|
||||||
|
overflow: 'hidden',
|
||||||
|
color: token.colorText,
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
transition: `all ${token.motionDurationSlow}s`,
|
||||||
|
|
||||||
|
'&:only-child': {
|
||||||
|
marginBlockEnd: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`&-active > ${componentCls}-link-title`]: {
|
||||||
|
color: token.colorPrimary,
|
||||||
|
},
|
||||||
|
|
||||||
|
// link link
|
||||||
|
[`${componentCls}-link`]: {
|
||||||
|
paddingBlock: 5,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-fixed ${componentCls}-ink ${componentCls}-ink-ball`]: {
|
||||||
|
display: 'none',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================== Export ==============================
|
||||||
|
export default genComponentStyleHook('Anchor', token => {
|
||||||
|
const anchorToken = mergeToken<AnchorToken>(token, {
|
||||||
|
anchorLinkTop: 7,
|
||||||
|
anchorLinkLeft: 16,
|
||||||
|
});
|
||||||
|
return [genSharedAnchorStyle(anchorToken)];
|
||||||
|
});
|
||||||
|
@ -34,7 +34,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-select-dropdown-empty"
|
class="ant-select-dropdown ant-select-dropdown-empty"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -80,7 +80,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-select-dropdown-empty"
|
class="ant-select-dropdown ant-select-dropdown-empty"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -163,7 +163,7 @@ exports[`renders ./components/auto-complete/demo/certain-category.md extend cont
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown certain-category-search-dropdown"
|
class="ant-select-dropdown certain-category-search-dropdown"
|
||||||
style="opacity:0;pointer-events:none;width:500px"
|
style="opacity:0;width:500px"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -501,7 +501,7 @@ exports[`renders ./components/auto-complete/demo/custom.md extend context correc
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-select-dropdown-empty"
|
class="ant-select-dropdown ant-select-dropdown-empty"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -571,7 +571,7 @@ exports[`renders ./components/auto-complete/demo/form-debug.md extend context co
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-select-dropdown-empty"
|
class="ant-select-dropdown ant-select-dropdown-empty"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -640,7 +640,7 @@ exports[`renders ./components/auto-complete/demo/form-debug.md extend context co
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-tree-select-dropdown ant-select-dropdown-empty"
|
class="ant-select-dropdown ant-tree-select-dropdown ant-select-dropdown-empty"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -785,7 +785,7 @@ exports[`renders ./components/auto-complete/demo/form-debug.md extend context co
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-tree-select-dropdown ant-select-dropdown-empty"
|
class="ant-select-dropdown ant-tree-select-dropdown ant-select-dropdown-empty"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -898,7 +898,7 @@ exports[`renders ./components/auto-complete/demo/form-debug.md extend context co
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-select-dropdown-empty"
|
class="ant-select-dropdown ant-select-dropdown-empty"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -993,7 +993,7 @@ exports[`renders ./components/auto-complete/demo/form-debug.md extend context co
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-select-dropdown-empty"
|
class="ant-select-dropdown ant-select-dropdown-empty"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -1066,7 +1066,7 @@ exports[`renders ./components/auto-complete/demo/form-debug.md extend context co
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-tree-select-dropdown ant-select-dropdown-empty"
|
class="ant-select-dropdown ant-tree-select-dropdown ant-select-dropdown-empty"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -1206,7 +1206,7 @@ exports[`renders ./components/auto-complete/demo/form-debug.md extend context co
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-select-dropdown-empty"
|
class="ant-select-dropdown ant-select-dropdown-empty"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -1280,7 +1280,7 @@ exports[`renders ./components/auto-complete/demo/form-debug.md extend context co
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-tree-select-dropdown ant-select-dropdown-empty"
|
class="ant-select-dropdown ant-tree-select-dropdown ant-select-dropdown-empty"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -1429,7 +1429,7 @@ exports[`renders ./components/auto-complete/demo/form-debug.md extend context co
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-select-dropdown-empty"
|
class="ant-select-dropdown ant-select-dropdown-empty"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -1503,7 +1503,7 @@ exports[`renders ./components/auto-complete/demo/form-debug.md extend context co
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-tree-select-dropdown ant-select-dropdown-empty"
|
class="ant-select-dropdown ant-tree-select-dropdown ant-select-dropdown-empty"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -1652,7 +1652,7 @@ exports[`renders ./components/auto-complete/demo/form-debug.md extend context co
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-select-dropdown-empty"
|
class="ant-select-dropdown ant-select-dropdown-empty"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -1732,7 +1732,7 @@ exports[`renders ./components/auto-complete/demo/non-case-sensitive.md extend co
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown"
|
class="ant-select-dropdown"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -1862,7 +1862,7 @@ exports[`renders ./components/auto-complete/demo/options.md extend context corre
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-select-dropdown-empty"
|
class="ant-select-dropdown ant-select-dropdown-empty"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -1915,7 +1915,7 @@ exports[`renders ./components/auto-complete/demo/status.md extend context correc
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-select-dropdown-empty"
|
class="ant-select-dropdown ant-select-dropdown-empty"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -1961,7 +1961,7 @@ exports[`renders ./components/auto-complete/demo/status.md extend context correc
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-select-dropdown-empty"
|
class="ant-select-dropdown ant-select-dropdown-empty"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -2045,7 +2045,7 @@ exports[`renders ./components/auto-complete/demo/uncertain-category.md extend co
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-select-dropdown-empty"
|
class="ant-select-dropdown ant-select-dropdown-empty"
|
||||||
style="opacity:0;pointer-events:none;width:252px"
|
style="opacity:0;width:252px"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
|
@ -32,7 +32,7 @@ exports[`AutoComplete legacy dataSource should accept react element option 1`] =
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
|
class="ant-select-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
|
||||||
style="opacity: 0; pointer-events: none; min-width: 0; width: 0px;"
|
style="opacity: 0; min-width: 0; width: 0px;"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
|
@ -2,8 +2,7 @@ import React from 'react';
|
|||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import { act } from 'react-dom/test-utils';
|
import { act } from 'react-dom/test-utils';
|
||||||
import { mount } from 'enzyme';
|
import { mount } from 'enzyme';
|
||||||
import { render } from '@testing-library/react';
|
import { render, fireEvent } from '../../../tests/utils';
|
||||||
import '@testing-library/jest-dom';
|
|
||||||
import Avatar from '..';
|
import Avatar from '..';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import rtlTest from '../../../tests/shared/rtlTest';
|
import rtlTest from '../../../tests/shared/rtlTest';
|
||||||
@ -88,7 +87,7 @@ describe('Avatar Render', () => {
|
|||||||
// https://github.com/jsdom/jsdom/issues/1816
|
// https://github.com/jsdom/jsdom/issues/1816
|
||||||
wrapper.find('img').simulate('error');
|
wrapper.find('img').simulate('error');
|
||||||
|
|
||||||
expect(wrapper).toMatchSnapshot();
|
expect(wrapper.render()).toMatchSnapshot();
|
||||||
expect(div.querySelector('img').getAttribute('src')).toBe(LOAD_SUCCESS_SRC);
|
expect(div.querySelector('img').getAttribute('src')).toBe(LOAD_SUCCESS_SRC);
|
||||||
|
|
||||||
wrapper.detach();
|
wrapper.detach();
|
||||||
@ -106,7 +105,7 @@ describe('Avatar Render', () => {
|
|||||||
const wrapper = mount(<Avatar src={LOAD_FAILURE_SRC}>Fallback</Avatar>, { attachTo: div });
|
const wrapper = mount(<Avatar src={LOAD_FAILURE_SRC}>Fallback</Avatar>, { attachTo: div });
|
||||||
wrapper.find('img').simulate('error');
|
wrapper.find('img').simulate('error');
|
||||||
|
|
||||||
expect(wrapper).toMatchSnapshot();
|
expect(wrapper.render()).toMatchSnapshot();
|
||||||
expect(wrapper.find('.ant-avatar-string').length).toBe(1);
|
expect(wrapper.find('.ant-avatar-string').length).toBe(1);
|
||||||
// children should show, when image load error without onError return false
|
// children should show, when image load error without onError return false
|
||||||
expect(wrapper.find('.ant-avatar-string').prop('style')).not.toHaveProperty('opacity', 0);
|
expect(wrapper.find('.ant-avatar-string').prop('style')).not.toHaveProperty('opacity', 0);
|
||||||
@ -115,7 +114,7 @@ describe('Avatar Render', () => {
|
|||||||
wrapper.setProps({ src: LOAD_SUCCESS_SRC });
|
wrapper.setProps({ src: LOAD_SUCCESS_SRC });
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
|
|
||||||
expect(wrapper).toMatchSnapshot();
|
expect(wrapper.render()).toMatchSnapshot();
|
||||||
expect(wrapper.find('.ant-avatar-image').length).toBe(1);
|
expect(wrapper.find('.ant-avatar-image').length).toBe(1);
|
||||||
|
|
||||||
// cleanup
|
// cleanup
|
||||||
@ -124,8 +123,8 @@ describe('Avatar Render', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should calculate scale of avatar children correctly', () => {
|
it('should calculate scale of avatar children correctly', () => {
|
||||||
const wrapper = mount(<Avatar>Avatar</Avatar>);
|
const { container, rerender } = render(<Avatar>Avatar</Avatar>);
|
||||||
expect(wrapper.find('.ant-avatar-string')).toMatchSnapshot();
|
expect(container.querySelector('.ant-avatar-string')).toMatchSnapshot();
|
||||||
|
|
||||||
Object.defineProperty(HTMLElement.prototype, 'offsetWidth', {
|
Object.defineProperty(HTMLElement.prototype, 'offsetWidth', {
|
||||||
get() {
|
get() {
|
||||||
@ -135,13 +134,14 @@ describe('Avatar Render', () => {
|
|||||||
return 40;
|
return 40;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
wrapper.setProps({ children: 'xx' });
|
|
||||||
expect(wrapper.find('.ant-avatar-string')).toMatchSnapshot();
|
rerender(<Avatar>xx</Avatar>);
|
||||||
|
expect(container.querySelector('.ant-avatar-string')).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should calculate scale of avatar children correctly with gap', () => {
|
it('should calculate scale of avatar children correctly with gap', () => {
|
||||||
const wrapper = mount(<Avatar gap={2}>Avatar</Avatar>);
|
const wrapper = mount(<Avatar gap={2}>Avatar</Avatar>);
|
||||||
expect(wrapper.find('.ant-avatar-string')).toMatchSnapshot();
|
expect(wrapper.find('.ant-avatar-string').render()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should warning when pass a string as icon props', () => {
|
it('should warning when pass a string as icon props', () => {
|
||||||
@ -176,8 +176,8 @@ describe('Avatar Render', () => {
|
|||||||
|
|
||||||
it('support onMouseEnter', () => {
|
it('support onMouseEnter', () => {
|
||||||
const onMouseEnter = jest.fn();
|
const onMouseEnter = jest.fn();
|
||||||
const wrapper = mount(<Avatar onMouseEnter={onMouseEnter}>TestString</Avatar>);
|
const { container } = render(<Avatar onMouseEnter={onMouseEnter}>TestString</Avatar>);
|
||||||
wrapper.simulate('mouseenter');
|
fireEvent.mouseEnter(container.firstChild);
|
||||||
expect(onMouseEnter).toHaveBeenCalled();
|
expect(onMouseEnter).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -110,14 +110,8 @@ exports[`Avatar Render rtl render component should be rendered correctly in RTL
|
|||||||
|
|
||||||
exports[`Avatar Render should calculate scale of avatar children correctly 1`] = `
|
exports[`Avatar Render should calculate scale of avatar children correctly 1`] = `
|
||||||
<span
|
<span
|
||||||
className="ant-avatar-string"
|
class="ant-avatar-string"
|
||||||
style={
|
style="transform: scale(0.72) translateX(-50%);"
|
||||||
Object {
|
|
||||||
"WebkitTransform": "scale(0.72) translateX(-50%)",
|
|
||||||
"msTransform": "scale(0.72) translateX(-50%)",
|
|
||||||
"transform": "scale(0.72) translateX(-50%)",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
Avatar
|
Avatar
|
||||||
</span>
|
</span>
|
||||||
@ -125,14 +119,8 @@ exports[`Avatar Render should calculate scale of avatar children correctly 1`] =
|
|||||||
|
|
||||||
exports[`Avatar Render should calculate scale of avatar children correctly 2`] = `
|
exports[`Avatar Render should calculate scale of avatar children correctly 2`] = `
|
||||||
<span
|
<span
|
||||||
className="ant-avatar-string"
|
class="ant-avatar-string"
|
||||||
style={
|
style="transform: scale(0.72) translateX(-50%);"
|
||||||
Object {
|
|
||||||
"WebkitTransform": "scale(0.72) translateX(-50%)",
|
|
||||||
"msTransform": "scale(0.72) translateX(-50%)",
|
|
||||||
"transform": "scale(0.72) translateX(-50%)",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
xx
|
xx
|
||||||
</span>
|
</span>
|
||||||
@ -140,93 +128,44 @@ exports[`Avatar Render should calculate scale of avatar children correctly 2`] =
|
|||||||
|
|
||||||
exports[`Avatar Render should calculate scale of avatar children correctly with gap 1`] = `
|
exports[`Avatar Render should calculate scale of avatar children correctly with gap 1`] = `
|
||||||
<span
|
<span
|
||||||
className="ant-avatar-string"
|
class="ant-avatar-string"
|
||||||
style={
|
style="transform: scale(0.36) translateX(-50%);"
|
||||||
Object {
|
|
||||||
"WebkitTransform": "scale(0.36) translateX(-50%)",
|
|
||||||
"msTransform": "scale(0.36) translateX(-50%)",
|
|
||||||
"transform": "scale(0.36) translateX(-50%)",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
Avatar
|
Avatar
|
||||||
</span>
|
</span>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`Avatar Render should handle onError correctly 1`] = `
|
exports[`Avatar Render should handle onError correctly 1`] = `
|
||||||
<Foo>
|
<span
|
||||||
<Avatar
|
class="ant-avatar ant-avatar-circle ant-avatar-image"
|
||||||
onError={[Function]}
|
>
|
||||||
shape="circle"
|
<img
|
||||||
size="default"
|
|
||||||
src="https://joeschmoe.io/api/v1/random"
|
src="https://joeschmoe.io/api/v1/random"
|
||||||
>
|
/>
|
||||||
<span
|
</span>
|
||||||
className="ant-avatar ant-avatar-circle ant-avatar-image"
|
|
||||||
style={Object {}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
onError={[Function]}
|
|
||||||
src="https://joeschmoe.io/api/v1/random"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</Avatar>
|
|
||||||
</Foo>
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`Avatar Render should show image on success after a failure state 1`] = `
|
exports[`Avatar Render should show image on success after a failure state 1`] = `
|
||||||
<Avatar
|
<span
|
||||||
shape="circle"
|
class="ant-avatar ant-avatar-circle"
|
||||||
size="default"
|
|
||||||
src="http://error.url"
|
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className="ant-avatar ant-avatar-circle"
|
class="ant-avatar-string"
|
||||||
style={Object {}}
|
style="transform: scale(1) translateX(-50%);"
|
||||||
>
|
>
|
||||||
<ResizeObserver
|
Fallback
|
||||||
onResize={[Function]}
|
|
||||||
>
|
|
||||||
<SingleObserver
|
|
||||||
key="rc-observer-key-0"
|
|
||||||
onResize={[Function]}
|
|
||||||
>
|
|
||||||
<DomWrapper>
|
|
||||||
<span
|
|
||||||
className="ant-avatar-string"
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"WebkitTransform": "scale(1) translateX(-50%)",
|
|
||||||
"msTransform": "scale(1) translateX(-50%)",
|
|
||||||
"transform": "scale(1) translateX(-50%)",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
Fallback
|
|
||||||
</span>
|
|
||||||
</DomWrapper>
|
|
||||||
</SingleObserver>
|
|
||||||
</ResizeObserver>
|
|
||||||
</span>
|
</span>
|
||||||
</Avatar>
|
</span>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`Avatar Render should show image on success after a failure state 2`] = `
|
exports[`Avatar Render should show image on success after a failure state 2`] = `
|
||||||
<Avatar
|
<span
|
||||||
shape="circle"
|
class="ant-avatar ant-avatar-circle ant-avatar-image"
|
||||||
size="default"
|
|
||||||
src="https://joeschmoe.io/api/v1/random"
|
|
||||||
>
|
>
|
||||||
<span
|
<img
|
||||||
className="ant-avatar ant-avatar-circle ant-avatar-image"
|
src="https://joeschmoe.io/api/v1/random"
|
||||||
style={Object {}}
|
/>
|
||||||
>
|
</span>
|
||||||
<img
|
|
||||||
onError={[Function]}
|
|
||||||
src="https://joeschmoe.io/api/v1/random"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</Avatar>
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`Avatar Render support size is number 1`] = `
|
exports[`Avatar Render support size is number 1`] = `
|
||||||
|
@ -383,7 +383,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip"
|
class="ant-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -468,7 +468,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-popover ant-avatar-group-popover"
|
class="ant-popover ant-avatar-group-popover"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-popover-content"
|
class="ant-popover-content"
|
||||||
@ -514,7 +514,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip"
|
class="ant-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -604,7 +604,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-popover ant-avatar-group-popover"
|
class="ant-popover ant-avatar-group-popover"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-popover-content"
|
class="ant-popover-content"
|
||||||
@ -650,7 +650,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip"
|
class="ant-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -740,7 +740,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-popover ant-avatar-group-popover"
|
class="ant-popover ant-avatar-group-popover"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-popover-content"
|
class="ant-popover-content"
|
||||||
@ -786,7 +786,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip"
|
class="ant-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
|
@ -66,5 +66,5 @@ const Demo = () => (
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
export default () => <Demo />;
|
export default Demo;
|
||||||
```
|
```
|
||||||
|
@ -71,5 +71,5 @@ const App: React.FC = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default () => <App />;
|
export default App;
|
||||||
```
|
```
|
||||||
|
@ -11,6 +11,8 @@ import getScroll from '../_util/getScroll';
|
|||||||
import scrollTo from '../_util/scrollTo';
|
import scrollTo from '../_util/scrollTo';
|
||||||
import { cloneElement } from '../_util/reactNode';
|
import { cloneElement } from '../_util/reactNode';
|
||||||
|
|
||||||
|
import useStyle from './style';
|
||||||
|
|
||||||
export interface BackTopProps {
|
export interface BackTopProps {
|
||||||
visibilityHeight?: number;
|
visibilityHeight?: number;
|
||||||
onClick?: React.MouseEventHandler<HTMLElement>;
|
onClick?: React.MouseEventHandler<HTMLElement>;
|
||||||
@ -105,7 +107,10 @@ const BackTop: React.FC<BackTopProps> = props => {
|
|||||||
const { prefixCls: customizePrefixCls, className = '' } = props;
|
const { prefixCls: customizePrefixCls, className = '' } = props;
|
||||||
const prefixCls = getPrefixCls('back-top', customizePrefixCls);
|
const prefixCls = getPrefixCls('back-top', customizePrefixCls);
|
||||||
const rootPrefixCls = getPrefixCls();
|
const rootPrefixCls = getPrefixCls();
|
||||||
|
const [wrapSSR, hashId] = useStyle(prefixCls);
|
||||||
|
|
||||||
const classString = classNames(
|
const classString = classNames(
|
||||||
|
hashId,
|
||||||
prefixCls,
|
prefixCls,
|
||||||
{
|
{
|
||||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||||
@ -123,10 +128,10 @@ const BackTop: React.FC<BackTopProps> = props => {
|
|||||||
'visible',
|
'visible',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return (
|
return wrapSSR(
|
||||||
<div {...divProps} className={classString} onClick={scrollToTop} ref={ref}>
|
<div {...divProps} className={classString} onClick={scrollToTop} ref={ref}>
|
||||||
{renderChildren({ prefixCls, rootPrefixCls })}
|
{renderChildren({ prefixCls, rootPrefixCls })}
|
||||||
</div>
|
</div>,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,49 +1,49 @@
|
|||||||
@import '../../style/themes/index';
|
// @import '../../style/themes/index';
|
||||||
@import '../../style/mixins/index';
|
// @import '../../style/mixins/index';
|
||||||
|
|
||||||
@backtop-prefix-cls: ~'@{ant-prefix}-back-top';
|
// @backtop-prefix-cls: ~'@{ant-prefix}-back-top';
|
||||||
|
|
||||||
.@{backtop-prefix-cls} {
|
// .@{backtop-prefix-cls} {
|
||||||
.reset-component();
|
// .reset-component();
|
||||||
|
|
||||||
position: fixed;
|
// position: fixed;
|
||||||
right: 100px;
|
// right: 100px;
|
||||||
bottom: 50px;
|
// bottom: 50px;
|
||||||
z-index: @zindex-back-top;
|
// z-index: @zindex-back-top;
|
||||||
width: 40px;
|
// width: 40px;
|
||||||
height: 40px;
|
// height: 40px;
|
||||||
cursor: pointer;
|
// cursor: pointer;
|
||||||
|
|
||||||
&:empty {
|
// &:empty {
|
||||||
display: none;
|
// display: none;
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-rtl {
|
// &-rtl {
|
||||||
right: auto;
|
// right: auto;
|
||||||
left: 100px;
|
// left: 100px;
|
||||||
direction: rtl;
|
// direction: rtl;
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-content {
|
// &-content {
|
||||||
width: 40px;
|
// width: 40px;
|
||||||
height: 40px;
|
// height: 40px;
|
||||||
overflow: hidden;
|
// overflow: hidden;
|
||||||
color: @back-top-color;
|
// color: @back-top-color;
|
||||||
text-align: center;
|
// text-align: center;
|
||||||
background-color: @back-top-bg;
|
// background-color: @back-top-bg;
|
||||||
border-radius: 20px;
|
// border-radius: 20px;
|
||||||
transition: all 0.3s;
|
// transition: all 0.3s;
|
||||||
|
|
||||||
&:hover {
|
// &:hover {
|
||||||
background-color: @back-top-hover-bg;
|
// background-color: @back-top-hover-bg;
|
||||||
transition: all 0.3s;
|
// transition: all 0.3s;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-icon {
|
// &-icon {
|
||||||
font-size: 24px;
|
// font-size: 24px;
|
||||||
line-height: 40px;
|
// line-height: 40px;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
@import './responsive';
|
// @import './responsive';
|
||||||
|
@ -1,2 +1,108 @@
|
|||||||
import '../../style/index.less';
|
// deps-lint-skip-all
|
||||||
import './index.less';
|
import { CSSObject } from '@ant-design/cssinjs';
|
||||||
|
import {
|
||||||
|
resetComponent,
|
||||||
|
genComponentStyleHook,
|
||||||
|
GenerateStyle,
|
||||||
|
FullToken,
|
||||||
|
mergeToken,
|
||||||
|
} from '../../_util/theme';
|
||||||
|
|
||||||
|
/** Component only token. Which will handle additional calculation of alias token */
|
||||||
|
export interface ComponentToken {}
|
||||||
|
|
||||||
|
type BackTopToken = FullToken<'BackTop'> & {
|
||||||
|
backTopBackground: string;
|
||||||
|
backTopColor: string;
|
||||||
|
backTopHoverBackground: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================== Shared ==============================
|
||||||
|
const genSharedBackTopStyle: GenerateStyle<BackTopToken, CSSObject> = (token): CSSObject => {
|
||||||
|
const { componentCls } = token;
|
||||||
|
|
||||||
|
return {
|
||||||
|
[componentCls]: {
|
||||||
|
...resetComponent(token),
|
||||||
|
|
||||||
|
position: 'fixed',
|
||||||
|
// FIXME right
|
||||||
|
insetInlineEnd: 100,
|
||||||
|
// FIXME bottom
|
||||||
|
insetBlockEnd: 50,
|
||||||
|
// FIX ME @zindex-back-top
|
||||||
|
zIndex: token.zIndexPopup,
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
cursor: 'pointer',
|
||||||
|
|
||||||
|
'&:empty': {
|
||||||
|
display: 'none',
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-content`]: {
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
overflow: 'hidden',
|
||||||
|
// FIXME @back-top-color
|
||||||
|
color: token.backTopColor,
|
||||||
|
textAlign: 'center',
|
||||||
|
// FIXME @back-top-bg
|
||||||
|
backgroundColor: token.backTopBackground,
|
||||||
|
// FIXME
|
||||||
|
borderRadius: 20,
|
||||||
|
transition: `all ${token.motionDurationSlow}`,
|
||||||
|
|
||||||
|
'&:hover': {
|
||||||
|
// FIX ME @back-top-hover-bg
|
||||||
|
backgroundColor: token.backTopHoverBackground,
|
||||||
|
transition: `all ${token.motionDurationSlow}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// change to .backtop .backtop-icon
|
||||||
|
[`${componentCls}-icon`]: {
|
||||||
|
// FIXME
|
||||||
|
fontSize: 24,
|
||||||
|
// FIXME
|
||||||
|
lineHeight: '40px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const genMediaBackTopStyle: GenerateStyle<BackTopToken> = (token): CSSObject => {
|
||||||
|
const { componentCls } = token;
|
||||||
|
|
||||||
|
return {
|
||||||
|
[`@media (max-width: ${token.screenMD}px)`]: {
|
||||||
|
[componentCls]: {
|
||||||
|
marginInlineEnd: 60,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`@media (max-width: ${token.screenXS}px)`]: {
|
||||||
|
[componentCls]: {
|
||||||
|
marginInlineEnd: 20,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================== Export ==============================
|
||||||
|
export default genComponentStyleHook<'BackTop'>(
|
||||||
|
'BackTop',
|
||||||
|
|
||||||
|
token => {
|
||||||
|
const backTopBackground = 'rgb(16, 136, 233)';
|
||||||
|
const backTopColor = '#fff';
|
||||||
|
const backTopHoverBackground = '#000000d9';
|
||||||
|
|
||||||
|
const backTopToken = mergeToken<BackTopToken>(token, {
|
||||||
|
backTopBackground,
|
||||||
|
backTopColor,
|
||||||
|
backTopHoverBackground,
|
||||||
|
});
|
||||||
|
return [genSharedBackTopStyle(backTopToken), genMediaBackTopStyle(backTopToken)];
|
||||||
|
},
|
||||||
|
);
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
@media screen and (max-width: @screen-md) {
|
// @media screen and (max-width: @screen-md) {
|
||||||
.@{backtop-prefix-cls} {
|
// .@{backtop-prefix-cls} {
|
||||||
right: 60px;
|
// right: 60px;
|
||||||
|
|
||||||
&-rtl {
|
// &-rtl {
|
||||||
right: auto;
|
// right: auto;
|
||||||
left: 60px;
|
// left: 60px;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
@media screen and (max-width: @screen-xs) {
|
// @media screen and (max-width: @screen-xs) {
|
||||||
.@{backtop-prefix-cls} {
|
// .@{backtop-prefix-cls} {
|
||||||
right: 20px;
|
// right: 20px;
|
||||||
|
|
||||||
&-rtl {
|
// &-rtl {
|
||||||
right: auto;
|
// right: auto;
|
||||||
left: 20px;
|
// left: 20px;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { mount } from 'enzyme';
|
import { mount } from 'enzyme';
|
||||||
import { act } from 'react-dom/test-utils';
|
import { act } from 'react-dom/test-utils';
|
||||||
|
import { fireEvent, render } from '@testing-library/react';
|
||||||
import Badge from '../index';
|
import Badge from '../index';
|
||||||
import Tooltip from '../../tooltip';
|
import Tooltip from '../../tooltip';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
@ -54,14 +55,14 @@ describe('Badge', () => {
|
|||||||
// https://github.com/ant-design/ant-design/issues/10626
|
// https://github.com/ant-design/ant-design/issues/10626
|
||||||
it('should be composable with Tooltip', () => {
|
it('should be composable with Tooltip', () => {
|
||||||
const ref = React.createRef();
|
const ref = React.createRef();
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<Tooltip title="Fix the error" ref={ref}>
|
<Tooltip title="Fix the error" ref={ref}>
|
||||||
<Badge status="error" />
|
<Badge status="error" />
|
||||||
</Tooltip>,
|
</Tooltip>,
|
||||||
);
|
);
|
||||||
|
|
||||||
act(() => {
|
act(() => {
|
||||||
wrapper.find('Badge').simulate('mouseenter');
|
fireEvent.mouseEnter(container.querySelector('.ant-badge'));
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
});
|
});
|
||||||
expect(ref.current.props.visible).toBeTruthy();
|
expect(ref.current.props.visible).toBeTruthy();
|
||||||
|
@ -74,5 +74,5 @@ class Demo extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default () => <Demo />;
|
export default Demo;
|
||||||
```
|
```
|
||||||
|
@ -36,5 +36,5 @@ const Demo = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default () => <Demo />;
|
export default Demo;
|
||||||
```
|
```
|
||||||
|
@ -54,10 +54,7 @@ const antBadgeLoadingCircle = new Keyframes('antBadgeLoadingCircle', {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const genSharedBadgeStyle: GenerateStyle<BadgeToken> = (
|
const genSharedBadgeStyle: GenerateStyle<BadgeToken> = (token: BadgeToken): CSSObject => {
|
||||||
token: BadgeToken,
|
|
||||||
hashId: string,
|
|
||||||
): CSSObject => {
|
|
||||||
const { componentCls, iconCls, antCls } = token;
|
const { componentCls, iconCls, antCls } = token;
|
||||||
const numberPrefixCls = `${antCls}-scroll-number`;
|
const numberPrefixCls = `${antCls}-scroll-number`;
|
||||||
const ribbonPrefixCls = `${antCls}-ribbon`;
|
const ribbonPrefixCls = `${antCls}-ribbon`;
|
||||||
@ -147,9 +144,10 @@ const genSharedBadgeStyle: GenerateStyle<BadgeToken> = (
|
|||||||
transform: 'translate(50%, -50%)',
|
transform: 'translate(50%, -50%)',
|
||||||
transformOrigin: '100% 0%',
|
transformOrigin: '100% 0%',
|
||||||
[`${iconCls}-spin`]: {
|
[`${iconCls}-spin`]: {
|
||||||
animation: `${antBadgeLoadingCircle.getName(hashId)} ${
|
animationName: antBadgeLoadingCircle,
|
||||||
token.motionDurationFast
|
animationDuration: token.motionDurationFast,
|
||||||
} infinite linear`,
|
animationIterationCount: 'infinite',
|
||||||
|
animationTimingFunction: 'linear',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
[`&${componentCls}-status`]: {
|
[`&${componentCls}-status`]: {
|
||||||
@ -181,7 +179,10 @@ const genSharedBadgeStyle: GenerateStyle<BadgeToken> = (
|
|||||||
height: '100%',
|
height: '100%',
|
||||||
border: `1px solid ${token.colorPrimary}`,
|
border: `1px solid ${token.colorPrimary}`,
|
||||||
borderRadius: '50%',
|
borderRadius: '50%',
|
||||||
animation: `${antStatusProcessing.getName(hashId)} 1.2s infinite ease-in-out`, // FIXME: hard code, copied from old less file
|
animationName: antStatusProcessing,
|
||||||
|
animationDuration: '1.2s',
|
||||||
|
animationIterationCount: 'infinite',
|
||||||
|
animationTimingFunction: 'ease-in-out',
|
||||||
content: '""',
|
content: '""',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -204,28 +205,28 @@ const genSharedBadgeStyle: GenerateStyle<BadgeToken> = (
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
[`${componentCls}-zoom-appear, ${componentCls}-zoom-enter`]: {
|
[`${componentCls}-zoom-appear, ${componentCls}-zoom-enter`]: {
|
||||||
animation: `${antZoomBadgeIn.getName(hashId)} ${token.motionDurationSlow} ${
|
animationName: antZoomBadgeIn,
|
||||||
token.motionEaseOutBack
|
animationDuration: token.motionDurationSlow,
|
||||||
}`,
|
animationTimingFunction: token.motionEaseOutBack,
|
||||||
animationFillMode: 'both',
|
animationFillMode: 'both',
|
||||||
},
|
},
|
||||||
[`${componentCls}-zoom-leave`]: {
|
[`${componentCls}-zoom-leave`]: {
|
||||||
animation: `${antZoomBadgeOut.getName(hashId)} ${token.motionDurationSlow} ${
|
animationName: antZoomBadgeOut,
|
||||||
token.motionEaseOutBack
|
animationDuration: token.motionDurationSlow,
|
||||||
}`,
|
animationTimingFunction: token.motionEaseOutBack,
|
||||||
animationFillMode: 'both',
|
animationFillMode: 'both',
|
||||||
},
|
},
|
||||||
[`&${componentCls}-not-a-wrapper`]: {
|
[`&${componentCls}-not-a-wrapper`]: {
|
||||||
[`${componentCls}-zoom-appear, ${componentCls}-zoom-enter`]: {
|
[`${componentCls}-zoom-appear, ${componentCls}-zoom-enter`]: {
|
||||||
animation: `${antNoWrapperZoomBadgeIn.getName(hashId)} ${token.motionDurationSlow} ${
|
animationName: antNoWrapperZoomBadgeIn,
|
||||||
token.motionEaseOutBack
|
animationDuration: token.motionDurationSlow,
|
||||||
}`,
|
animationTimingFunction: token.motionEaseOutBack,
|
||||||
},
|
},
|
||||||
|
|
||||||
[`${componentCls}-zoom-leave`]: {
|
[`${componentCls}-zoom-leave`]: {
|
||||||
animation: `${antNoWrapperZoomBadgeOut.getName(hashId)} ${token.motionDurationSlow} ${
|
animationName: antNoWrapperZoomBadgeOut,
|
||||||
token.motionEaseOutBack
|
animationDuration: token.motionDurationSlow,
|
||||||
}`,
|
animationTimingFunction: token.motionEaseOutBack,
|
||||||
},
|
},
|
||||||
[`&:not(${componentCls}-status)`]: {
|
[`&:not(${componentCls}-status)`]: {
|
||||||
verticalAlign: 'middle',
|
verticalAlign: 'middle',
|
||||||
@ -296,7 +297,7 @@ const genSharedBadgeStyle: GenerateStyle<BadgeToken> = (
|
|||||||
...statusRibbonPreset,
|
...statusRibbonPreset,
|
||||||
[`&${ribbonPrefixCls}-placement-end`]: {
|
[`&${ribbonPrefixCls}-placement-end`]: {
|
||||||
insetInlineEnd: -1 * token.marginXS,
|
insetInlineEnd: -1 * token.marginXS,
|
||||||
borderBottomRightRadius: 0,
|
borderEndEndRadius: 0,
|
||||||
[`${ribbonPrefixCls}-corner`]: {
|
[`${ribbonPrefixCls}-corner`]: {
|
||||||
insetInlineEnd: 0,
|
insetInlineEnd: 0,
|
||||||
borderColor: 'currentcolor transparent transparent currentcolor',
|
borderColor: 'currentcolor transparent transparent currentcolor',
|
||||||
@ -304,24 +305,18 @@ const genSharedBadgeStyle: GenerateStyle<BadgeToken> = (
|
|||||||
},
|
},
|
||||||
[`&${ribbonPrefixCls}-placement-start`]: {
|
[`&${ribbonPrefixCls}-placement-start`]: {
|
||||||
insetInlineStart: -1 * token.marginXS,
|
insetInlineStart: -1 * token.marginXS,
|
||||||
borderBottomLeftRadius: 0,
|
borderEndStartRadius: 0,
|
||||||
[`${ribbonPrefixCls}-corner`]: {
|
[`${ribbonPrefixCls}-corner`]: {
|
||||||
insetInlineStart: 0,
|
insetInlineStart: 0,
|
||||||
borderColor: 'currentcolor currentcolor transparent transparent',
|
borderColor: 'currentcolor currentcolor transparent transparent',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
antStatusProcessing,
|
|
||||||
antZoomBadgeIn,
|
|
||||||
antZoomBadgeOut,
|
|
||||||
antNoWrapperZoomBadgeIn,
|
|
||||||
antNoWrapperZoomBadgeOut,
|
|
||||||
antBadgeLoadingCircle,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// ============================== Export ==============================
|
// ============================== Export ==============================
|
||||||
export default genComponentStyleHook('Badge', (token, { hashId }) => {
|
export default genComponentStyleHook('Badge', token => {
|
||||||
const badgeZIndex = 'auto';
|
const badgeZIndex = 'auto';
|
||||||
const badgeHeight = 20; // FIXME: hard code
|
const badgeHeight = 20; // FIXME: hard code
|
||||||
const badgeTextColor = token.colorBgComponent;
|
const badgeTextColor = token.colorBgComponent;
|
||||||
@ -346,5 +341,5 @@ export default genComponentStyleHook('Badge', (token, { hashId }) => {
|
|||||||
badgeStatusSize,
|
badgeStatusSize,
|
||||||
});
|
});
|
||||||
|
|
||||||
return [genSharedBadgeStyle(badgeToken, hashId), { display: 'none' }];
|
return [genSharedBadgeStyle(badgeToken), { display: 'none' }];
|
||||||
});
|
});
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import DownOutlined from '@ant-design/icons/DownOutlined';
|
import DownOutlined from '@ant-design/icons/DownOutlined';
|
||||||
|
|
||||||
import DropDown, { DropDownProps } from '../dropdown/dropdown';
|
import Dropdown, { DropdownProps } from '../dropdown/dropdown';
|
||||||
import { ConfigContext } from '../config-provider';
|
import { ConfigContext } from '../config-provider';
|
||||||
|
|
||||||
export interface BreadcrumbItemProps {
|
export interface BreadcrumbItemProps {
|
||||||
prefixCls?: string;
|
prefixCls?: string;
|
||||||
separator?: React.ReactNode;
|
separator?: React.ReactNode;
|
||||||
href?: string;
|
href?: string;
|
||||||
overlay?: DropDownProps['overlay'];
|
overlay?: DropdownProps['overlay'];
|
||||||
dropdownProps?: DropDownProps;
|
dropdownProps?: DropdownProps;
|
||||||
onClick?: React.MouseEventHandler<HTMLAnchorElement | HTMLSpanElement>;
|
onClick?: React.MouseEventHandler<HTMLAnchorElement | HTMLSpanElement>;
|
||||||
className?: string;
|
className?: string;
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
@ -27,16 +27,16 @@ const BreadcrumbItem: BreadcrumbItemInterface = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const { getPrefixCls } = React.useContext(ConfigContext);
|
const { getPrefixCls } = React.useContext(ConfigContext);
|
||||||
const prefixCls = getPrefixCls('breadcrumb', customizePrefixCls);
|
const prefixCls = getPrefixCls('breadcrumb', customizePrefixCls);
|
||||||
/** If overlay is have Wrap a DropDown */
|
/** If overlay is have Wrap a Dropdown */
|
||||||
const renderBreadcrumbNode = (breadcrumbItem: React.ReactNode) => {
|
const renderBreadcrumbNode = (breadcrumbItem: React.ReactNode) => {
|
||||||
if (overlay) {
|
if (overlay) {
|
||||||
return (
|
return (
|
||||||
<DropDown overlay={overlay} placement="bottomCenter" {...dropdownProps}>
|
<Dropdown overlay={overlay} placement="bottom" {...dropdownProps}>
|
||||||
<span className={`${prefixCls}-overlay-link`}>
|
<span className={`${prefixCls}-overlay-link`}>
|
||||||
{breadcrumbItem}
|
{breadcrumbItem}
|
||||||
<DownOutlined />
|
<DownOutlined />
|
||||||
</span>
|
</span>
|
||||||
</DropDown>
|
</Dropdown>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return breadcrumbItem;
|
return breadcrumbItem;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { mount } from 'enzyme';
|
import { mount } from 'enzyme';
|
||||||
import { render } from '@testing-library/react';
|
import { render } from '../../../tests/utils';
|
||||||
import '@testing-library/jest-dom';
|
|
||||||
import Breadcrumb from '../index';
|
import Breadcrumb from '../index';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import rtlTest from '../../../tests/shared/rtlTest';
|
import rtlTest from '../../../tests/shared/rtlTest';
|
||||||
@ -30,8 +29,7 @@ describe('Breadcrumb', () => {
|
|||||||
<MyCom />
|
<MyCom />
|
||||||
</Breadcrumb>,
|
</Breadcrumb>,
|
||||||
);
|
);
|
||||||
expect(errorSpy.mock.calls).toHaveLength(1);
|
expect(errorSpy).toHaveBeenCalledWith(
|
||||||
expect(errorSpy.mock.calls[0][0]).toMatch(
|
|
||||||
"Warning: [antd: Breadcrumb] Only accepts Breadcrumb.Item and Breadcrumb.Separator as it's children",
|
"Warning: [antd: Breadcrumb] Only accepts Breadcrumb.Item and Breadcrumb.Separator as it's children",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -134,10 +134,11 @@ exports[`renders ./components/breadcrumb/demo/overlay.md extend context correctl
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-dropdown"
|
class="ant-dropdown"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<ul
|
<ul
|
||||||
class="ant-dropdown-menu ant-dropdown-menu-root ant-dropdown-menu-vertical ant-dropdown-menu-light"
|
class="ant-dropdown-menu ant-dropdown-menu-root ant-dropdown-menu-vertical ant-dropdown-menu-light"
|
||||||
|
data-dropdown-inject="true"
|
||||||
data-menu-list="true"
|
data-menu-list="true"
|
||||||
role="menu"
|
role="menu"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
@ -162,7 +163,7 @@ exports[`renders ./components/breadcrumb/demo/overlay.md extend context correctl
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -201,7 +202,7 @@ exports[`renders ./components/breadcrumb/demo/overlay.md extend context correctl
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -240,7 +241,7 @@ exports[`renders ./components/breadcrumb/demo/overlay.md extend context correctl
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -267,7 +268,7 @@ exports[`renders ./components/breadcrumb/demo/overlay.md extend context correctl
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -289,7 +290,7 @@ exports[`renders ./components/breadcrumb/demo/overlay.md extend context correctl
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -311,7 +312,7 @@ exports[`renders ./components/breadcrumb/demo/overlay.md extend context correctl
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
|
@ -1,166 +1,72 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`react router react router 3 1`] = `
|
exports[`react router react router 3 1`] = `
|
||||||
<Breadcrumb
|
<nav
|
||||||
params={
|
class="ant-breadcrumb"
|
||||||
Object {
|
|
||||||
"id": 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
routes={
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"breadcrumbName": "Home",
|
|
||||||
"childRoutes": Array [
|
|
||||||
Object {
|
|
||||||
"breadcrumbName": "Application List",
|
|
||||||
"childRoutes": Array [
|
|
||||||
Object {
|
|
||||||
"breadcrumbName": "Application:id",
|
|
||||||
"childRoutes": Array [
|
|
||||||
Object {
|
|
||||||
"breadcrumbName": "Detail",
|
|
||||||
"name": "detail",
|
|
||||||
"path": "detail",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"name": "app",
|
|
||||||
"path": ":id",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"name": "apps",
|
|
||||||
"path": "apps",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"name": "home",
|
|
||||||
"path": "/",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"breadcrumbName": "Application List",
|
|
||||||
"childRoutes": Array [
|
|
||||||
Object {
|
|
||||||
"breadcrumbName": "Application:id",
|
|
||||||
"childRoutes": Array [
|
|
||||||
Object {
|
|
||||||
"breadcrumbName": "Detail",
|
|
||||||
"name": "detail",
|
|
||||||
"path": "detail",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"name": "app",
|
|
||||||
"path": ":id",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"name": "apps",
|
|
||||||
"path": "apps",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"breadcrumbName": "Application:id",
|
|
||||||
"childRoutes": Array [
|
|
||||||
Object {
|
|
||||||
"breadcrumbName": "Detail",
|
|
||||||
"name": "detail",
|
|
||||||
"path": "detail",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"name": "app",
|
|
||||||
"path": ":id",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"breadcrumbName": "Detail",
|
|
||||||
"name": "detail",
|
|
||||||
"path": "detail",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<nav
|
<ol>
|
||||||
className="ant-breadcrumb"
|
<li>
|
||||||
>
|
<span
|
||||||
<ol>
|
class="ant-breadcrumb-link"
|
||||||
<BreadcrumbItem
|
|
||||||
key="Home"
|
|
||||||
separator="/"
|
|
||||||
>
|
>
|
||||||
<li>
|
<a
|
||||||
<span
|
href="#/"
|
||||||
className="ant-breadcrumb-link"
|
>
|
||||||
>
|
Home
|
||||||
<a
|
</a>
|
||||||
href="#/"
|
</span>
|
||||||
>
|
<span
|
||||||
Home
|
class="ant-breadcrumb-separator"
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
className="ant-breadcrumb-separator"
|
|
||||||
>
|
|
||||||
/
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
</BreadcrumbItem>
|
|
||||||
<BreadcrumbItem
|
|
||||||
key="apps"
|
|
||||||
separator="/"
|
|
||||||
>
|
>
|
||||||
<li>
|
/
|
||||||
<span
|
</span>
|
||||||
className="ant-breadcrumb-link"
|
</li>
|
||||||
>
|
<li>
|
||||||
<a
|
<span
|
||||||
href="#/apps"
|
class="ant-breadcrumb-link"
|
||||||
>
|
|
||||||
Application List
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
className="ant-breadcrumb-separator"
|
|
||||||
>
|
|
||||||
/
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
</BreadcrumbItem>
|
|
||||||
<BreadcrumbItem
|
|
||||||
key="1"
|
|
||||||
separator="/"
|
|
||||||
>
|
>
|
||||||
<li>
|
<a
|
||||||
<span
|
href="#/apps"
|
||||||
className="ant-breadcrumb-link"
|
>
|
||||||
>
|
Application List
|
||||||
<a
|
</a>
|
||||||
href="#/apps/1"
|
</span>
|
||||||
>
|
<span
|
||||||
Application1
|
class="ant-breadcrumb-separator"
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
className="ant-breadcrumb-separator"
|
|
||||||
>
|
|
||||||
/
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
</BreadcrumbItem>
|
|
||||||
<BreadcrumbItem
|
|
||||||
key="detail"
|
|
||||||
separator="/"
|
|
||||||
>
|
>
|
||||||
<li>
|
/
|
||||||
<span
|
</span>
|
||||||
className="ant-breadcrumb-link"
|
</li>
|
||||||
>
|
<li>
|
||||||
<span>
|
<span
|
||||||
Detail
|
class="ant-breadcrumb-link"
|
||||||
</span>
|
>
|
||||||
</span>
|
<a
|
||||||
<span
|
href="#/apps/1"
|
||||||
className="ant-breadcrumb-separator"
|
>
|
||||||
>
|
Application1
|
||||||
/
|
</a>
|
||||||
</span>
|
</span>
|
||||||
</li>
|
<span
|
||||||
</BreadcrumbItem>
|
class="ant-breadcrumb-separator"
|
||||||
</ol>
|
>
|
||||||
</nav>
|
/
|
||||||
</Breadcrumb>
|
</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span
|
||||||
|
class="ant-breadcrumb-link"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
Detail
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="ant-breadcrumb-separator"
|
||||||
|
>
|
||||||
|
/
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
`;
|
`;
|
||||||
|
@ -144,6 +144,6 @@ describe('react router', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
const wrapper = mount(<Breadcrumb routes={routes} params={{ id: 1 }} />);
|
const wrapper = mount(<Breadcrumb routes={routes} params={{ id: 1 }} />);
|
||||||
expect(wrapper).toMatchSnapshot();
|
expect(wrapper.render()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -16,6 +16,9 @@
|
|||||||
ol {
|
ol {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
|
@ -397,7 +397,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip"
|
class="ant-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -480,7 +480,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip"
|
class="ant-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -556,7 +556,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip"
|
class="ant-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -631,7 +631,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip"
|
class="ant-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -732,7 +732,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip"
|
class="ant-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -815,7 +815,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip"
|
class="ant-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -891,7 +891,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip"
|
class="ant-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -966,7 +966,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip"
|
class="ant-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -1048,7 +1048,7 @@ Array [
|
|||||||
class="ant-btn-group ant-btn-group-sm"
|
class="ant-btn-group ant-btn-group-sm"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="ant-btn ant-btn-primary"
|
class="ant-btn ant-btn-primary ant-btn-sm"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
@ -1056,7 +1056,7 @@ Array [
|
|||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="ant-btn ant-btn-primary"
|
class="ant-btn ant-btn-primary ant-btn-sm"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
@ -1068,7 +1068,7 @@ Array [
|
|||||||
style="display:inline-block;cursor:not-allowed"
|
style="display:inline-block;cursor:not-allowed"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="ant-btn ant-btn-primary ant-btn-icon-only"
|
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-icon-only"
|
||||||
disabled=""
|
disabled=""
|
||||||
style="pointer-events:none"
|
style="pointer-events:none"
|
||||||
type="button"
|
type="button"
|
||||||
@ -1097,7 +1097,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip"
|
class="ant-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -1119,7 +1119,7 @@ Array [
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
class="ant-btn ant-btn-primary ant-btn-icon-only"
|
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-icon-only"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
@ -1145,7 +1145,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip"
|
class="ant-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -1223,7 +1223,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip"
|
class="ant-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -1271,7 +1271,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip"
|
class="ant-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -1300,7 +1300,7 @@ Array [
|
|||||||
class="ant-btn-group ant-btn-group-lg"
|
class="ant-btn-group ant-btn-group-lg"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="ant-btn ant-btn-primary"
|
class="ant-btn ant-btn-primary ant-btn-lg"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
@ -1308,7 +1308,7 @@ Array [
|
|||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="ant-btn ant-btn-primary"
|
class="ant-btn ant-btn-primary ant-btn-lg"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
@ -1320,7 +1320,7 @@ Array [
|
|||||||
style="display:inline-block;cursor:not-allowed"
|
style="display:inline-block;cursor:not-allowed"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="ant-btn ant-btn-primary ant-btn-icon-only"
|
class="ant-btn ant-btn-primary ant-btn-lg ant-btn-icon-only"
|
||||||
disabled=""
|
disabled=""
|
||||||
style="pointer-events:none"
|
style="pointer-events:none"
|
||||||
type="button"
|
type="button"
|
||||||
@ -1349,7 +1349,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip"
|
class="ant-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -1371,7 +1371,7 @@ Array [
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
class="ant-btn ant-btn-primary ant-btn-icon-only"
|
class="ant-btn ant-btn-primary ant-btn-lg ant-btn-icon-only"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
@ -1397,7 +1397,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip"
|
class="ant-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -1671,10 +1671,11 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-dropdown"
|
class="ant-dropdown"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<ul
|
<ul
|
||||||
class="ant-dropdown-menu ant-dropdown-menu-root ant-dropdown-menu-vertical ant-dropdown-menu-light"
|
class="ant-dropdown-menu ant-dropdown-menu-root ant-dropdown-menu-vertical ant-dropdown-menu-light"
|
||||||
|
data-dropdown-inject="true"
|
||||||
data-menu-list="true"
|
data-menu-list="true"
|
||||||
role="menu"
|
role="menu"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
@ -1693,7 +1694,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -1726,7 +1727,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -1759,7 +1760,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -1786,7 +1787,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -1808,7 +1809,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
@ -1830,7 +1831,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tooltip-content"
|
class="ant-tooltip-content"
|
||||||
|
@ -856,7 +856,7 @@ Array [
|
|||||||
class="ant-btn-group ant-btn-group-sm"
|
class="ant-btn-group ant-btn-group-sm"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="ant-btn ant-btn-primary"
|
class="ant-btn ant-btn-primary ant-btn-sm"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
@ -864,7 +864,7 @@ Array [
|
|||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="ant-btn ant-btn-primary"
|
class="ant-btn ant-btn-primary ant-btn-sm"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
@ -876,7 +876,7 @@ Array [
|
|||||||
style="display:inline-block;cursor:not-allowed"
|
style="display:inline-block;cursor:not-allowed"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="ant-btn ant-btn-primary ant-btn-icon-only"
|
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-icon-only"
|
||||||
disabled=""
|
disabled=""
|
||||||
style="pointer-events:none"
|
style="pointer-events:none"
|
||||||
type="button"
|
type="button"
|
||||||
@ -903,7 +903,7 @@ Array [
|
|||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
<button
|
<button
|
||||||
class="ant-btn ant-btn-primary ant-btn-icon-only"
|
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-icon-only"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
@ -1012,7 +1012,7 @@ Array [
|
|||||||
class="ant-btn-group ant-btn-group-lg"
|
class="ant-btn-group ant-btn-group-lg"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="ant-btn ant-btn-primary"
|
class="ant-btn ant-btn-primary ant-btn-lg"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
@ -1020,7 +1020,7 @@ Array [
|
|||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="ant-btn ant-btn-primary"
|
class="ant-btn ant-btn-primary ant-btn-lg"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
@ -1032,7 +1032,7 @@ Array [
|
|||||||
style="display:inline-block;cursor:not-allowed"
|
style="display:inline-block;cursor:not-allowed"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="ant-btn ant-btn-primary ant-btn-icon-only"
|
class="ant-btn ant-btn-primary ant-btn-lg ant-btn-icon-only"
|
||||||
disabled=""
|
disabled=""
|
||||||
style="pointer-events:none"
|
style="pointer-events:none"
|
||||||
type="button"
|
type="button"
|
||||||
@ -1059,7 +1059,7 @@ Array [
|
|||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
<button
|
<button
|
||||||
class="ant-btn ant-btn-primary ant-btn-icon-only"
|
class="ant-btn ant-btn-primary ant-btn-lg ant-btn-icon-only"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { mount } from 'enzyme';
|
import { mount } from 'enzyme';
|
||||||
import { render } from '@testing-library/react';
|
|
||||||
import '@testing-library/jest-dom';
|
|
||||||
import { act } from 'react-dom/test-utils';
|
import { act } from 'react-dom/test-utils';
|
||||||
import { SearchOutlined } from '@ant-design/icons';
|
import { SearchOutlined } from '@ant-design/icons';
|
||||||
import { resetWarned } from 'rc-util/lib/warning';
|
import { resetWarned } from 'rc-util/lib/warning';
|
||||||
@ -9,7 +7,7 @@ import Button from '..';
|
|||||||
import ConfigProvider from '../../config-provider';
|
import ConfigProvider from '../../config-provider';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import rtlTest from '../../../tests/shared/rtlTest';
|
import rtlTest from '../../../tests/shared/rtlTest';
|
||||||
import { sleep } from '../../../tests/utils';
|
import { sleep, render, fireEvent } from '../../../tests/utils';
|
||||||
import { SizeType } from '../../config-provider/SizeContext';
|
import { SizeType } from '../../config-provider/SizeContext';
|
||||||
|
|
||||||
describe('Button', () => {
|
describe('Button', () => {
|
||||||
@ -38,14 +36,13 @@ describe('Button', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('warns if size is wrong', () => {
|
it('warns if size is wrong', () => {
|
||||||
const mockWarn = jest.fn();
|
resetWarned();
|
||||||
jest.spyOn(console, 'warn').mockImplementation(mockWarn);
|
const mockWarn = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
const size = 'who am I' as any as SizeType;
|
const size = 'who am I' as any as SizeType;
|
||||||
mount(<Button.Group size={size} />);
|
render(<Button.Group size={size} />);
|
||||||
expect(mockWarn).toHaveBeenCalledTimes(1);
|
expect(mockWarn).toHaveBeenCalledWith('Warning: [antd: Button.Group] Invalid prop `size`.');
|
||||||
expect(mockWarn.mock.calls[0][0]).toMatchObject({
|
|
||||||
message: 'unreachable case: "who am I"',
|
mockWarn.mockRestore();
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders Chinese characters correctly', () => {
|
it('renders Chinese characters correctly', () => {
|
||||||
@ -86,22 +83,26 @@ describe('Button', () => {
|
|||||||
|
|
||||||
it('renders Chinese characters correctly in HOC', () => {
|
it('renders Chinese characters correctly in HOC', () => {
|
||||||
const Text = ({ children }: { children: React.ReactNode }) => <span>{children}</span>;
|
const Text = ({ children }: { children: React.ReactNode }) => <span>{children}</span>;
|
||||||
const wrapper = mount(
|
const { container, rerender } = render(
|
||||||
<Button>
|
<Button>
|
||||||
<Text>按钮</Text>
|
<Text>按钮</Text>
|
||||||
</Button>,
|
</Button>,
|
||||||
);
|
);
|
||||||
expect(wrapper.find('.ant-btn').hasClass('ant-btn-two-chinese-chars')).toBe(true);
|
expect(container.querySelector('.ant-btn')).toHaveClass('ant-btn-two-chinese-chars');
|
||||||
wrapper.setProps({
|
|
||||||
children: <Text>大按钮</Text>,
|
rerender(
|
||||||
});
|
<Button>
|
||||||
wrapper.update();
|
<Text>大按钮</Text>
|
||||||
expect(wrapper.find('.ant-btn').hasClass('ant-btn-two-chinese-chars')).toBe(false);
|
</Button>,
|
||||||
wrapper.setProps({
|
);
|
||||||
children: <Text>按钮</Text>,
|
expect(container.querySelector('.ant-btn')).not.toHaveClass('ant-btn-two-chinese-chars');
|
||||||
});
|
|
||||||
wrapper.update();
|
rerender(
|
||||||
expect(wrapper.find('.ant-btn').hasClass('ant-btn-two-chinese-chars')).toBe(true);
|
<Button>
|
||||||
|
<Text>按钮</Text>
|
||||||
|
</Button>,
|
||||||
|
);
|
||||||
|
expect(container.querySelector('.ant-btn')).toHaveClass('ant-btn-two-chinese-chars');
|
||||||
});
|
});
|
||||||
|
|
||||||
// https://github.com/ant-design/ant-design/issues/18118
|
// https://github.com/ant-design/ant-design/issues/18118
|
||||||
@ -124,7 +125,7 @@ describe('Button', () => {
|
|||||||
|
|
||||||
it('have static property for type detecting', () => {
|
it('have static property for type detecting', () => {
|
||||||
const wrapper = mount(<Button>Button Text</Button>);
|
const wrapper = mount(<Button>Button Text</Button>);
|
||||||
expect((wrapper.type() as any).__ANT_BUTTON).toBe(true);
|
expect((wrapper.find(Button).type() as any).__ANT_BUTTON).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should change loading state instantly by default', () => {
|
it('should change loading state instantly by default', () => {
|
||||||
@ -195,12 +196,12 @@ describe('Button', () => {
|
|||||||
|
|
||||||
it('should not clickable when button is loading', () => {
|
it('should not clickable when button is loading', () => {
|
||||||
const onClick = jest.fn();
|
const onClick = jest.fn();
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<Button loading onClick={onClick}>
|
<Button loading onClick={onClick}>
|
||||||
button
|
button
|
||||||
</Button>,
|
</Button>,
|
||||||
);
|
);
|
||||||
wrapper.simulate('click');
|
fireEvent.click(container.firstChild!);
|
||||||
expect(onClick).not.toHaveBeenCalledWith();
|
expect(onClick).not.toHaveBeenCalledWith();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -314,12 +315,12 @@ describe('Button', () => {
|
|||||||
|
|
||||||
it('should not redirect when button is disabled', () => {
|
it('should not redirect when button is disabled', () => {
|
||||||
const onClick = jest.fn();
|
const onClick = jest.fn();
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<Button href="https://ant.design" onClick={onClick} disabled>
|
<Button href="https://ant.design" onClick={onClick} disabled>
|
||||||
click me
|
click me
|
||||||
</Button>,
|
</Button>,
|
||||||
);
|
);
|
||||||
wrapper.simulate('click');
|
fireEvent.click(container.firstChild!);
|
||||||
expect(onClick).not.toHaveBeenCalled();
|
expect(onClick).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -210,28 +210,6 @@
|
|||||||
.@{btnClassName}-icon-only {
|
.@{btnClassName}-icon-only {
|
||||||
font-size: @font-size-base;
|
font-size: @font-size-base;
|
||||||
}
|
}
|
||||||
// size
|
|
||||||
&-lg > .@{btnClassName},
|
|
||||||
&-lg > span > .@{btnClassName} {
|
|
||||||
.button-size(@btn-height-lg; @btn-padding-horizontal-lg; @btn-font-size-lg; 0);
|
|
||||||
}
|
|
||||||
&-lg .@{btnClassName}.@{btnClassName}-icon-only {
|
|
||||||
.square(@btn-height-lg);
|
|
||||||
padding-right: 0;
|
|
||||||
padding-left: 0;
|
|
||||||
}
|
|
||||||
&-sm > .@{btnClassName},
|
|
||||||
&-sm > span > .@{btnClassName} {
|
|
||||||
.button-size(@btn-height-sm; @btn-padding-horizontal-sm; @font-size-base; 0);
|
|
||||||
> .@{iconfont-css-prefix} {
|
|
||||||
font-size: @font-size-base;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&-sm .@{btnClassName}.@{btnClassName}-icon-only {
|
|
||||||
.square(@btn-height-sm);
|
|
||||||
padding-right: 0;
|
|
||||||
padding-left: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Base styles of buttons
|
// Base styles of buttons
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { SizeType } from '../config-provider/SizeContext';
|
import { SizeType } from '../config-provider/SizeContext';
|
||||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
import { ConfigContext } from '../config-provider';
|
||||||
import UnreachableException from '../_util/unreachableException';
|
import devWarning from '../_util/devWarning';
|
||||||
|
import { useToken } from '../_util/theme';
|
||||||
|
|
||||||
export interface ButtonGroupProps {
|
export interface ButtonGroupProps {
|
||||||
size?: SizeType;
|
size?: SizeType;
|
||||||
@ -12,42 +13,49 @@ export interface ButtonGroupProps {
|
|||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ButtonGroup: React.FC<ButtonGroupProps> = props => (
|
export const GroupSizeContext = React.createContext<SizeType | undefined>(undefined);
|
||||||
<ConfigConsumer>
|
|
||||||
{({ getPrefixCls, direction }: ConfigConsumerProps) => {
|
|
||||||
const { prefixCls: customizePrefixCls, size, className, ...others } = props;
|
|
||||||
const prefixCls = getPrefixCls('btn-group', customizePrefixCls);
|
|
||||||
|
|
||||||
// large => lg
|
const ButtonGroup: React.FC<ButtonGroupProps> = props => {
|
||||||
// small => sm
|
const { getPrefixCls, direction } = React.useContext(ConfigContext);
|
||||||
let sizeCls = '';
|
|
||||||
switch (size) {
|
|
||||||
case 'large':
|
|
||||||
sizeCls = 'lg';
|
|
||||||
break;
|
|
||||||
case 'small':
|
|
||||||
sizeCls = 'sm';
|
|
||||||
break;
|
|
||||||
case 'middle':
|
|
||||||
case undefined:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.warn(new UnreachableException(size).error);
|
|
||||||
}
|
|
||||||
|
|
||||||
const classes = classNames(
|
const { prefixCls: customizePrefixCls, size, className, ...others } = props;
|
||||||
prefixCls,
|
const prefixCls = getPrefixCls('btn-group', customizePrefixCls);
|
||||||
{
|
|
||||||
[`${prefixCls}-${sizeCls}`]: sizeCls,
|
|
||||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
|
||||||
},
|
|
||||||
className,
|
|
||||||
);
|
|
||||||
|
|
||||||
return <div {...others} className={classes} />;
|
// Here we only need hashId
|
||||||
}}
|
const [, , hashId] = useToken();
|
||||||
</ConfigConsumer>
|
|
||||||
);
|
// large => lg
|
||||||
|
// small => sm
|
||||||
|
let sizeCls = '';
|
||||||
|
switch (size) {
|
||||||
|
case 'large':
|
||||||
|
sizeCls = 'lg';
|
||||||
|
break;
|
||||||
|
case 'small':
|
||||||
|
sizeCls = 'sm';
|
||||||
|
break;
|
||||||
|
case 'middle':
|
||||||
|
case undefined:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
devWarning(!size, 'Button.Group', 'Invalid prop `size`.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const classes = classNames(
|
||||||
|
prefixCls,
|
||||||
|
{
|
||||||
|
[`${prefixCls}-${sizeCls}`]: sizeCls,
|
||||||
|
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||||
|
},
|
||||||
|
className,
|
||||||
|
hashId,
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<GroupSizeContext.Provider value={size}>
|
||||||
|
<div {...others} className={classes} />
|
||||||
|
</GroupSizeContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default ButtonGroup;
|
export default ButtonGroup;
|
||||||
|
@ -3,7 +3,7 @@ import * as React from 'react';
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import omit from 'rc-util/lib/omit';
|
import omit from 'rc-util/lib/omit';
|
||||||
|
|
||||||
import Group from './button-group';
|
import Group, { GroupSizeContext } from './button-group';
|
||||||
import { ConfigContext } from '../config-provider';
|
import { ConfigContext } from '../config-provider';
|
||||||
import Wave from '../_util/wave';
|
import Wave from '../_util/wave';
|
||||||
import { tuple } from '../_util/type';
|
import { tuple } from '../_util/type';
|
||||||
@ -21,7 +21,7 @@ function isString(str: any) {
|
|||||||
return typeof str === 'string';
|
return typeof str === 'string';
|
||||||
}
|
}
|
||||||
|
|
||||||
function isUnborderedButtonType(type: ButtonType | undefined) {
|
function isUnBorderedButtonType(type: ButtonType | undefined) {
|
||||||
return type === 'text' || type === 'link';
|
return type === 'text' || type === 'link';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +97,11 @@ export function convertLegacyProps(type?: LegacyButtonType): ButtonProps {
|
|||||||
export interface BaseButtonProps {
|
export interface BaseButtonProps {
|
||||||
type?: ButtonType;
|
type?: ButtonType;
|
||||||
icon?: React.ReactNode;
|
icon?: React.ReactNode;
|
||||||
/** @default default */
|
/**
|
||||||
|
* Shape of Button
|
||||||
|
*
|
||||||
|
* @default default
|
||||||
|
*/
|
||||||
shape?: ButtonShape;
|
shape?: ButtonShape;
|
||||||
size?: SizeType;
|
size?: SizeType;
|
||||||
loading?: boolean | { delay?: number };
|
loading?: boolean | { delay?: number };
|
||||||
@ -161,12 +165,13 @@ const InternalButton: React.ForwardRefRenderFunction<unknown, ButtonProps> = (pr
|
|||||||
const [wrapSSR, hashId] = useStyle(prefixCls);
|
const [wrapSSR, hashId] = useStyle(prefixCls);
|
||||||
|
|
||||||
const size = React.useContext(SizeContext);
|
const size = React.useContext(SizeContext);
|
||||||
|
const groupSize = React.useContext(GroupSizeContext);
|
||||||
const [innerLoading, setLoading] = React.useState<Loading>(!!loading);
|
const [innerLoading, setLoading] = React.useState<Loading>(!!loading);
|
||||||
const [hasTwoCNChar, setHasTwoCNChar] = React.useState(false);
|
const [hasTwoCNChar, setHasTwoCNChar] = React.useState(false);
|
||||||
const buttonRef = (ref as any) || React.createRef<HTMLElement>();
|
const buttonRef = (ref as any) || React.createRef<HTMLElement>();
|
||||||
|
|
||||||
const isNeedInserted = () =>
|
const isNeedInserted = () =>
|
||||||
React.Children.count(children) === 1 && !icon && !isUnborderedButtonType(type);
|
React.Children.count(children) === 1 && !icon && !isUnBorderedButtonType(type);
|
||||||
|
|
||||||
const fixTwoCNChar = () => {
|
const fixTwoCNChar = () => {
|
||||||
// Fix for HOC usage like <FormatMessage />
|
// Fix for HOC usage like <FormatMessage />
|
||||||
@ -228,7 +233,7 @@ const InternalButton: React.ForwardRefRenderFunction<unknown, ButtonProps> = (pr
|
|||||||
);
|
);
|
||||||
|
|
||||||
devWarning(
|
devWarning(
|
||||||
!(ghost && isUnborderedButtonType(type)),
|
!(ghost && isUnBorderedButtonType(type)),
|
||||||
'Button',
|
'Button',
|
||||||
"`link` or `text` button can't be a `ghost` button.",
|
"`link` or `text` button can't be a `ghost` button.",
|
||||||
);
|
);
|
||||||
@ -236,7 +241,7 @@ const InternalButton: React.ForwardRefRenderFunction<unknown, ButtonProps> = (pr
|
|||||||
const autoInsertSpace = autoInsertSpaceInButton !== false;
|
const autoInsertSpace = autoInsertSpaceInButton !== false;
|
||||||
|
|
||||||
const sizeClassNameMap = { large: 'lg', small: 'sm', middle: undefined };
|
const sizeClassNameMap = { large: 'lg', small: 'sm', middle: undefined };
|
||||||
const sizeFullname = customizeSize || size;
|
const sizeFullname = groupSize || customizeSize || size;
|
||||||
const sizeCls = sizeFullname ? sizeClassNameMap[sizeFullname] || '' : '';
|
const sizeCls = sizeFullname ? sizeClassNameMap[sizeFullname] || '' : '';
|
||||||
|
|
||||||
const iconType = innerLoading ? 'loading' : icon;
|
const iconType = innerLoading ? 'loading' : icon;
|
||||||
@ -249,7 +254,7 @@ const InternalButton: React.ForwardRefRenderFunction<unknown, ButtonProps> = (pr
|
|||||||
[`${prefixCls}-${type}`]: type,
|
[`${prefixCls}-${type}`]: type,
|
||||||
[`${prefixCls}-${sizeCls}`]: sizeCls,
|
[`${prefixCls}-${sizeCls}`]: sizeCls,
|
||||||
[`${prefixCls}-icon-only`]: !children && children !== 0 && !!iconType,
|
[`${prefixCls}-icon-only`]: !children && children !== 0 && !!iconType,
|
||||||
[`${prefixCls}-background-ghost`]: ghost && !isUnborderedButtonType(type),
|
[`${prefixCls}-background-ghost`]: ghost && !isUnBorderedButtonType(type),
|
||||||
[`${prefixCls}-loading`]: innerLoading,
|
[`${prefixCls}-loading`]: innerLoading,
|
||||||
[`${prefixCls}-two-chinese-chars`]: hasTwoCNChar && autoInsertSpace,
|
[`${prefixCls}-two-chinese-chars`]: hasTwoCNChar && autoInsertSpace,
|
||||||
[`${prefixCls}-block`]: block,
|
[`${prefixCls}-block`]: block,
|
||||||
@ -294,7 +299,7 @@ const InternalButton: React.ForwardRefRenderFunction<unknown, ButtonProps> = (pr
|
|||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!isUnborderedButtonType(type)) {
|
if (!isUnBorderedButtonType(type)) {
|
||||||
buttonNode = <Wave disabled={!!innerLoading}>{buttonNode}</Wave>;
|
buttonNode = <Wave disabled={!!innerLoading}>{buttonNode}</Wave>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,9 +45,3 @@ export default () => (
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
```css
|
|
||||||
#components-button-demo-legacy-group .ant-btn {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
@ -81,5 +81,5 @@ class App extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default () => <App />;
|
export default App;
|
||||||
```
|
```
|
||||||
|
@ -57,18 +57,14 @@ Following the Ant Design specification, we will add one space between if Button
|
|||||||
<img src="https://gw.alipayobjects.com/zos/antfincdn/MY%26THAPZrW/38f06cb9-293a-4b42-b183-9f443e79ffea.png" style="box-shadow: none; margin: 0; width: 100px" alt="Button with two Chinese characters" />
|
<img src="https://gw.alipayobjects.com/zos/antfincdn/MY%26THAPZrW/38f06cb9-293a-4b42-b183-9f443e79ffea.png" style="box-shadow: none; margin: 0; width: 100px" alt="Button with two Chinese characters" />
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
[id^=components-button-demo-] .ant-btn {
|
[id^="components-button-demo-"]:not([id^="components-button-demo-legacy-group"]) .ant-btn {
|
||||||
margin-right: 8px;
|
margin-right: 8px;
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
[id^="components-button-demo-"] .ant-btn-rtl {
|
[id^="components-button-demo-"]:not([id^="components-button-demo-legacy-group"]) .ant-btn-rtl {
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
margin-left: 8px;
|
margin-left: 8px;
|
||||||
}
|
}
|
||||||
[id^=components-button-demo-] .ant-btn-group > .ant-btn,
|
|
||||||
[id^=components-button-demo-] .ant-btn-group > span > .ant-btn {
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
[data-theme="dark"] .site-button-ghost-wrapper {
|
[data-theme="dark"] .site-button-ghost-wrapper {
|
||||||
background: rgba(255, 255, 255, 0.2);
|
background: rgba(255, 255, 255, 0.2);
|
||||||
}
|
}
|
||||||
|
@ -62,17 +62,14 @@ cover: https://gw.alipayobjects.com/zos/alicdn/fNUKzY1sk/Button.svg
|
|||||||
<img src="https://gw.alipayobjects.com/zos/antfincdn/MY%26THAPZrW/38f06cb9-293a-4b42-b183-9f443e79ffea.png" style="box-shadow: none; margin: 0; width: 100px" alt="移除两个汉字之间的空格" />
|
<img src="https://gw.alipayobjects.com/zos/antfincdn/MY%26THAPZrW/38f06cb9-293a-4b42-b183-9f443e79ffea.png" style="box-shadow: none; margin: 0; width: 100px" alt="移除两个汉字之间的空格" />
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
[id^="components-button-demo-"] .ant-btn {
|
[id^="components-button-demo-"]:not([id^="components-button-demo-legacy-group"]) .ant-btn {
|
||||||
margin-right: 8px;
|
margin-right: 8px;
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
[id^="components-button-demo-"] .ant-btn-rtl {
|
[id^="components-button-demo-"]:not([id^="components-button-demo-legacy-group"]) .ant-btn-rtl {
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
margin-left: 8px;
|
margin-left: 8px;
|
||||||
}
|
}
|
||||||
[id^="components-button-demo-"] .ant-btn-group > .ant-btn {
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
[data-theme="dark"] .site-button-ghost-wrapper {
|
[data-theme="dark"] .site-button-ghost-wrapper {
|
||||||
background: rgba(255, 255, 255, 0.2);
|
background: rgba(255, 255, 255, 0.2);
|
||||||
}
|
}
|
||||||
|
81
components/button/style/group.tsx
Normal file
81
components/button/style/group.tsx
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
import type { GenerateStyle } from '../../_util/theme';
|
||||||
|
import type { ButtonToken } from '.';
|
||||||
|
|
||||||
|
const genButtonBorderStyle = (buttonTypeCls: string, borderColor: string) => ({
|
||||||
|
// Border
|
||||||
|
[`> span, > ${buttonTypeCls}`]: {
|
||||||
|
'&:not(:last-child)': {
|
||||||
|
[`&, & > ${buttonTypeCls}`]: {
|
||||||
|
'&:not(:disabled)': {
|
||||||
|
borderInlineEndColor: borderColor,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
'&:not(:first-child)': {
|
||||||
|
[`&, & > ${buttonTypeCls}`]: {
|
||||||
|
'&:not(:disabled)': {
|
||||||
|
borderInlineStartColor: borderColor,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const genGroupStyle: GenerateStyle<ButtonToken> = token => {
|
||||||
|
const { componentCls, fontSizeBase, controlLineWidth, colorPrimaryHover, colorErrorHover } =
|
||||||
|
token;
|
||||||
|
|
||||||
|
return {
|
||||||
|
[`${componentCls}-group`]: [
|
||||||
|
{
|
||||||
|
position: 'relative',
|
||||||
|
display: 'inline-flex',
|
||||||
|
|
||||||
|
// Border
|
||||||
|
[`> span, > ${componentCls}`]: {
|
||||||
|
'&:not(:last-child)': {
|
||||||
|
[`&, & > ${componentCls}`]: {
|
||||||
|
borderStartEndRadius: 0,
|
||||||
|
borderEndEndRadius: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
'&:not(:first-child)': {
|
||||||
|
marginInlineStart: -controlLineWidth,
|
||||||
|
|
||||||
|
[`&, & > ${componentCls}`]: {
|
||||||
|
borderStartStartRadius: 0,
|
||||||
|
borderEndStartRadius: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[componentCls]: {
|
||||||
|
position: 'relative',
|
||||||
|
zIndex: 1,
|
||||||
|
|
||||||
|
[`&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active`]: {
|
||||||
|
zIndex: 2,
|
||||||
|
},
|
||||||
|
|
||||||
|
'&[disabled]': {
|
||||||
|
zIndex: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-icon-only`]: {
|
||||||
|
fontSize: fontSizeBase,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Border Color
|
||||||
|
genButtonBorderStyle(`${componentCls}-primary`, colorPrimaryHover),
|
||||||
|
genButtonBorderStyle(`${componentCls}-danger`, colorErrorHover),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default genGroupStyle;
|
@ -3,6 +3,7 @@ import { CSSInterpolation, CSSObject } from '@ant-design/cssinjs';
|
|||||||
import { TinyColor } from '@ctrl/tinycolor';
|
import { TinyColor } from '@ctrl/tinycolor';
|
||||||
import { mergeToken, genComponentStyleHook } from '../../_util/theme';
|
import { mergeToken, genComponentStyleHook } from '../../_util/theme';
|
||||||
import type { GenerateStyle, FullToken } from '../../_util/theme';
|
import type { GenerateStyle, FullToken } from '../../_util/theme';
|
||||||
|
import genGroupStyle from './group';
|
||||||
|
|
||||||
/** Component only token. Which will handle additional calculation of alias token */
|
/** Component only token. Which will handle additional calculation of alias token */
|
||||||
export interface ComponentToken {
|
export interface ComponentToken {
|
||||||
@ -10,7 +11,7 @@ export interface ComponentToken {
|
|||||||
colorBgTextActive: string;
|
colorBgTextActive: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ButtonToken extends FullToken<'Button'> {}
|
export interface ButtonToken extends FullToken<'Button'> {}
|
||||||
|
|
||||||
// ============================== Shared ==============================
|
// ============================== Shared ==============================
|
||||||
const genSharedButtonStyle: GenerateStyle<ButtonToken, CSSObject> = (token): CSSObject => {
|
const genSharedButtonStyle: GenerateStyle<ButtonToken, CSSObject> = (token): CSSObject => {
|
||||||
@ -325,7 +326,7 @@ const genSizeButtonStyle = (token: ButtonToken, sizePrefixCls: string = ''): CSS
|
|||||||
|
|
||||||
// Loading
|
// Loading
|
||||||
[`&${componentCls}-loading`]: {
|
[`&${componentCls}-loading`]: {
|
||||||
opacity: 0.65,
|
opacity: token.colorLoadingOpacity,
|
||||||
cursor: 'default',
|
cursor: 'default',
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -383,6 +384,9 @@ export default genComponentStyleHook(
|
|||||||
|
|
||||||
// Group (type, ghost, danger, disabled, loading)
|
// Group (type, ghost, danger, disabled, loading)
|
||||||
genTypeButtonStyle(token),
|
genTypeButtonStyle(token),
|
||||||
|
|
||||||
|
// Button Group
|
||||||
|
genGroupStyle(token),
|
||||||
],
|
],
|
||||||
token => {
|
token => {
|
||||||
const { colorText } = token;
|
const { colorText } = token;
|
||||||
|
@ -42,7 +42,7 @@ exports[`renders ./components/calendar/demo/basic.md extend context correctly 1`
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown"
|
class="ant-select-dropdown"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -489,7 +489,7 @@ exports[`renders ./components/calendar/demo/basic.md extend context correctly 1`
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown"
|
class="ant-select-dropdown"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -1627,7 +1627,7 @@ exports[`renders ./components/calendar/demo/card.md extend context correctly 1`]
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown"
|
class="ant-select-dropdown"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -2074,7 +2074,7 @@ exports[`renders ./components/calendar/demo/card.md extend context correctly 1`]
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown"
|
class="ant-select-dropdown"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -3274,7 +3274,7 @@ exports[`renders ./components/calendar/demo/customize-header.md extend context c
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown"
|
class="ant-select-dropdown"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -3724,7 +3724,7 @@ exports[`renders ./components/calendar/demo/customize-header.md extend context c
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown"
|
class="ant-select-dropdown"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -4819,7 +4819,7 @@ exports[`renders ./components/calendar/demo/notice-calendar.md extend context co
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown"
|
class="ant-select-dropdown"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -5266,7 +5266,7 @@ exports[`renders ./components/calendar/demo/notice-calendar.md extend context co
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown"
|
class="ant-select-dropdown"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -6814,7 +6814,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown"
|
class="ant-select-dropdown"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -7261,7 +7261,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown"
|
class="ant-select-dropdown"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Dayjs from 'dayjs';
|
import Dayjs from 'dayjs';
|
||||||
|
import 'dayjs/locale/zh-cn';
|
||||||
import dayjsGenerateConfig from 'rc-picker/lib/generate/dayjs';
|
import dayjsGenerateConfig from 'rc-picker/lib/generate/dayjs';
|
||||||
import { mount } from 'enzyme';
|
import { mount } from 'enzyme';
|
||||||
import MockDate from 'mockdate';
|
import MockDate from 'mockdate';
|
||||||
@ -10,7 +11,7 @@ import Group from '../../radio/group';
|
|||||||
import Button from '../../radio/radioButton';
|
import Button from '../../radio/radioButton';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import rtlTest from '../../../tests/shared/rtlTest';
|
import rtlTest from '../../../tests/shared/rtlTest';
|
||||||
import 'dayjs/locale/zh-cn';
|
import { render, fireEvent } from '../../../tests/utils';
|
||||||
|
|
||||||
describe('Calendar', () => {
|
describe('Calendar', () => {
|
||||||
mountTest(Calendar);
|
mountTest(Calendar);
|
||||||
@ -41,14 +42,20 @@ describe('Calendar', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Calendar should be selectable', () => {
|
it('Calendar should be selectable', () => {
|
||||||
|
MockDate.set(Moment('2000-01-01').valueOf());
|
||||||
|
|
||||||
const onSelect = jest.fn();
|
const onSelect = jest.fn();
|
||||||
const onChange = jest.fn();
|
const onChange = jest.fn();
|
||||||
const wrapper = mount(<Calendar onSelect={onSelect} onChange={onChange} />);
|
const { container } = render(<Calendar onSelect={onSelect} onChange={onChange} />);
|
||||||
wrapper.find('.ant-picker-cell').at(0).simulate('click');
|
|
||||||
|
fireEvent.click(container.querySelector('.ant-picker-cell'));
|
||||||
expect(onSelect).toHaveBeenCalledWith(expect.anything());
|
expect(onSelect).toHaveBeenCalledWith(expect.anything());
|
||||||
|
|
||||||
const value = onSelect.mock.calls[0][0];
|
const value = onSelect.mock.calls[0][0];
|
||||||
expect(Dayjs.isDayjs(value)).toBe(true);
|
expect(Dayjs.isDayjs(value)).toBe(true);
|
||||||
expect(onChange).toHaveBeenCalled();
|
expect(onChange).toHaveBeenCalled();
|
||||||
|
|
||||||
|
MockDate.reset();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('only Valid range should be selectable', () => {
|
it('only Valid range should be selectable', () => {
|
||||||
|
@ -47,5 +47,5 @@ class App extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default () => <App />;
|
export default App;
|
||||||
```
|
```
|
||||||
|
@ -139,6 +139,8 @@ function generateCalendar<DateType>(generateConfig: GenerateConfig<DateType>) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const triggerChange = (date: DateType) => {
|
const triggerChange = (date: DateType) => {
|
||||||
|
console.log('trigger change!!!', isSameDate(date, mergedValue));
|
||||||
|
console.log('trigger change!!!', String(date), String(mergedValue));
|
||||||
setMergedValue(date);
|
setMergedValue(date);
|
||||||
|
|
||||||
if (!isSameDate(date, mergedValue)) {
|
if (!isSameDate(date, mergedValue)) {
|
||||||
|
@ -912,11 +912,12 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tabs-dropdown"
|
class="ant-tabs-dropdown"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<ul
|
<ul
|
||||||
aria-label="expanded dropdown"
|
aria-label="expanded dropdown"
|
||||||
class="ant-tabs-dropdown-menu ant-tabs-dropdown-menu-root ant-tabs-dropdown-menu-vertical"
|
class="ant-tabs-dropdown-menu ant-tabs-dropdown-menu-root ant-tabs-dropdown-menu-vertical"
|
||||||
|
data-dropdown-inject="true"
|
||||||
data-menu-list="true"
|
data-menu-list="true"
|
||||||
id="null-more-popup"
|
id="null-more-popup"
|
||||||
role="listbox"
|
role="listbox"
|
||||||
@ -1065,11 +1066,12 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tabs-dropdown"
|
class="ant-tabs-dropdown"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<ul
|
<ul
|
||||||
aria-label="expanded dropdown"
|
aria-label="expanded dropdown"
|
||||||
class="ant-tabs-dropdown-menu ant-tabs-dropdown-menu-root ant-tabs-dropdown-menu-vertical"
|
class="ant-tabs-dropdown-menu ant-tabs-dropdown-menu-root ant-tabs-dropdown-menu-vertical"
|
||||||
|
data-dropdown-inject="true"
|
||||||
data-menu-list="true"
|
data-menu-list="true"
|
||||||
id="null-more-popup"
|
id="null-more-popup"
|
||||||
role="listbox"
|
role="listbox"
|
||||||
|
@ -4,6 +4,7 @@ import Card from '../index';
|
|||||||
import Button from '../../button/index';
|
import Button from '../../button/index';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import rtlTest from '../../../tests/shared/rtlTest';
|
import rtlTest from '../../../tests/shared/rtlTest';
|
||||||
|
import { render } from '../../../tests/utils';
|
||||||
|
|
||||||
describe('Card', () => {
|
describe('Card', () => {
|
||||||
mountTest(Card);
|
mountTest(Card);
|
||||||
@ -84,20 +85,14 @@ describe('Card', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('get ref of card', () => {
|
it('get ref of card', () => {
|
||||||
class WrapperComponent extends React.Component {
|
const cardRef = React.createRef();
|
||||||
render() {
|
|
||||||
return (
|
render(
|
||||||
<Card
|
<Card ref={cardRef} title="Card title">
|
||||||
// eslint-disable-next-line react/no-string-refs
|
<p>Card content</p>
|
||||||
ref="firstRef"
|
</Card>,
|
||||||
title="Card title"
|
);
|
||||||
>
|
|
||||||
<p>Card content</p>
|
expect(cardRef.current).toHaveClass('ant-card');
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const wrapper = mount(<WrapperComponent />);
|
|
||||||
expect(wrapper.ref('firstRef').className.includes('ant-card')).toBe(true);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -64,5 +64,5 @@ class App extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default () => <App />;
|
export default App;
|
||||||
```
|
```
|
||||||
|
@ -8,6 +8,7 @@ import Row from '../row';
|
|||||||
import Col from '../col';
|
import Col from '../col';
|
||||||
import { ConfigContext } from '../config-provider';
|
import { ConfigContext } from '../config-provider';
|
||||||
import SizeContext from '../config-provider/SizeContext';
|
import SizeContext from '../config-provider/SizeContext';
|
||||||
|
import useStyle from './style';
|
||||||
|
|
||||||
function getAction(actions: React.ReactNode[]) {
|
function getAction(actions: React.ReactNode[]) {
|
||||||
const actionList = actions.map((action, index) => (
|
const actionList = actions.map((action, index) => (
|
||||||
@ -103,6 +104,7 @@ const Card = React.forwardRef((props: CardProps, ref: React.Ref<HTMLDivElement>)
|
|||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const prefixCls = getPrefixCls('card', customizePrefixCls);
|
const prefixCls = getPrefixCls('card', customizePrefixCls);
|
||||||
|
const [wrapSSR, hashId] = useStyle(prefixCls);
|
||||||
|
|
||||||
const loadingBlockStyle =
|
const loadingBlockStyle =
|
||||||
bodyStyle.padding === 0 || bodyStyle.padding === '0px' ? { padding: 24 } : undefined;
|
bodyStyle.padding === 0 || bodyStyle.padding === '0px' ? { padding: 24 } : undefined;
|
||||||
@ -193,15 +195,16 @@ const Card = React.forwardRef((props: CardProps, ref: React.Ref<HTMLDivElement>)
|
|||||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||||
},
|
},
|
||||||
className,
|
className,
|
||||||
|
hashId,
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return wrapSSR(
|
||||||
<div ref={ref} {...divProps} className={classString}>
|
<div ref={ref} {...divProps} className={classString}>
|
||||||
{head}
|
{head}
|
||||||
{coverDom}
|
{coverDom}
|
||||||
{body}
|
{body}
|
||||||
{actionDom}
|
{actionDom}
|
||||||
</div>
|
</div>,
|
||||||
);
|
);
|
||||||
}) as CardInterface;
|
}) as CardInterface;
|
||||||
|
|
||||||
|
@ -1,308 +1,308 @@
|
|||||||
@import '../../style/themes/index';
|
// @import '../../style/themes/index';
|
||||||
@import '../../style/mixins/index';
|
// @import '../../style/mixins/index';
|
||||||
|
|
||||||
@card-prefix-cls: ~'@{ant-prefix}-card';
|
// @card-prefix-cls: ~'@{ant-prefix}-card';
|
||||||
@card-hoverable-hover-border: transparent;
|
// @card-hoverable-hover-border: transparent;
|
||||||
@card-action-icon-size: 16px;
|
// @card-action-icon-size: 16px;
|
||||||
|
|
||||||
@gradient-min: fade(@card-skeleton-bg, 20%);
|
// @gradient-min: fade(@card-skeleton-bg, 20%);
|
||||||
@gradient-max: fade(@card-skeleton-bg, 40%);
|
// @gradient-max: fade(@card-skeleton-bg, 40%);
|
||||||
|
|
||||||
.@{card-prefix-cls} {
|
// .@{card-prefix-cls} {
|
||||||
.reset-component();
|
// .reset-component();
|
||||||
|
|
||||||
position: relative;
|
// position: relative;
|
||||||
background: @card-background;
|
// background: @card-background;
|
||||||
border-radius: @card-radius;
|
// border-radius: @card-radius;
|
||||||
|
|
||||||
&-rtl {
|
// &-rtl {
|
||||||
direction: rtl;
|
// direction: rtl;
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-hoverable {
|
// &-hoverable {
|
||||||
cursor: pointer;
|
// cursor: pointer;
|
||||||
transition: box-shadow 0.3s, border-color 0.3s;
|
// transition: box-shadow 0.3s, border-color 0.3s;
|
||||||
|
|
||||||
&:hover {
|
// &:hover {
|
||||||
border-color: @card-hoverable-hover-border;
|
// border-color: @card-hoverable-hover-border;
|
||||||
box-shadow: @card-shadow;
|
// box-shadow: @card-shadow;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-bordered {
|
// &-bordered {
|
||||||
border: @border-width-base @border-style-base @border-color-split;
|
// border: @border-width-base @border-style-base @border-color-split;
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-head {
|
// &-head {
|
||||||
min-height: @card-head-height;
|
// min-height: @card-head-height;
|
||||||
margin-bottom: -1px; // Fix card grid overflow bug: https://gw.alipayobjects.com/zos/rmsportal/XonYxBikwpgbqIQBeuhk.png
|
// margin-bottom: -1px; // Fix card grid overflow bug: https://gw.alipayobjects.com/zos/rmsportal/XonYxBikwpgbqIQBeuhk.png
|
||||||
padding: 0 @card-padding-base;
|
// padding: 0 @card-padding-base;
|
||||||
color: @card-head-color;
|
// color: @card-head-color;
|
||||||
font-weight: 500;
|
// font-weight: 500;
|
||||||
font-size: @card-head-font-size;
|
// font-size: @card-head-font-size;
|
||||||
background: @card-head-background;
|
// background: @card-head-background;
|
||||||
border-bottom: @border-width-base @border-style-base @border-color-split;
|
// border-bottom: @border-width-base @border-style-base @border-color-split;
|
||||||
border-radius: @card-radius @card-radius 0 0;
|
// border-radius: @card-radius @card-radius 0 0;
|
||||||
.clearfix();
|
// .clearfix();
|
||||||
|
|
||||||
&-wrapper {
|
// &-wrapper {
|
||||||
display: flex;
|
// display: flex;
|
||||||
align-items: center;
|
// align-items: center;
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-title {
|
// &-title {
|
||||||
display: inline-block;
|
// display: inline-block;
|
||||||
flex: 1;
|
// flex: 1;
|
||||||
padding: @card-head-padding 0;
|
// padding: @card-head-padding 0;
|
||||||
overflow: hidden;
|
// overflow: hidden;
|
||||||
white-space: nowrap;
|
// white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
// text-overflow: ellipsis;
|
||||||
|
|
||||||
> .@{ant-prefix}-typography,
|
// > .@{ant-prefix}-typography,
|
||||||
> .@{ant-prefix}-typography-edit-content {
|
// > .@{ant-prefix}-typography-edit-content {
|
||||||
left: 0;
|
// left: 0;
|
||||||
margin-top: 0;
|
// margin-top: 0;
|
||||||
margin-bottom: 0;
|
// margin-bottom: 0;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
.@{ant-prefix}-tabs-top {
|
// .@{ant-prefix}-tabs-top {
|
||||||
clear: both;
|
// clear: both;
|
||||||
margin-bottom: @card-head-tabs-margin-bottom;
|
// margin-bottom: @card-head-tabs-margin-bottom;
|
||||||
color: @text-color;
|
// color: @text-color;
|
||||||
font-weight: normal;
|
// font-weight: normal;
|
||||||
font-size: @font-size-base;
|
// font-size: @font-size-base;
|
||||||
|
|
||||||
&-bar {
|
// &-bar {
|
||||||
border-bottom: @border-width-base @border-style-base @border-color-split;
|
// border-bottom: @border-width-base @border-style-base @border-color-split;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-extra {
|
// &-extra {
|
||||||
float: right;
|
// float: right;
|
||||||
// https://stackoverflow.com/a/22429853/3040605
|
// // https://stackoverflow.com/a/22429853/3040605
|
||||||
margin-left: auto;
|
// margin-left: auto;
|
||||||
padding: @card-head-padding 0;
|
// padding: @card-head-padding 0;
|
||||||
color: @card-head-extra-color;
|
// color: @card-head-extra-color;
|
||||||
font-weight: normal;
|
// font-weight: normal;
|
||||||
font-size: @font-size-base;
|
// font-size: @font-size-base;
|
||||||
|
|
||||||
.@{card-prefix-cls}-rtl & {
|
// .@{card-prefix-cls}-rtl & {
|
||||||
margin-right: auto;
|
// margin-right: auto;
|
||||||
margin-left: 0;
|
// margin-left: 0;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-body {
|
// &-body {
|
||||||
padding: @card-padding-base;
|
// padding: @card-padding-base;
|
||||||
.clearfix();
|
// .clearfix();
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-contain-grid:not(&-loading) &-body {
|
// &-contain-grid:not(&-loading) &-body {
|
||||||
margin: -1px 0 0 -1px;
|
// margin: -1px 0 0 -1px;
|
||||||
padding: 0;
|
// padding: 0;
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-grid {
|
// &-grid {
|
||||||
float: left;
|
// float: left;
|
||||||
width: 33.33%;
|
// width: 33.33%;
|
||||||
padding: @card-padding-base;
|
// padding: @card-padding-base;
|
||||||
border: 0;
|
// border: 0;
|
||||||
border-radius: 0;
|
// border-radius: 0;
|
||||||
box-shadow: 1px 0 0 0 @border-color-split, 0 1px 0 0 @border-color-split,
|
// box-shadow: 1px 0 0 0 @border-color-split, 0 1px 0 0 @border-color-split,
|
||||||
1px 1px 0 0 @border-color-split, 1px 0 0 0 @border-color-split inset,
|
// 1px 1px 0 0 @border-color-split, 1px 0 0 0 @border-color-split inset,
|
||||||
0 1px 0 0 @border-color-split inset;
|
// 0 1px 0 0 @border-color-split inset;
|
||||||
transition: all 0.3s;
|
// transition: all 0.3s;
|
||||||
|
|
||||||
.@{card-prefix-cls}-rtl & {
|
// .@{card-prefix-cls}-rtl & {
|
||||||
float: right;
|
// float: right;
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-hoverable {
|
// &-hoverable {
|
||||||
&:hover {
|
// &:hover {
|
||||||
position: relative;
|
// position: relative;
|
||||||
z-index: 1;
|
// z-index: 1;
|
||||||
box-shadow: @card-shadow;
|
// box-shadow: @card-shadow;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-contain-tabs > &-head &-head-title {
|
// &-contain-tabs > &-head &-head-title {
|
||||||
min-height: @card-head-height - @card-head-padding;
|
// min-height: @card-head-height - @card-head-padding;
|
||||||
padding-bottom: 0;
|
// padding-bottom: 0;
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-contain-tabs > &-head &-extra {
|
// &-contain-tabs > &-head &-extra {
|
||||||
padding-bottom: 0;
|
// padding-bottom: 0;
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-bordered &-cover {
|
// &-bordered &-cover {
|
||||||
margin-top: -1px;
|
// margin-top: -1px;
|
||||||
margin-right: -1px;
|
// margin-right: -1px;
|
||||||
margin-left: -1px;
|
// margin-left: -1px;
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-cover {
|
// &-cover {
|
||||||
> * {
|
// > * {
|
||||||
display: block;
|
// display: block;
|
||||||
width: 100%;
|
// width: 100%;
|
||||||
}
|
// }
|
||||||
|
|
||||||
img {
|
// img {
|
||||||
border-radius: @card-radius @card-radius 0 0;
|
// border-radius: @card-radius @card-radius 0 0;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-actions {
|
// &-actions {
|
||||||
margin: 0;
|
// margin: 0;
|
||||||
padding: 0;
|
// padding: 0;
|
||||||
list-style: none;
|
// list-style: none;
|
||||||
background: @card-actions-background;
|
// background: @card-actions-background;
|
||||||
border-top: @border-width-base @border-style-base @border-color-split;
|
// border-top: @border-width-base @border-style-base @border-color-split;
|
||||||
.clearfix();
|
// .clearfix();
|
||||||
|
|
||||||
& > li {
|
// & > li {
|
||||||
float: left;
|
// float: left;
|
||||||
margin: @card-actions-li-margin;
|
// margin: @card-actions-li-margin;
|
||||||
color: @text-color-secondary;
|
// color: @text-color-secondary;
|
||||||
text-align: center;
|
// text-align: center;
|
||||||
|
|
||||||
.@{card-prefix-cls}-rtl & {
|
// .@{card-prefix-cls}-rtl & {
|
||||||
float: right;
|
// float: right;
|
||||||
}
|
// }
|
||||||
|
|
||||||
> span {
|
// > span {
|
||||||
position: relative;
|
// position: relative;
|
||||||
display: block;
|
// display: block;
|
||||||
min-width: 32px;
|
// min-width: 32px;
|
||||||
font-size: @font-size-base;
|
// font-size: @font-size-base;
|
||||||
line-height: @line-height-base;
|
// line-height: @line-height-base;
|
||||||
cursor: pointer;
|
// cursor: pointer;
|
||||||
|
|
||||||
&:hover {
|
// &:hover {
|
||||||
color: @primary-color;
|
// color: @primary-color;
|
||||||
transition: color 0.3s;
|
// transition: color 0.3s;
|
||||||
}
|
// }
|
||||||
|
|
||||||
a:not(.@{ant-prefix}-btn),
|
// a:not(.@{ant-prefix}-btn),
|
||||||
> .@{iconfont-css-prefix} {
|
// > .@{iconfont-css-prefix} {
|
||||||
display: inline-block;
|
// display: inline-block;
|
||||||
width: 100%;
|
// width: 100%;
|
||||||
color: @text-color-secondary;
|
// color: @text-color-secondary;
|
||||||
line-height: 22px;
|
// line-height: 22px;
|
||||||
transition: color 0.3s;
|
// transition: color 0.3s;
|
||||||
|
|
||||||
&:hover {
|
// &:hover {
|
||||||
color: @primary-color;
|
// color: @primary-color;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
> .@{iconfont-css-prefix} {
|
// > .@{iconfont-css-prefix} {
|
||||||
font-size: @card-action-icon-size;
|
// font-size: @card-action-icon-size;
|
||||||
line-height: 22px;
|
// line-height: 22px;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
&:not(:last-child) {
|
// &:not(:last-child) {
|
||||||
border-right: @border-width-base @border-style-base @border-color-split;
|
// border-right: @border-width-base @border-style-base @border-color-split;
|
||||||
|
|
||||||
.@{card-prefix-cls}-rtl & {
|
// .@{card-prefix-cls}-rtl & {
|
||||||
border-right: none;
|
// border-right: none;
|
||||||
border-left: @border-width-base @border-style-base @border-color-split;
|
// border-left: @border-width-base @border-style-base @border-color-split;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-type-inner &-head {
|
// &-type-inner &-head {
|
||||||
padding: 0 @card-padding-base;
|
// padding: 0 @card-padding-base;
|
||||||
background: @background-color-light;
|
// background: @background-color-light;
|
||||||
|
|
||||||
&-title {
|
// &-title {
|
||||||
padding: @card-inner-head-padding 0;
|
// padding: @card-inner-head-padding 0;
|
||||||
font-size: @font-size-base;
|
// font-size: @font-size-base;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-type-inner &-body {
|
// &-type-inner &-body {
|
||||||
padding: 16px @card-padding-base;
|
// padding: 16px @card-padding-base;
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-type-inner &-extra {
|
// &-type-inner &-extra {
|
||||||
padding: @card-inner-head-padding + 1.5px 0;
|
// padding: @card-inner-head-padding + 1.5px 0;
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-meta {
|
// &-meta {
|
||||||
margin: -4px 0;
|
// margin: -4px 0;
|
||||||
.clearfix();
|
// .clearfix();
|
||||||
|
|
||||||
&-avatar {
|
// &-avatar {
|
||||||
float: left;
|
// float: left;
|
||||||
padding-right: 16px;
|
// padding-right: 16px;
|
||||||
|
|
||||||
.@{card-prefix-cls}-rtl & {
|
// .@{card-prefix-cls}-rtl & {
|
||||||
float: right;
|
// float: right;
|
||||||
padding-right: 0;
|
// padding-right: 0;
|
||||||
padding-left: 16px;
|
// padding-left: 16px;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-detail {
|
// &-detail {
|
||||||
overflow: hidden;
|
// overflow: hidden;
|
||||||
|
|
||||||
> div:not(:last-child) {
|
// > div:not(:last-child) {
|
||||||
margin-bottom: @margin-xs;
|
// margin-bottom: @margin-xs;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-title {
|
// &-title {
|
||||||
overflow: hidden;
|
// overflow: hidden;
|
||||||
color: @card-head-color;
|
// color: @card-head-color;
|
||||||
font-weight: 500;
|
// font-weight: 500;
|
||||||
font-size: @font-size-lg;
|
// font-size: @font-size-lg;
|
||||||
white-space: nowrap;
|
// white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
// text-overflow: ellipsis;
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-description {
|
// &-description {
|
||||||
color: @text-color-secondary;
|
// color: @text-color-secondary;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-loading {
|
// &-loading {
|
||||||
overflow: hidden;
|
// overflow: hidden;
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-loading &-body {
|
// &-loading &-body {
|
||||||
user-select: none;
|
// user-select: none;
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-loading-content {
|
// &-loading-content {
|
||||||
p {
|
// p {
|
||||||
margin: 0;
|
// margin: 0;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-loading-block {
|
// &-loading-block {
|
||||||
height: 14px;
|
// height: 14px;
|
||||||
margin: 4px 0;
|
// margin: 4px 0;
|
||||||
background: linear-gradient(90deg, @gradient-min, @gradient-max, @gradient-min);
|
// background: linear-gradient(90deg, @gradient-min, @gradient-max, @gradient-min);
|
||||||
background-size: 600% 600%;
|
// background-size: 600% 600%;
|
||||||
border-radius: @card-radius;
|
// border-radius: @card-radius;
|
||||||
animation: card-loading 1.4s ease infinite;
|
// animation: card-loading 1.4s ease infinite;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
@keyframes card-loading {
|
// @keyframes card-loading {
|
||||||
0%,
|
// 0%,
|
||||||
100% {
|
// 100% {
|
||||||
background-position: 0 50%;
|
// background-position: 0 50%;
|
||||||
}
|
// }
|
||||||
|
|
||||||
50% {
|
// 50% {
|
||||||
background-position: 100% 50%;
|
// background-position: 100% 50%;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
@import './size';
|
// @import './size';
|
||||||
|
@ -1,7 +1,460 @@
|
|||||||
import '../../style/index.less';
|
// import '../../style/index.less';
|
||||||
import './index.less';
|
// import './index.less';
|
||||||
|
|
||||||
// style dependencies
|
// style dependencies
|
||||||
import '../../tabs/style';
|
// import '../../tabs/style';
|
||||||
import '../../row/style';
|
// import '../../row/style';
|
||||||
import '../../col/style';
|
// import '../../col/style';
|
||||||
|
|
||||||
|
// deps-lint-skip-all
|
||||||
|
import { CSSObject, Keyframes } from '@ant-design/cssinjs';
|
||||||
|
import { TinyColor } from '@ctrl/tinycolor';
|
||||||
|
|
||||||
|
import {
|
||||||
|
resetComponent,
|
||||||
|
GenerateStyle,
|
||||||
|
genComponentStyleHook,
|
||||||
|
FullToken,
|
||||||
|
mergeToken,
|
||||||
|
clearFix,
|
||||||
|
} from '../../_util/theme';
|
||||||
|
|
||||||
|
interface CardToken extends FullToken<'Card'> {
|
||||||
|
rootPrefixCls: string;
|
||||||
|
cardHoverableHoverBorder: string;
|
||||||
|
cardShadow: string;
|
||||||
|
cardHeadHeight: number;
|
||||||
|
cardHeadHeightSM: number;
|
||||||
|
cardHeadPadding: number;
|
||||||
|
cardPaddingBase: number;
|
||||||
|
cardHeadTabsMarginBottom: number;
|
||||||
|
cardInnerHeadPadding: number;
|
||||||
|
cardActionsLiMargin: string;
|
||||||
|
cardActionsIconSize: number;
|
||||||
|
cardSkeletonBg: string;
|
||||||
|
borderColorSplit: string;
|
||||||
|
backgroundColorLight: string;
|
||||||
|
gradientMin: string;
|
||||||
|
gradientMax: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================== Motion ==============================
|
||||||
|
const antCardLoading = new Keyframes('antCardLoading', {
|
||||||
|
'0%, 100%': {
|
||||||
|
backgroundPosition: '0 50%',
|
||||||
|
},
|
||||||
|
|
||||||
|
'50%': {
|
||||||
|
backgroundPosition: '100% 50%',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// ============================== Styles ==============================
|
||||||
|
|
||||||
|
// ============================== Head ==============================
|
||||||
|
const genCardHeadStyle: GenerateStyle<CardToken> = (token): CSSObject => {
|
||||||
|
const {
|
||||||
|
rootPrefixCls,
|
||||||
|
componentCls,
|
||||||
|
cardHoverableHoverBorder,
|
||||||
|
cardHeadHeight,
|
||||||
|
cardHeadPadding,
|
||||||
|
cardPaddingBase,
|
||||||
|
cardHeadTabsMarginBottom,
|
||||||
|
borderColorSplit,
|
||||||
|
} = token;
|
||||||
|
|
||||||
|
return {
|
||||||
|
minHeight: cardHeadHeight,
|
||||||
|
marginBottom: -1, // Fix card grid overflow bug: https://gw.alipayobjects.com/zos/rmsportal/XonYxBikwpgbqIQBeuhk.png
|
||||||
|
padding: `0 ${cardPaddingBase}px`,
|
||||||
|
color: token.colorTextHeading,
|
||||||
|
fontWeight: 500, // FIXME: hardcode in v4
|
||||||
|
fontSize: token.fontSizeLG,
|
||||||
|
background: cardHoverableHoverBorder,
|
||||||
|
borderBottom: `${token.controlLineWidth}px ${token.controlLineType} ${borderColorSplit}`,
|
||||||
|
borderRadius: `${token.radiusBase}px ${token.radiusBase}px 0 0`,
|
||||||
|
|
||||||
|
...clearFix(),
|
||||||
|
|
||||||
|
'&-wrapper': {
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
|
||||||
|
'&-title': {
|
||||||
|
display: 'inline-block',
|
||||||
|
flex: 1,
|
||||||
|
padding: `${cardHeadPadding}px 0`,
|
||||||
|
overflow: 'hidden',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
|
||||||
|
[`
|
||||||
|
> ${componentCls}-typography,
|
||||||
|
> ${componentCls}-typography-edit-content
|
||||||
|
`]: {
|
||||||
|
insetInlineStart: 0,
|
||||||
|
marginTop: 0,
|
||||||
|
marginBottom: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`.${rootPrefixCls}-tabs-top`]: {
|
||||||
|
clear: 'both',
|
||||||
|
marginBottom: cardHeadTabsMarginBottom,
|
||||||
|
color: token.colorText,
|
||||||
|
fontWeight: 'normal',
|
||||||
|
fontSize: token.fontSizeBase,
|
||||||
|
|
||||||
|
'&-bar': {
|
||||||
|
borderBottom: `${token.controlLineWidth}px ${token.controlLineType} ${borderColorSplit}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================== Grid ==============================
|
||||||
|
const genCardGridStyle: GenerateStyle<CardToken> = (token): CSSObject => {
|
||||||
|
const { cardPaddingBase, borderColorSplit, cardShadow } = token;
|
||||||
|
return {
|
||||||
|
width: '33.33%', // FIXME: hardcode in v4
|
||||||
|
padding: cardPaddingBase,
|
||||||
|
border: 0,
|
||||||
|
borderRadius: 0,
|
||||||
|
boxShadow: `
|
||||||
|
1px 0 0 0 ${borderColorSplit},
|
||||||
|
0 1px 0 0 ${borderColorSplit},
|
||||||
|
1px 1px 0 0 ${borderColorSplit},
|
||||||
|
1px 0 0 0 ${borderColorSplit} inset,
|
||||||
|
0 1px 0 0 ${borderColorSplit} inset;
|
||||||
|
transition: all ${token.motionDurationSlow}
|
||||||
|
`, // FIXME: hardcode in v4
|
||||||
|
|
||||||
|
'&-hoverable:hover': {
|
||||||
|
position: 'relative',
|
||||||
|
zIndex: 1,
|
||||||
|
boxShadow: cardShadow,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================== Actions ==============================
|
||||||
|
const genCardActionsStyle: GenerateStyle<CardToken> = (token): CSSObject => {
|
||||||
|
const { componentCls, iconCls, cardActionsLiMargin, cardActionsIconSize, borderColorSplit } =
|
||||||
|
token;
|
||||||
|
return {
|
||||||
|
margin: 0,
|
||||||
|
padding: 0,
|
||||||
|
listStyle: 'none',
|
||||||
|
background: token.colorBgComponent,
|
||||||
|
borderTop: `${token.controlLineWidth}px ${token.controlLineType} ${borderColorSplit}`,
|
||||||
|
display: 'flex',
|
||||||
|
...clearFix(),
|
||||||
|
|
||||||
|
'& > li': {
|
||||||
|
margin: cardActionsLiMargin,
|
||||||
|
color: token.colorTextSecondary,
|
||||||
|
textAlign: 'center',
|
||||||
|
|
||||||
|
'> span': {
|
||||||
|
position: 'relative',
|
||||||
|
display: 'block',
|
||||||
|
minWidth: 32, // FIXME: hardcode in v4
|
||||||
|
fontSize: token.fontSizeBase,
|
||||||
|
lineHeight: token.lineHeight,
|
||||||
|
cursor: 'pointer',
|
||||||
|
|
||||||
|
'&:hover': {
|
||||||
|
color: token.colorPrimary,
|
||||||
|
transition: `color ${token.motionDurationSlow}`,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`a:not(${componentCls}-btn), > ${iconCls}`]: {
|
||||||
|
display: 'inline-block',
|
||||||
|
width: '100%',
|
||||||
|
color: token.colorTextSecondary,
|
||||||
|
lineHeight: '22px', // FIXME: hardcode in v4
|
||||||
|
transition: `color ${token.motionDurationSlow}`,
|
||||||
|
|
||||||
|
'&:hover': {
|
||||||
|
color: token.colorPrimary,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`> ${iconCls}`]: {
|
||||||
|
fontSize: cardActionsIconSize,
|
||||||
|
lineHeight: '22px', // FIXME: hardcode in v4
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
'&:not(:last-child)': {
|
||||||
|
borderInlineEnd: `${token.controlLineWidth}px ${token.controlLineType} ${borderColorSplit}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================== Meta ==============================
|
||||||
|
const genCardMetaStyle: GenerateStyle<CardToken> = (token): CSSObject => ({
|
||||||
|
margin: '-4px 0', // FIXME: hardcode in v4
|
||||||
|
display: 'flex',
|
||||||
|
...clearFix(),
|
||||||
|
|
||||||
|
'&-avatar': {
|
||||||
|
paddingInlineEnd: 16, // FIXME: hardcode in v4
|
||||||
|
},
|
||||||
|
|
||||||
|
'&-detail': {
|
||||||
|
overflow: 'hidden',
|
||||||
|
|
||||||
|
'> div:not(:last-child)': {
|
||||||
|
marginBottom: token.marginXS,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
'&-title': {
|
||||||
|
overflow: 'hidden',
|
||||||
|
color: token.colorTextHeading,
|
||||||
|
fontWeight: 500, // FIXME: hardcode in v4
|
||||||
|
fontSize: token.fontSizeLG,
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
},
|
||||||
|
|
||||||
|
'&-description': {
|
||||||
|
color: token.colorTextSecondary,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// ============================== Inner ==============================
|
||||||
|
const genCardTypeInnerStyle: GenerateStyle<CardToken> = (token): CSSObject => {
|
||||||
|
const { componentCls, cardPaddingBase, backgroundColorLight, cardInnerHeadPadding } = token;
|
||||||
|
|
||||||
|
return {
|
||||||
|
[`${componentCls}-head`]: {
|
||||||
|
padding: `0 ${cardPaddingBase}px`,
|
||||||
|
background: backgroundColorLight,
|
||||||
|
|
||||||
|
'&-title': {
|
||||||
|
padding: `${cardInnerHeadPadding}px 0`,
|
||||||
|
fontSize: token.fontSizeBase,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-body`]: {
|
||||||
|
padding: `16px ${cardPaddingBase}px`, // FIXME: hardcode in v4
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-extra`]: {
|
||||||
|
padding: `${cardInnerHeadPadding + 1.5}px 0`,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================== Loading ==============================
|
||||||
|
const genCardLoadingStyle: GenerateStyle<CardToken> = (token): CSSObject => {
|
||||||
|
const { componentCls, gradientMin, gradientMax } = token;
|
||||||
|
|
||||||
|
return {
|
||||||
|
overflow: 'hidden',
|
||||||
|
|
||||||
|
[`${componentCls}-body`]: {
|
||||||
|
userSelect: 'none',
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-loading-content p`]: {
|
||||||
|
margin: 0,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-loading-block`]: {
|
||||||
|
height: 14, // FIXME: hardcode in v4
|
||||||
|
margin: '4px 0', // FIXME: hardcode in v4
|
||||||
|
background: `linear-gradient(90deg, ${gradientMin}, ${gradientMax}, ${gradientMin})`,
|
||||||
|
backgroundSize: '600% 600%',
|
||||||
|
borderRadius: token.radiusBase,
|
||||||
|
animationName: antCardLoading,
|
||||||
|
animationDuration: '1.4s', // FIXME: hardcode
|
||||||
|
animationTimingFunction: 'ease',
|
||||||
|
animationIterationCount: 'infinite',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================== Basic ==============================
|
||||||
|
const genCardStyle: GenerateStyle<CardToken> = (token): CSSObject => {
|
||||||
|
const {
|
||||||
|
componentCls,
|
||||||
|
cardHoverableHoverBorder,
|
||||||
|
cardShadow,
|
||||||
|
cardHeadHeight,
|
||||||
|
cardHeadPadding,
|
||||||
|
cardPaddingBase,
|
||||||
|
borderColorSplit,
|
||||||
|
} = token;
|
||||||
|
|
||||||
|
return {
|
||||||
|
[componentCls]: {
|
||||||
|
...resetComponent(token),
|
||||||
|
|
||||||
|
position: 'relative',
|
||||||
|
background: token.colorBgComponent,
|
||||||
|
borderRadius: token.radiusBase,
|
||||||
|
|
||||||
|
[`${componentCls}-head`]: genCardHeadStyle(token),
|
||||||
|
|
||||||
|
[`${componentCls}-extra`]: {
|
||||||
|
// https://stackoverflow.com/a/22429853/3040605
|
||||||
|
marginInlineStart: 'auto',
|
||||||
|
padding: '',
|
||||||
|
color: '',
|
||||||
|
fontWeight: 'normal',
|
||||||
|
fontSize: token.fontSizeBase,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-body`]: {
|
||||||
|
padding: cardPaddingBase,
|
||||||
|
...clearFix(),
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-grid`]: genCardGridStyle(token),
|
||||||
|
|
||||||
|
[`${componentCls}-cover`]: {
|
||||||
|
'> *': {
|
||||||
|
display: 'block',
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
|
||||||
|
img: {
|
||||||
|
borderRadius: `${token.radiusBase}px ${token.radiusBase}px 0 0`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-actions`]: genCardActionsStyle(token),
|
||||||
|
|
||||||
|
[`${componentCls}-meta`]: genCardMetaStyle(token),
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-bordered`]: {
|
||||||
|
border: `${token.controlLineWidth}px ${token.controlLineType} ${borderColorSplit}`,
|
||||||
|
|
||||||
|
[`${componentCls}-cover`]: {
|
||||||
|
marginTop: -1,
|
||||||
|
marginInlineStart: -1,
|
||||||
|
marginInlineEnd: -1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-hoverable`]: {
|
||||||
|
cursor: 'pointer',
|
||||||
|
transition: `box-shadow ${token.motionDurationSlow}, border-color ${token.motionDurationSlow}`,
|
||||||
|
|
||||||
|
'&:hover': {
|
||||||
|
borderColor: cardHoverableHoverBorder,
|
||||||
|
boxShadow: cardShadow,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-contain-grid`]: {
|
||||||
|
[`${componentCls}-body`]: {
|
||||||
|
display: 'flex',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
},
|
||||||
|
|
||||||
|
[`&:not(${componentCls}-loading) ${componentCls}-body`]: {
|
||||||
|
margin: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: '-1px 0 0 -1px', // FIXME: hardcode in v4
|
||||||
|
},
|
||||||
|
padding: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-contain-tabs`]: {
|
||||||
|
[`> ${componentCls}-head`]: {
|
||||||
|
[`${componentCls}-head-title`]: {
|
||||||
|
minHeight: cardHeadHeight - cardHeadPadding,
|
||||||
|
paddingBottom: 0,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-extra`]: {
|
||||||
|
paddingBottom: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-type-inner`]: genCardTypeInnerStyle(token),
|
||||||
|
|
||||||
|
[`${componentCls}-loading`]: genCardLoadingStyle(token),
|
||||||
|
|
||||||
|
[`${componentCls}-rtl`]: {
|
||||||
|
direction: 'rtl',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================== Size ==============================
|
||||||
|
const genCardSizeStyle: GenerateStyle<CardToken> = (token): CSSObject => {
|
||||||
|
const { componentCls, cardHeadHeightSM, cardPaddingBase, cardHeadPadding } = token;
|
||||||
|
const cardPaddingBaseSM = cardPaddingBase / 2;
|
||||||
|
const cardHeadPaddingSM = cardHeadPadding / 2;
|
||||||
|
|
||||||
|
return {
|
||||||
|
[`${componentCls}-small`]: {
|
||||||
|
[`> ${componentCls}-head`]: {
|
||||||
|
minHeight: cardHeadHeightSM,
|
||||||
|
padding: `0 ${cardPaddingBaseSM}px`,
|
||||||
|
fontSize: token.fontSizeBase,
|
||||||
|
|
||||||
|
[`> ${componentCls}-head-wrapper`]: {
|
||||||
|
[`> ${componentCls}-head-title`]: {
|
||||||
|
padding: `${cardHeadPaddingSM}px 0`,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`> ${componentCls}-extra`]: {
|
||||||
|
padding: `${cardHeadPaddingSM}px 0`,
|
||||||
|
fontSize: token.fontSizeBase,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`> ${componentCls}-body`]: {
|
||||||
|
padding: cardPaddingBaseSM,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================== Export ==============================
|
||||||
|
export default genComponentStyleHook('Card', (token, { rootPrefixCls }) => {
|
||||||
|
const cardToken = mergeToken<CardToken>(token, {
|
||||||
|
rootPrefixCls,
|
||||||
|
|
||||||
|
cardHoverableHoverBorder: 'transparent', // FIXME: hardcode in v4
|
||||||
|
cardShadow: `
|
||||||
|
0 1px 2px -2px ${new TinyColor('rgba(0, 0, 0, 0.16)').toRgbString()},
|
||||||
|
0 3px 6px 0 ${new TinyColor('rgba(0, 0, 0, 0.12)').toRgbString()},
|
||||||
|
0 5px 12px 4px ${new TinyColor('rgba(0, 0, 0, 0.09)').toRgbString()}
|
||||||
|
`, // FIXME: hardcode in v4
|
||||||
|
cardHeadHeight: 48, // FIXME: hardcode in v4
|
||||||
|
cardHeadHeightSM: 30, // FIXME: hardcode in v4
|
||||||
|
cardHeadPadding: 16, // FIXME: hardcode in v4
|
||||||
|
cardPaddingBase: 24, // FIXME: hardcode in v4
|
||||||
|
cardHeadTabsMarginBottom: -17, // FIXME: hardcode in v4
|
||||||
|
cardInnerHeadPadding: 12, // FIXME: hardcode in v4
|
||||||
|
cardActionsLiMargin: '12px 0', // FIXME: hardcode in v4
|
||||||
|
cardActionsIconSize: 16, // FIXME: hardcode in v4
|
||||||
|
borderColorSplit: new TinyColor({ h: 0, s: 0, v: 94 }).toHexString(), // FIXME: hardcode in v4
|
||||||
|
backgroundColorLight: new TinyColor({ h: 0, s: 0, v: 98 }).toHexString(), // FIXME: hardcode in v4
|
||||||
|
gradientMin: new TinyColor('#cfd8dc').setAlpha(0.2).toRgbString(), // FIXME: hardcode in v4
|
||||||
|
gradientMax: new TinyColor('#cfd8dc').setAlpha(0.4).toRgbString(), // FIXME: hardcode in v4
|
||||||
|
});
|
||||||
|
|
||||||
|
return [
|
||||||
|
// Style
|
||||||
|
genCardStyle(cardToken),
|
||||||
|
|
||||||
|
// Size
|
||||||
|
genCardSizeStyle(cardToken),
|
||||||
|
];
|
||||||
|
});
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
.@{card-prefix-cls}-small {
|
// .@{card-prefix-cls}-small {
|
||||||
> .@{card-prefix-cls}-head {
|
// > .@{card-prefix-cls}-head {
|
||||||
min-height: @card-head-height-sm;
|
// min-height: @card-head-height-sm;
|
||||||
padding: 0 @card-padding-base-sm;
|
// padding: 0 @card-padding-base-sm;
|
||||||
font-size: @card-head-font-size-sm;
|
// font-size: @card-head-font-size-sm;
|
||||||
|
|
||||||
> .@{card-prefix-cls}-head-wrapper {
|
// > .@{card-prefix-cls}-head-wrapper {
|
||||||
> .@{card-prefix-cls}-head-title {
|
// > .@{card-prefix-cls}-head-title {
|
||||||
padding: @card-head-padding-sm 0;
|
// padding: @card-head-padding-sm 0;
|
||||||
}
|
// }
|
||||||
> .@{card-prefix-cls}-extra {
|
// > .@{card-prefix-cls}-extra {
|
||||||
padding: @card-head-padding-sm 0;
|
// padding: @card-head-padding-sm 0;
|
||||||
font-size: @card-head-font-size-sm;
|
// font-size: @card-head-font-size-sm;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
> .@{card-prefix-cls}-body {
|
// > .@{card-prefix-cls}-body {
|
||||||
padding: @card-padding-base-sm;
|
// padding: @card-padding-base-sm;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
@ -3,7 +3,7 @@ import { mount } from 'enzyme';
|
|||||||
import Carousel from '..';
|
import Carousel from '..';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import rtlTest from '../../../tests/shared/rtlTest';
|
import rtlTest from '../../../tests/shared/rtlTest';
|
||||||
import { sleep } from '../../../tests/utils';
|
import { sleep, render } from '../../../tests/utils';
|
||||||
|
|
||||||
describe('Carousel', () => {
|
describe('Carousel', () => {
|
||||||
mountTest(Carousel);
|
mountTest(Carousel);
|
||||||
@ -99,21 +99,28 @@ describe('Carousel', () => {
|
|||||||
|
|
||||||
describe('should active when children change', () => {
|
describe('should active when children change', () => {
|
||||||
it('should active', () => {
|
it('should active', () => {
|
||||||
const wrapper = mount(<Carousel />);
|
const { rerender, container } = render(<Carousel />);
|
||||||
wrapper.setProps({
|
expect(container.querySelector('.slick-active')).toBeFalsy();
|
||||||
children: <div />,
|
|
||||||
});
|
// Update children
|
||||||
wrapper.update();
|
rerender(
|
||||||
expect(wrapper.find('.slick-active').length).toBeTruthy();
|
<Carousel>
|
||||||
|
<div />
|
||||||
|
</Carousel>,
|
||||||
|
);
|
||||||
|
expect(container.querySelector('.slick-active')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should keep initialSlide', () => {
|
it('should keep initialSlide', () => {
|
||||||
const wrapper = mount(<Carousel initialSlide={1} />);
|
const { rerender, container } = render(<Carousel initialSlide={1} />);
|
||||||
wrapper.setProps({
|
rerender(
|
||||||
children: [<div key="1" />, <div key="2" />, <div key="3" />],
|
<Carousel initialSlide={1}>
|
||||||
});
|
<div key="1" />
|
||||||
wrapper.update();
|
<div key="2" />
|
||||||
expect(wrapper.find('.slick-dots li').at(1).hasClass('slick-active')).toBeTruthy();
|
<div key="3" />
|
||||||
|
</Carousel>,
|
||||||
|
);
|
||||||
|
expect(container.querySelectorAll('.slick-dots li')[1]).toHaveClass('slick-active');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -31,7 +31,17 @@ export interface CarouselRef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Carousel = React.forwardRef<CarouselRef, CarouselProps>(
|
const Carousel = React.forwardRef<CarouselRef, CarouselProps>(
|
||||||
({ dots = true, arrows = false, draggable = false, dotPosition = 'bottom', ...props }, ref) => {
|
(
|
||||||
|
{
|
||||||
|
dots = true,
|
||||||
|
arrows = false,
|
||||||
|
draggable = false,
|
||||||
|
dotPosition = 'bottom',
|
||||||
|
vertical = dotPosition === 'left' || dotPosition === 'right',
|
||||||
|
...props
|
||||||
|
},
|
||||||
|
ref,
|
||||||
|
) => {
|
||||||
const { getPrefixCls, direction } = React.useContext(ConfigContext);
|
const { getPrefixCls, direction } = React.useContext(ConfigContext);
|
||||||
const slickRef = React.useRef<any>();
|
const slickRef = React.useRef<any>();
|
||||||
|
|
||||||
@ -61,6 +71,7 @@ const Carousel = React.forwardRef<CarouselRef, CarouselProps>(
|
|||||||
}, [props.children]);
|
}, [props.children]);
|
||||||
|
|
||||||
const newProps = {
|
const newProps = {
|
||||||
|
vertical,
|
||||||
...props,
|
...props,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -70,7 +81,6 @@ const Carousel = React.forwardRef<CarouselRef, CarouselProps>(
|
|||||||
|
|
||||||
const prefixCls = getPrefixCls('carousel', newProps.prefixCls);
|
const prefixCls = getPrefixCls('carousel', newProps.prefixCls);
|
||||||
const dotsClass = 'slick-dots';
|
const dotsClass = 'slick-dots';
|
||||||
newProps.vertical = dotPosition === 'left' || dotPosition === 'right';
|
|
||||||
|
|
||||||
const enableDots = !!dots;
|
const enableDots = !!dots;
|
||||||
const dsClass = classNames(
|
const dsClass = classNames(
|
||||||
|
@ -1,20 +1,15 @@
|
|||||||
// deps-lint-skip-all
|
// deps-lint-skip-all
|
||||||
import type { CSSObject } from '@ant-design/cssinjs';
|
import type { CSSObject } from '@ant-design/cssinjs';
|
||||||
import {
|
import { genComponentStyleHook, resetComponent } from '../../_util/theme';
|
||||||
resetComponent,
|
import type { GenerateStyle, FullToken } from '../../_util/theme';
|
||||||
GenerateStyle,
|
|
||||||
genComponentStyleHook,
|
|
||||||
FullToken,
|
|
||||||
mergeToken,
|
|
||||||
} from '../../_util/theme';
|
|
||||||
|
|
||||||
interface CarouselToken extends FullToken<'Carousel'> {
|
export interface ComponentToken {
|
||||||
carouselDotWidth: CSSObject['width'];
|
carouselDotWidth: CSSObject['width'];
|
||||||
carouselDotHeight: CSSObject['height'];
|
carouselDotHeight: CSSObject['height'];
|
||||||
carouselDotActiveWidth: CSSObject['width'];
|
carouselDotActiveWidth: CSSObject['width'];
|
||||||
}
|
}
|
||||||
|
|
||||||
const genCarouselStyle: GenerateStyle<CarouselToken, CSSObject> = token => {
|
const genCarouselStyle: GenerateStyle<FullToken<'Carousel'>> = token => {
|
||||||
const { componentCls, antCls } = token;
|
const { componentCls, antCls } = token;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -127,7 +122,7 @@ const genCarouselStyle: GenerateStyle<CarouselToken, CSSObject> = token => {
|
|||||||
// FIXME hardcode in v4
|
// FIXME hardcode in v4
|
||||||
width: 20,
|
width: 20,
|
||||||
height: 20,
|
height: 20,
|
||||||
marginTop: '-10px',
|
marginTop: -10,
|
||||||
padding: 0,
|
padding: 0,
|
||||||
color: 'transparent',
|
color: 'transparent',
|
||||||
fontSize: 0,
|
fontSize: 0,
|
||||||
@ -157,7 +152,7 @@ const genCarouselStyle: GenerateStyle<CarouselToken, CSSObject> = token => {
|
|||||||
insetInlineStart: -25,
|
insetInlineStart: -25,
|
||||||
|
|
||||||
'&::before': {
|
'&::before': {
|
||||||
content: '←',
|
content: '"←"',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -166,7 +161,7 @@ const genCarouselStyle: GenerateStyle<CarouselToken, CSSObject> = token => {
|
|||||||
insetInlineEnd: -25,
|
insetInlineEnd: -25,
|
||||||
|
|
||||||
'&::before': {
|
'&::before': {
|
||||||
content: '→',
|
content: '"→"',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -186,12 +181,12 @@ const genCarouselStyle: GenerateStyle<CarouselToken, CSSObject> = token => {
|
|||||||
|
|
||||||
'&-bottom': {
|
'&-bottom': {
|
||||||
// FIXME hardcode in v4
|
// FIXME hardcode in v4
|
||||||
bottom: '12px',
|
bottom: 12,
|
||||||
},
|
},
|
||||||
|
|
||||||
'&-top': {
|
'&-top': {
|
||||||
// FIXME hardcode in v4
|
// FIXME hardcode in v4
|
||||||
top: '12px',
|
top: 12,
|
||||||
bottom: 'auto',
|
bottom: 'auto',
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -250,7 +245,7 @@ const genCarouselStyle: GenerateStyle<CarouselToken, CSSObject> = token => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const genCarouselVerticalStyle: GenerateStyle<CarouselToken, CSSObject> = token => {
|
const genCarouselVerticalStyle: GenerateStyle<FullToken<'Carousel'>> = token => {
|
||||||
const { componentCls } = token;
|
const { componentCls } = token;
|
||||||
|
|
||||||
const reverseSizeOfDot = {
|
const reverseSizeOfDot = {
|
||||||
@ -298,7 +293,7 @@ const genCarouselVerticalStyle: GenerateStyle<CarouselToken, CSSObject> = token
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const genCarouselRtlStyle: GenerateStyle<CarouselToken> = token => {
|
const genCarouselRtlStyle: GenerateStyle<FullToken<'Carousel'>> = token => {
|
||||||
const { componentCls } = token;
|
const { componentCls } = token;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
@ -327,16 +322,13 @@ const genCarouselRtlStyle: GenerateStyle<CarouselToken> = token => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ============================== Export ==============================
|
// ============================== Export ==============================
|
||||||
export default genComponentStyleHook('Carousel', token => {
|
export default genComponentStyleHook(
|
||||||
const carouselToken = mergeToken<CarouselToken>(token, {
|
'Carousel',
|
||||||
|
token => [genCarouselStyle(token), genCarouselVerticalStyle(token), genCarouselRtlStyle(token)],
|
||||||
|
{
|
||||||
// FIXME
|
// FIXME
|
||||||
carouselDotWidth: 16,
|
carouselDotWidth: 16,
|
||||||
carouselDotHeight: 3,
|
carouselDotHeight: 3,
|
||||||
carouselDotActiveWidth: 24,
|
carouselDotActiveWidth: 24,
|
||||||
});
|
},
|
||||||
return [
|
);
|
||||||
genCarouselStyle(carouselToken),
|
|
||||||
genCarouselVerticalStyle(carouselToken),
|
|
||||||
genCarouselRtlStyle(carouselToken),
|
|
||||||
];
|
|
||||||
});
|
|
||||||
|
@ -34,7 +34,7 @@ exports[`renders ./components/cascader/demo/basic.md extend context correctly 1`
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown"
|
class="ant-select-dropdown ant-cascader-dropdown"
|
||||||
style="opacity:0;pointer-events:none;min-width:auto"
|
style="opacity:0;min-width:auto"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -182,7 +182,7 @@ exports[`renders ./components/cascader/demo/change-on-select.md extend context c
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown"
|
class="ant-select-dropdown ant-cascader-dropdown"
|
||||||
style="opacity:0;pointer-events:none;min-width:auto"
|
style="opacity:0;min-width:auto"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -332,7 +332,7 @@ exports[`renders ./components/cascader/demo/custom-dropdown.md extend context co
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown"
|
class="ant-select-dropdown ant-cascader-dropdown"
|
||||||
style="opacity:0;pointer-events:none;min-width:auto"
|
style="opacity:0;min-width:auto"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
@ -507,7 +507,7 @@ exports[`renders ./components/cascader/demo/custom-render.md extend context corr
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown"
|
class="ant-select-dropdown ant-cascader-dropdown"
|
||||||
style="opacity:0;pointer-events:none;min-width:auto"
|
style="opacity:0;min-width:auto"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -660,7 +660,7 @@ exports[`renders ./components/cascader/demo/custom-trigger.md extend context cor
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown"
|
class="ant-select-dropdown ant-cascader-dropdown"
|
||||||
style="opacity:0;pointer-events:none;min-width:auto"
|
style="opacity:0;min-width:auto"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -785,7 +785,7 @@ exports[`renders ./components/cascader/demo/default-value.md extend context corr
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown"
|
class="ant-select-dropdown ant-cascader-dropdown"
|
||||||
style="opacity:0;pointer-events:none;min-width:auto"
|
style="opacity:0;min-width:auto"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -959,7 +959,7 @@ exports[`renders ./components/cascader/demo/disabled-option.md extend context co
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown"
|
class="ant-select-dropdown ant-cascader-dropdown"
|
||||||
style="opacity:0;pointer-events:none;min-width:auto"
|
style="opacity:0;min-width:auto"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -1109,7 +1109,7 @@ exports[`renders ./components/cascader/demo/fields-name.md extend context correc
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown"
|
class="ant-select-dropdown ant-cascader-dropdown"
|
||||||
style="opacity:0;pointer-events:none;min-width:auto"
|
style="opacity:0;min-width:auto"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -1257,7 +1257,7 @@ exports[`renders ./components/cascader/demo/hover.md extend context correctly 1`
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown"
|
class="ant-select-dropdown ant-cascader-dropdown"
|
||||||
style="opacity:0;pointer-events:none;min-width:auto"
|
style="opacity:0;min-width:auto"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -1405,7 +1405,7 @@ exports[`renders ./components/cascader/demo/lazy.md extend context correctly 1`]
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown"
|
class="ant-select-dropdown ant-cascader-dropdown"
|
||||||
style="opacity:0;pointer-events:none;min-width:auto"
|
style="opacity:0;min-width:auto"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -1570,7 +1570,7 @@ exports[`renders ./components/cascader/demo/multiple.md extend context correctly
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown"
|
class="ant-select-dropdown ant-cascader-dropdown"
|
||||||
style="opacity:0;pointer-events:none;min-width:auto"
|
style="opacity:0;min-width:auto"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -1792,7 +1792,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown"
|
class="ant-select-dropdown ant-cascader-dropdown"
|
||||||
style="opacity:0;pointer-events:none;min-width:auto"
|
style="opacity:0;min-width:auto"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -1940,7 +1940,7 @@ exports[`renders ./components/cascader/demo/search.md extend context correctly 1
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown"
|
class="ant-select-dropdown ant-cascader-dropdown"
|
||||||
style="opacity:0;pointer-events:none;min-width:auto"
|
style="opacity:0;min-width:auto"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -2119,7 +2119,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown"
|
class="ant-select-dropdown ant-cascader-dropdown"
|
||||||
style="opacity:0;pointer-events:none;min-width:auto"
|
style="opacity:0;min-width:auto"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -2310,7 +2310,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown"
|
class="ant-select-dropdown ant-cascader-dropdown"
|
||||||
style="opacity:0;pointer-events:none;min-width:auto"
|
style="opacity:0;min-width:auto"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -2474,7 +2474,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown"
|
class="ant-select-dropdown ant-cascader-dropdown"
|
||||||
style="opacity:0;pointer-events:none;min-width:auto"
|
style="opacity:0;min-width:auto"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -2621,7 +2621,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown"
|
class="ant-select-dropdown ant-cascader-dropdown"
|
||||||
style="opacity:0;pointer-events:none;min-width:auto"
|
style="opacity:0;min-width:auto"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -2768,7 +2768,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown"
|
class="ant-select-dropdown ant-cascader-dropdown"
|
||||||
style="opacity:0;pointer-events:none;min-width:auto"
|
style="opacity:0;min-width:auto"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -2928,7 +2928,7 @@ exports[`renders ./components/cascader/demo/status.md extend context correctly 1
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown ant-select-dropdown-empty"
|
class="ant-select-dropdown ant-cascader-dropdown ant-select-dropdown-empty"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -3080,7 +3080,7 @@ exports[`renders ./components/cascader/demo/status.md extend context correctly 1
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown ant-select-dropdown-empty"
|
class="ant-select-dropdown ant-cascader-dropdown ant-select-dropdown-empty"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -3192,7 +3192,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown"
|
class="ant-select-dropdown ant-cascader-dropdown"
|
||||||
style="opacity:0;pointer-events:none;min-width:auto"
|
style="opacity:0;min-width:auto"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -3341,7 +3341,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown"
|
class="ant-select-dropdown ant-cascader-dropdown"
|
||||||
style="opacity:0;pointer-events:none;min-width:auto"
|
style="opacity:0;min-width:auto"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -3472,7 +3472,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown"
|
class="ant-select-dropdown ant-cascader-dropdown"
|
||||||
style="opacity:0;pointer-events:none;min-width:auto"
|
style="opacity:0;min-width:auto"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -3621,7 +3621,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown"
|
class="ant-select-dropdown ant-cascader-dropdown"
|
||||||
style="opacity:0;pointer-events:none;min-width:auto"
|
style="opacity:0;min-width:auto"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
exports[`Cascader can be selected 1`] = `
|
exports[`Cascader can be selected 1`] = `
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
|
class="ant-select-dropdown ant-cascader-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
|
||||||
style="opacity: 0; pointer-events: none; min-width: auto;"
|
style="opacity: 0; min-width: auto;"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -135,7 +135,7 @@ exports[`Cascader can be selected 1`] = `
|
|||||||
exports[`Cascader can be selected 2`] = `
|
exports[`Cascader can be selected 2`] = `
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
|
class="ant-select-dropdown ant-cascader-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
|
||||||
style="opacity: 0; pointer-events: none; min-width: auto;"
|
style="opacity: 0; min-width: auto;"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -285,7 +285,7 @@ exports[`Cascader can be selected 2`] = `
|
|||||||
exports[`Cascader can be selected 3`] = `
|
exports[`Cascader can be selected 3`] = `
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown ant-slide-up-leave ant-slide-up-leave-start ant-slide-up"
|
class="ant-select-dropdown ant-cascader-dropdown ant-slide-up-leave ant-slide-up-leave-start ant-slide-up"
|
||||||
style="pointer-events: none; min-width: auto;"
|
style="min-width: auto; pointer-events: none;"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -435,7 +435,7 @@ exports[`Cascader can be selected 3`] = `
|
|||||||
exports[`Cascader can be selected in RTL direction 1`] = `
|
exports[`Cascader can be selected in RTL direction 1`] = `
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown ant-cascader-dropdown-rtl ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
|
class="ant-select-dropdown ant-cascader-dropdown ant-cascader-dropdown-rtl ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
|
||||||
style="opacity: 0; pointer-events: none; min-width: auto;"
|
style="opacity: 0; min-width: auto;"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -567,7 +567,7 @@ exports[`Cascader can be selected in RTL direction 1`] = `
|
|||||||
exports[`Cascader can be selected in RTL direction 2`] = `
|
exports[`Cascader can be selected in RTL direction 2`] = `
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown ant-cascader-dropdown-rtl ant-slide-up-leave ant-slide-up-leave-start ant-slide-up"
|
class="ant-select-dropdown ant-cascader-dropdown ant-cascader-dropdown-rtl ant-slide-up-leave ant-slide-up-leave-start ant-slide-up"
|
||||||
style="pointer-events: none; min-width: auto;"
|
style="min-width: auto; pointer-events: none;"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -717,7 +717,7 @@ exports[`Cascader can be selected in RTL direction 2`] = `
|
|||||||
exports[`Cascader can be selected in RTL direction 3`] = `
|
exports[`Cascader can be selected in RTL direction 3`] = `
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown ant-cascader-dropdown-rtl ant-slide-up-leave ant-slide-up-leave-start ant-slide-up"
|
class="ant-select-dropdown ant-cascader-dropdown ant-cascader-dropdown-rtl ant-slide-up-leave ant-slide-up-leave-start ant-slide-up"
|
||||||
style="pointer-events: none; min-width: auto;"
|
style="min-width: auto; pointer-events: none;"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -914,7 +914,7 @@ exports[`Cascader legacy props should support showCheckedStrategy child 1`] = `
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
|
class="ant-select-dropdown ant-cascader-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
|
||||||
style="opacity: 0; pointer-events: none; min-width: auto;"
|
style="opacity: 0; min-width: auto;"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -1068,7 +1068,7 @@ exports[`Cascader legacy props should support showCheckedStrategy parent 1`] = `
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
|
class="ant-select-dropdown ant-cascader-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
|
||||||
style="opacity: 0; pointer-events: none; min-width: auto;"
|
style="opacity: 0; min-width: auto;"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -1175,7 +1175,7 @@ exports[`Cascader legacy props should support showCheckedStrategy parent 1`] = `
|
|||||||
exports[`Cascader popup correctly with defaultValue 1`] = `
|
exports[`Cascader popup correctly with defaultValue 1`] = `
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
|
class="ant-select-dropdown ant-cascader-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
|
||||||
style="opacity: 0; pointer-events: none; min-width: auto;"
|
style="opacity: 0; min-width: auto;"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -1359,7 +1359,7 @@ exports[`Cascader popup correctly with defaultValue RTL 1`] = `
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown ant-cascader-dropdown-rtl ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
|
class="ant-select-dropdown ant-cascader-dropdown ant-cascader-dropdown-rtl ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
|
||||||
style="opacity: 0; pointer-events: none; min-width: auto;"
|
style="opacity: 0; min-width: auto;"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -1622,7 +1622,7 @@ exports[`Cascader rtl render component should be rendered correctly in RTL direc
|
|||||||
exports[`Cascader should highlight keyword and filter when search in Cascader 1`] = `
|
exports[`Cascader should highlight keyword and filter when search in Cascader 1`] = `
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
|
class="ant-select-dropdown ant-cascader-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
|
||||||
style="opacity: 0; pointer-events: none; min-width: 0;"
|
style="opacity: 0; min-width: 0;"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -1682,7 +1682,7 @@ exports[`Cascader should highlight keyword and filter when search in Cascader 1`
|
|||||||
exports[`Cascader should highlight keyword and filter when search in Cascader with same field name of label and value 1`] = `
|
exports[`Cascader should highlight keyword and filter when search in Cascader with same field name of label and value 1`] = `
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
|
class="ant-select-dropdown ant-cascader-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
|
||||||
style="opacity: 0; pointer-events: none; min-width: 0;"
|
style="opacity: 0; min-width: 0;"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -1747,7 +1747,7 @@ exports[`Cascader should highlight keyword and filter when search in Cascader wi
|
|||||||
exports[`Cascader should render not found content 1`] = `
|
exports[`Cascader should render not found content 1`] = `
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown ant-select-dropdown-empty ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
|
class="ant-select-dropdown ant-cascader-dropdown ant-select-dropdown-empty ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
|
||||||
style="opacity: 0; pointer-events: none; min-width: 0;"
|
style="opacity: 0; min-width: 0;"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -1823,7 +1823,7 @@ exports[`Cascader should render not found content 1`] = `
|
|||||||
exports[`Cascader should show not found content when options.length is 0 1`] = `
|
exports[`Cascader should show not found content when options.length is 0 1`] = `
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown ant-cascader-dropdown ant-select-dropdown-empty ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
|
class="ant-select-dropdown ant-cascader-dropdown ant-select-dropdown-empty ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
|
||||||
style="opacity: 0; pointer-events: none; min-width: 0;"
|
style="opacity: 0; min-width: 0;"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
|
@ -66,5 +66,5 @@ const App = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default () => <App />;
|
export default App;
|
||||||
```
|
```
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// &-menu {
|
// &-menu {
|
||||||
|
// flex-grow: 1;
|
||||||
// min-width: 111px;
|
// min-width: 111px;
|
||||||
// height: 180px;
|
// height: 180px;
|
||||||
// margin: 0;
|
// margin: 0;
|
||||||
|
@ -21,7 +21,7 @@ export interface ComponentToken {
|
|||||||
type CascaderToken = FullToken<'Cascader'>;
|
type CascaderToken = FullToken<'Cascader'>;
|
||||||
|
|
||||||
// =============================== Base ===============================
|
// =============================== Base ===============================
|
||||||
const genBaseStyle: GenerateStyle<CascaderToken> = (token, hashId) => {
|
const genBaseStyle: GenerateStyle<CascaderToken> = token => {
|
||||||
const { prefixCls, componentCls } = token;
|
const { prefixCls, componentCls } = token;
|
||||||
const cascaderMenuItemCls = `${componentCls}-menu-item`;
|
const cascaderMenuItemCls = `${componentCls}-menu-item`;
|
||||||
const iconCls = `
|
const iconCls = `
|
||||||
@ -49,7 +49,7 @@ const genBaseStyle: GenerateStyle<CascaderToken> = (token, hashId) => {
|
|||||||
{
|
{
|
||||||
[`${componentCls}-dropdown`]: [
|
[`${componentCls}-dropdown`]: [
|
||||||
// ==================== Checkbox ====================
|
// ==================== Checkbox ====================
|
||||||
getCheckboxStyle(`${prefixCls}-checkbox`, token, hashId!),
|
getCheckboxStyle(`${prefixCls}-checkbox`, token),
|
||||||
{
|
{
|
||||||
[componentCls]: {
|
[componentCls]: {
|
||||||
// ================== Checkbox ==================
|
// ================== Checkbox ==================
|
||||||
@ -81,6 +81,7 @@ const genBaseStyle: GenerateStyle<CascaderToken> = (token, hashId) => {
|
|||||||
|
|
||||||
// >>> Menu
|
// >>> Menu
|
||||||
'&-menu': {
|
'&-menu': {
|
||||||
|
flexGrow: 1,
|
||||||
minWidth: token.controlItemWidth,
|
minWidth: token.controlItemWidth,
|
||||||
height: token.dropdownHeight,
|
height: token.dropdownHeight,
|
||||||
margin: `-${token.paddingXS}px 0`,
|
margin: `-${token.paddingXS}px 0`,
|
||||||
@ -157,12 +158,8 @@ const genBaseStyle: GenerateStyle<CascaderToken> = (token, hashId) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ============================== Export ==============================
|
// ============================== Export ==============================
|
||||||
export default genComponentStyleHook(
|
export default genComponentStyleHook('Cascader', token => [genBaseStyle(token)], {
|
||||||
'Cascader',
|
controlWidth: 184,
|
||||||
(token, { hashId }) => [genBaseStyle(token, hashId)],
|
controlItemWidth: 111,
|
||||||
{
|
dropdownHeight: 180,
|
||||||
controlWidth: 184,
|
});
|
||||||
controlItemWidth: 111,
|
|
||||||
dropdownHeight: 180,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
@ -25,7 +25,7 @@ exports[`CheckboxGroup passes prefixCls down to checkbox 1`] = `
|
|||||||
</label>
|
</label>
|
||||||
<label
|
<label
|
||||||
class="my-checkbox-wrapper my-checkbox-group-item"
|
class="my-checkbox-wrapper my-checkbox-group-item"
|
||||||
style="font-size:12px"
|
style="font-size: 12px;"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="my-checkbox"
|
class="my-checkbox"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { mount } from 'enzyme';
|
import { render, fireEvent } from '../../../tests/utils';
|
||||||
import Checkbox from '..';
|
import Checkbox from '..';
|
||||||
import focusTest from '../../../tests/shared/focusTest';
|
import focusTest from '../../../tests/shared/focusTest';
|
||||||
import { resetWarned } from '../../_util/devWarning';
|
import { resetWarned } from '../../_util/devWarning';
|
||||||
@ -15,12 +15,14 @@ describe('Checkbox', () => {
|
|||||||
const onMouseEnter = jest.fn();
|
const onMouseEnter = jest.fn();
|
||||||
const onMouseLeave = jest.fn();
|
const onMouseLeave = jest.fn();
|
||||||
|
|
||||||
const wrapper = mount(<Checkbox onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} />);
|
const { container } = render(
|
||||||
|
<Checkbox onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} />,
|
||||||
|
);
|
||||||
|
|
||||||
wrapper.find('label').simulate('mouseenter');
|
fireEvent.mouseEnter(container.querySelector('label'));
|
||||||
expect(onMouseEnter).toHaveBeenCalled();
|
expect(onMouseEnter).toHaveBeenCalled();
|
||||||
|
|
||||||
wrapper.find('label').simulate('mouseleave');
|
fireEvent.mouseLeave(container.querySelector('label'));
|
||||||
expect(onMouseLeave).toHaveBeenCalled();
|
expect(onMouseLeave).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -28,7 +30,7 @@ describe('Checkbox', () => {
|
|||||||
resetWarned();
|
resetWarned();
|
||||||
|
|
||||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
mount(<Checkbox value />);
|
render(<Checkbox value />);
|
||||||
expect(errorSpy).toHaveBeenCalledWith(
|
expect(errorSpy).toHaveBeenCalledWith(
|
||||||
'Warning: [antd: Checkbox] `value` is not a valid prop, do you mean `checked`?',
|
'Warning: [antd: Checkbox] `value` is not a valid prop, do you mean `checked`?',
|
||||||
);
|
);
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { mount, render } from 'enzyme';
|
|
||||||
import Collapse from '../../collapse';
|
import Collapse from '../../collapse';
|
||||||
import Table from '../../table';
|
import Table from '../../table';
|
||||||
import Checkbox from '../index';
|
import Checkbox from '../index';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import rtlTest from '../../../tests/shared/rtlTest';
|
import rtlTest from '../../../tests/shared/rtlTest';
|
||||||
|
import { render, fireEvent } from '../../../tests/utils';
|
||||||
import Input from '../../input';
|
import Input from '../../input';
|
||||||
|
|
||||||
describe('CheckboxGroup', () => {
|
describe('CheckboxGroup', () => {
|
||||||
@ -13,16 +13,16 @@ describe('CheckboxGroup', () => {
|
|||||||
|
|
||||||
it('should work basically', () => {
|
it('should work basically', () => {
|
||||||
const onChange = jest.fn();
|
const onChange = jest.fn();
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<Checkbox.Group options={['Apple', 'Pear', 'Orange']} onChange={onChange} />,
|
<Checkbox.Group options={['Apple', 'Pear', 'Orange']} onChange={onChange} />,
|
||||||
);
|
);
|
||||||
wrapper.find('.ant-checkbox-input').at(0).simulate('change');
|
fireEvent.click(container.querySelectorAll('.ant-checkbox-input')[0]);
|
||||||
expect(onChange).toHaveBeenCalledWith(['Apple']);
|
expect(onChange).toHaveBeenCalledWith(['Apple']);
|
||||||
wrapper.find('.ant-checkbox-input').at(1).simulate('change');
|
fireEvent.click(container.querySelectorAll('.ant-checkbox-input')[1]);
|
||||||
expect(onChange).toHaveBeenCalledWith(['Apple', 'Pear']);
|
expect(onChange).toHaveBeenCalledWith(['Apple', 'Pear']);
|
||||||
wrapper.find('.ant-checkbox-input').at(2).simulate('change');
|
fireEvent.click(container.querySelectorAll('.ant-checkbox-input')[2]);
|
||||||
expect(onChange).toHaveBeenCalledWith(['Apple', 'Pear', 'Orange']);
|
expect(onChange).toHaveBeenCalledWith(['Apple', 'Pear', 'Orange']);
|
||||||
wrapper.find('.ant-checkbox-input').at(1).simulate('change');
|
fireEvent.click(container.querySelectorAll('.ant-checkbox-input')[1]);
|
||||||
expect(onChange).toHaveBeenCalledWith(['Apple', 'Orange']);
|
expect(onChange).toHaveBeenCalledWith(['Apple', 'Orange']);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -34,12 +34,12 @@ describe('CheckboxGroup', () => {
|
|||||||
{ label: 'Pear', value: 'Pear' },
|
{ label: 'Pear', value: 'Pear' },
|
||||||
];
|
];
|
||||||
|
|
||||||
const groupWrapper = mount(
|
const { container } = render(
|
||||||
<Checkbox.Group options={options} onChange={onChangeGroup} disabled />,
|
<Checkbox.Group options={options} onChange={onChangeGroup} disabled />,
|
||||||
);
|
);
|
||||||
groupWrapper.find('.ant-checkbox-input').at(0).simulate('change');
|
fireEvent.click(container.querySelectorAll('.ant-checkbox-input')[0]);
|
||||||
expect(onChangeGroup).not.toHaveBeenCalled();
|
expect(onChangeGroup).not.toHaveBeenCalled();
|
||||||
groupWrapper.find('.ant-checkbox-input').at(1).simulate('change');
|
fireEvent.click(container.querySelectorAll('.ant-checkbox-input')[1]);
|
||||||
expect(onChangeGroup).not.toHaveBeenCalled();
|
expect(onChangeGroup).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -51,17 +51,17 @@ describe('CheckboxGroup', () => {
|
|||||||
{ label: 'Orange', value: 'Orange', disabled: true },
|
{ label: 'Orange', value: 'Orange', disabled: true },
|
||||||
];
|
];
|
||||||
|
|
||||||
const groupWrapper = mount(<Checkbox.Group options={options} onChange={onChangeGroup} />);
|
const { container } = render(<Checkbox.Group options={options} onChange={onChangeGroup} />);
|
||||||
groupWrapper.find('.ant-checkbox-input').at(0).simulate('change');
|
fireEvent.click(container.querySelectorAll('.ant-checkbox-input')[0]);
|
||||||
expect(onChangeGroup).toHaveBeenCalledWith(['Apple']);
|
expect(onChangeGroup).toHaveBeenCalledWith(['Apple']);
|
||||||
groupWrapper.find('.ant-checkbox-input').at(1).simulate('change');
|
fireEvent.click(container.querySelectorAll('.ant-checkbox-input')[1]);
|
||||||
expect(onChangeGroup).toHaveBeenCalledWith(['Apple']);
|
expect(onChangeGroup).toHaveBeenCalledWith(['Apple']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('all children should have a name property', () => {
|
it('all children should have a name property', () => {
|
||||||
const wrapper = mount(<Checkbox.Group name="checkboxgroup" options={['Yes', 'No']} />);
|
const { container } = render(<Checkbox.Group name="checkboxgroup" options={['Yes', 'No']} />);
|
||||||
wrapper.find('input[type="checkbox"]').forEach(el => {
|
[...container.querySelectorAll('input[type="checkbox"]')].forEach(el => {
|
||||||
expect(el.props().name).toEqual('checkboxgroup');
|
expect(el.getAttribute('name')).toEqual('checkboxgroup');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -71,9 +71,9 @@ describe('CheckboxGroup', () => {
|
|||||||
{ label: 'Orange', value: 'Orange', style: { fontSize: 12 } },
|
{ label: 'Orange', value: 'Orange', style: { fontSize: 12 } },
|
||||||
];
|
];
|
||||||
|
|
||||||
const wrapper = render(<Checkbox.Group prefixCls="my-checkbox" options={options} />);
|
const { container } = render(<Checkbox.Group prefixCls="my-checkbox" options={options} />);
|
||||||
|
|
||||||
expect(wrapper).toMatchSnapshot();
|
expect(container.firstChild).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be controlled by value', () => {
|
it('should be controlled by value', () => {
|
||||||
@ -81,23 +81,22 @@ describe('CheckboxGroup', () => {
|
|||||||
{ label: 'Apple', value: 'Apple' },
|
{ label: 'Apple', value: 'Apple' },
|
||||||
{ label: 'Orange', value: 'Orange' },
|
{ label: 'Orange', value: 'Orange' },
|
||||||
];
|
];
|
||||||
|
const renderCheckbox = props => <Checkbox.Group {...props} />;
|
||||||
const wrapper = mount(<Checkbox.Group options={options} />);
|
const { container, rerender } = render(renderCheckbox({ options }));
|
||||||
expect(wrapper.find('.ant-checkbox-checked').length).toBe(0);
|
expect(container.querySelectorAll('.ant-checkbox-checked').length).toBe(0);
|
||||||
wrapper.setProps({ value: ['Apple'] });
|
rerender(renderCheckbox({ options, value: 'Apple' }));
|
||||||
wrapper.update();
|
expect(container.querySelectorAll('.ant-checkbox-checked').length).toBe(1);
|
||||||
expect(wrapper.find('.ant-checkbox-checked').length).toBe(1);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// https://github.com/ant-design/ant-design/issues/12642
|
// https://github.com/ant-design/ant-design/issues/12642
|
||||||
it('should trigger onChange in sub Checkbox', () => {
|
it('should trigger onChange in sub Checkbox', () => {
|
||||||
const onChange = jest.fn();
|
const onChange = jest.fn();
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<Checkbox.Group>
|
<Checkbox.Group>
|
||||||
<Checkbox value="my" onChange={onChange} />
|
<Checkbox value="my" onChange={onChange} />
|
||||||
</Checkbox.Group>,
|
</Checkbox.Group>,
|
||||||
);
|
);
|
||||||
wrapper.find('.ant-checkbox-input').at(0).simulate('change');
|
fireEvent.click(container.querySelectorAll('.ant-checkbox-input')[0]);
|
||||||
expect(onChange).toHaveBeenCalled();
|
expect(onChange).toHaveBeenCalled();
|
||||||
expect(onChange.mock.calls[0][0].target.value).toEqual('my');
|
expect(onChange.mock.calls[0][0].target.value).toEqual('my');
|
||||||
});
|
});
|
||||||
@ -105,40 +104,44 @@ describe('CheckboxGroup', () => {
|
|||||||
// https://github.com/ant-design/ant-design/issues/16376
|
// https://github.com/ant-design/ant-design/issues/16376
|
||||||
it('onChange should filter removed value', () => {
|
it('onChange should filter removed value', () => {
|
||||||
const onChange = jest.fn();
|
const onChange = jest.fn();
|
||||||
const wrapper = mount(
|
const { container, rerender } = render(
|
||||||
<Checkbox.Group defaultValue={[1]} onChange={onChange}>
|
<Checkbox.Group defaultValue={[1]} onChange={onChange}>
|
||||||
<Checkbox key={1} value={1} />
|
<Checkbox key={1} value={1} />
|
||||||
<Checkbox key={2} value={2} />
|
<Checkbox key={2} value={2} />
|
||||||
</Checkbox.Group>,
|
</Checkbox.Group>,
|
||||||
);
|
);
|
||||||
|
|
||||||
wrapper.setProps({
|
rerender(
|
||||||
children: [<Checkbox key={2} value={2} />],
|
<Checkbox.Group defaultValue={[1]} onChange={onChange}>
|
||||||
});
|
<Checkbox key={2} value={2} />
|
||||||
|
</Checkbox.Group>,
|
||||||
wrapper.find('.ant-checkbox-input').at(0).simulate('change');
|
);
|
||||||
|
fireEvent.click(container.querySelector('.ant-checkbox-input'));
|
||||||
|
|
||||||
expect(onChange).toHaveBeenCalledWith([2]);
|
expect(onChange).toHaveBeenCalledWith([2]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('checkbox should register value again after value changed', () => {
|
it('checkbox should register value again after value changed', () => {
|
||||||
const onChange = jest.fn();
|
const onChange = jest.fn();
|
||||||
const wrapper = mount(
|
const { container, rerender } = render(
|
||||||
<Checkbox.Group defaultValue={[1]} onChange={onChange}>
|
<Checkbox.Group defaultValue={[1]} onChange={onChange}>
|
||||||
<Checkbox key={1} value={1} />
|
<Checkbox key={1} value={1} />
|
||||||
</Checkbox.Group>,
|
</Checkbox.Group>,
|
||||||
);
|
);
|
||||||
|
|
||||||
wrapper.setProps({
|
rerender(
|
||||||
children: [<Checkbox key={1} value={2} />],
|
<Checkbox.Group defaultValue={[1]} onChange={onChange}>
|
||||||
});
|
<Checkbox key={1} value={2} />
|
||||||
expect(wrapper.find('.ant-checkbox-input').at(0).prop('checked')).toBe(false);
|
</Checkbox.Group>,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(container.querySelector('.ant-checkbox-input')).toHaveAttribute('checked');
|
||||||
});
|
});
|
||||||
|
|
||||||
// https://github.com/ant-design/ant-design/issues/17297
|
// https://github.com/ant-design/ant-design/issues/17297
|
||||||
it('onChange should keep the order of the original values', () => {
|
it('onChange should keep the order of the original values', () => {
|
||||||
const onChange = jest.fn();
|
const onChange = jest.fn();
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<Checkbox.Group onChange={onChange}>
|
<Checkbox.Group onChange={onChange}>
|
||||||
<Checkbox key={1} value={1} />
|
<Checkbox key={1} value={1} />
|
||||||
<Checkbox key={2} value={2} />
|
<Checkbox key={2} value={2} />
|
||||||
@ -146,20 +149,19 @@ describe('CheckboxGroup', () => {
|
|||||||
<Checkbox key={4} value={4} />
|
<Checkbox key={4} value={4} />
|
||||||
</Checkbox.Group>,
|
</Checkbox.Group>,
|
||||||
);
|
);
|
||||||
|
fireEvent.click(container.querySelectorAll('.ant-checkbox-input')[0]);
|
||||||
wrapper.find('.ant-checkbox-input').at(0).simulate('change');
|
|
||||||
expect(onChange).toHaveBeenCalledWith([1]);
|
expect(onChange).toHaveBeenCalledWith([1]);
|
||||||
wrapper.find('.ant-checkbox-input').at(1).simulate('change');
|
fireEvent.click(container.querySelectorAll('.ant-checkbox-input')[1]);
|
||||||
expect(onChange).toHaveBeenCalledWith([1, 2]);
|
expect(onChange).toHaveBeenCalledWith([1, 2]);
|
||||||
wrapper.find('.ant-checkbox-input').at(0).simulate('change');
|
fireEvent.click(container.querySelectorAll('.ant-checkbox-input')[0]);
|
||||||
expect(onChange).toHaveBeenCalledWith([2]);
|
expect(onChange).toHaveBeenCalledWith([2]);
|
||||||
wrapper.find('.ant-checkbox-input').at(0).simulate('change');
|
fireEvent.click(container.querySelectorAll('.ant-checkbox-input')[0]);
|
||||||
expect(onChange).toHaveBeenCalledWith([1, 2]);
|
expect(onChange).toHaveBeenCalledWith([1, 2]);
|
||||||
});
|
});
|
||||||
|
|
||||||
// https://github.com/ant-design/ant-design/issues/21134
|
// https://github.com/ant-design/ant-design/issues/21134
|
||||||
it('should work when checkbox is wrapped by other components', () => {
|
it('should work when checkbox is wrapped by other components', () => {
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<Checkbox.Group>
|
<Checkbox.Group>
|
||||||
<Collapse bordered={false}>
|
<Collapse bordered={false}>
|
||||||
<Collapse.Panel header="test panel">
|
<Collapse.Panel header="test panel">
|
||||||
@ -170,28 +172,31 @@ describe('CheckboxGroup', () => {
|
|||||||
</Collapse>
|
</Collapse>
|
||||||
</Checkbox.Group>,
|
</Checkbox.Group>,
|
||||||
);
|
);
|
||||||
wrapper.find('.ant-collapse-item').at(0).find('.ant-collapse-header').simulate('click');
|
|
||||||
wrapper.find('.ant-checkbox-input').at(0).simulate('change');
|
fireEvent.click(
|
||||||
expect(wrapper.find('.ant-checkbox-checked').length).toBe(1);
|
container.querySelector('.ant-collapse-item').querySelector('.ant-collapse-header'),
|
||||||
wrapper.find('.ant-checkbox-input').at(0).simulate('change');
|
);
|
||||||
expect(wrapper.find('.ant-checkbox-checked').length).toBe(0);
|
fireEvent.click(container.querySelector('.ant-checkbox-input'));
|
||||||
|
expect(container.querySelectorAll('.ant-checkbox-checked').length).toBe(1);
|
||||||
|
fireEvent.click(container.querySelector('.ant-checkbox-input'));
|
||||||
|
expect(container.querySelectorAll('.ant-checkbox-checked').length).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('skipGroup', () => {
|
it('skipGroup', () => {
|
||||||
const onChange = jest.fn();
|
const onChange = jest.fn();
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<Checkbox.Group onChange={onChange}>
|
<Checkbox.Group onChange={onChange}>
|
||||||
<Checkbox value={1} />
|
<Checkbox value={1} />
|
||||||
<Checkbox value={2} skipGroup />
|
<Checkbox value={2} skipGroup />
|
||||||
</Checkbox.Group>,
|
</Checkbox.Group>,
|
||||||
);
|
);
|
||||||
wrapper.find('.ant-checkbox-input').at(1).simulate('change');
|
fireEvent.click(container.querySelectorAll('.ant-checkbox-input')[1]);
|
||||||
expect(onChange).not.toHaveBeenCalled();
|
expect(onChange).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Table rowSelection', () => {
|
it('Table rowSelection', () => {
|
||||||
const onChange = jest.fn();
|
const onChange = jest.fn();
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<Checkbox.Group onChange={onChange}>
|
<Checkbox.Group onChange={onChange}>
|
||||||
<Table
|
<Table
|
||||||
dataSource={[{ key: 1, value: '1' }]}
|
dataSource={[{ key: 1, value: '1' }]}
|
||||||
@ -200,27 +205,32 @@ describe('CheckboxGroup', () => {
|
|||||||
/>
|
/>
|
||||||
</Checkbox.Group>,
|
</Checkbox.Group>,
|
||||||
);
|
);
|
||||||
wrapper.find('.ant-checkbox-input').at(1).simulate('change');
|
fireEvent.click(container.querySelectorAll('.ant-checkbox-input')[1]);
|
||||||
expect(onChange).not.toHaveBeenCalled();
|
expect(onChange).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get div ref', () => {
|
it('should get div ref', () => {
|
||||||
mount(
|
const refCalls = [];
|
||||||
|
render(
|
||||||
<Checkbox.Group
|
<Checkbox.Group
|
||||||
options={['Apple', 'Pear', 'Orange']}
|
options={['Apple', 'Pear', 'Orange']}
|
||||||
ref={node => {
|
ref={node => {
|
||||||
expect(node.nodeName).toBe('DIV');
|
refCalls.push(node);
|
||||||
}}
|
}}
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
|
const [mountCall] = refCalls;
|
||||||
|
expect(mountCall.nodeName).toBe('DIV');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support number option', () => {
|
it('should support number option', () => {
|
||||||
const onChange = jest.fn();
|
const onChange = jest.fn();
|
||||||
|
|
||||||
const wrapper = mount(<Checkbox.Group options={[1, 'Pear', 'Orange']} onChange={onChange} />);
|
const { container } = render(
|
||||||
|
<Checkbox.Group options={[1, 'Pear', 'Orange']} onChange={onChange} />,
|
||||||
|
);
|
||||||
|
|
||||||
wrapper.find('.ant-checkbox-input').at(0).simulate('change');
|
fireEvent.click(container.querySelector('.ant-checkbox-input'));
|
||||||
expect(onChange).toHaveBeenCalledWith([1]);
|
expect(onChange).toHaveBeenCalledWith([1]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -246,17 +256,13 @@ describe('CheckboxGroup', () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const wrapper = mount(<Demo />);
|
const { container } = render(<Demo />);
|
||||||
|
fireEvent.click(container.querySelector('.ant-checkbox-input'));
|
||||||
wrapper.find('.ant-checkbox-input').first().simulate('change');
|
|
||||||
expect(onChange).toHaveBeenCalledWith([]);
|
expect(onChange).toHaveBeenCalledWith([]);
|
||||||
wrapper.find('.ant-checkbox-input').first().simulate('change');
|
fireEvent.click(container.querySelector('.ant-checkbox-input'));
|
||||||
expect(onChange).toHaveBeenCalledWith(['length1']);
|
expect(onChange).toHaveBeenCalledWith(['length1']);
|
||||||
wrapper
|
fireEvent.change(container.querySelector('.ant-input'), { target: { value: '' } });
|
||||||
.find('.ant-input')
|
fireEvent.click(container.querySelector('.ant-checkbox-input'));
|
||||||
.first()
|
|
||||||
.simulate('change', { target: { value: '' } });
|
|
||||||
wrapper.find('.ant-checkbox-input').first().simulate('change');
|
|
||||||
expect(onChange).toHaveBeenCalledWith(['A']);
|
expect(onChange).toHaveBeenCalledWith(['A']);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -49,5 +49,5 @@ const App = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default () => <App />;
|
export default App;
|
||||||
```
|
```
|
||||||
|
@ -70,5 +70,5 @@ class App extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default () => <App />;
|
export default App;
|
||||||
```
|
```
|
||||||
|
@ -26,7 +26,7 @@ const antCheckboxEffect = new Keyframes('antCheckboxEffect', {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// ============================== Styles ==============================
|
// ============================== Styles ==============================
|
||||||
export const genCheckboxStyle: GenerateStyle<CheckboxToken> = (token, hashId) => {
|
export const genCheckboxStyle: GenerateStyle<CheckboxToken> = token => {
|
||||||
const { checkboxCls } = token;
|
const { checkboxCls } = token;
|
||||||
const wrapperCls = `${checkboxCls}-wrapper`;
|
const wrapperCls = `${checkboxCls}-wrapper`;
|
||||||
|
|
||||||
@ -197,7 +197,9 @@ export const genCheckboxStyle: GenerateStyle<CheckboxToken> = (token, hashId) =>
|
|||||||
border: `${token.controlLineWidth}px ${token.controlLineType} ${token.colorPrimary}`,
|
border: `${token.controlLineWidth}px ${token.controlLineType} ${token.colorPrimary}`,
|
||||||
borderRadius: token.controlRadius,
|
borderRadius: token.controlRadius,
|
||||||
visibility: 'hidden',
|
visibility: 'hidden',
|
||||||
animation: `${antCheckboxEffect.getName(hashId)} ${token.motionDurationSlow} ease-in-out`,
|
animationName: antCheckboxEffect,
|
||||||
|
animationDuration: token.motionDurationSlow,
|
||||||
|
animationTimingFunction: 'ease-in-out',
|
||||||
animationFillMode: 'backwards',
|
animationFillMode: 'backwards',
|
||||||
content: '""',
|
content: '""',
|
||||||
},
|
},
|
||||||
@ -241,14 +243,14 @@ export const genCheckboxStyle: GenerateStyle<CheckboxToken> = (token, hashId) =>
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ============================== Export ==============================
|
// ============================== Export ==============================
|
||||||
export function getStyle(prefixCls: string, token: FullToken<'Checkbox'>, hashId: string) {
|
export function getStyle(prefixCls: string, token: FullToken<'Checkbox'>) {
|
||||||
const checkboxToken: CheckboxToken = mergeToken<CheckboxToken>(token, {
|
const checkboxToken: CheckboxToken = mergeToken<CheckboxToken>(token, {
|
||||||
checkboxCls: `.${prefixCls}`,
|
checkboxCls: `.${prefixCls}`,
|
||||||
});
|
});
|
||||||
|
|
||||||
return [genCheckboxStyle(checkboxToken, hashId), antCheckboxEffect];
|
return [genCheckboxStyle(checkboxToken)];
|
||||||
}
|
}
|
||||||
|
|
||||||
export default genComponentStyleHook('Checkbox', (token, { prefixCls, hashId }) => [
|
export default genComponentStyleHook('Checkbox', (token, { prefixCls }) => [
|
||||||
getStyle(prefixCls, token, hashId),
|
getStyle(prefixCls, token),
|
||||||
]);
|
]);
|
||||||
|
@ -10,6 +10,7 @@ import CollapsePanel, { CollapsibleType } from './CollapsePanel';
|
|||||||
import { ConfigContext } from '../config-provider';
|
import { ConfigContext } from '../config-provider';
|
||||||
import collapseMotion from '../_util/motion';
|
import collapseMotion from '../_util/motion';
|
||||||
import { cloneElement } from '../_util/reactNode';
|
import { cloneElement } from '../_util/reactNode';
|
||||||
|
import useStyle from './style';
|
||||||
|
|
||||||
export type ExpandIconPosition = 'left' | 'right' | undefined;
|
export type ExpandIconPosition = 'left' | 'right' | undefined;
|
||||||
|
|
||||||
@ -52,6 +53,7 @@ const Collapse: CollapseInterface = props => {
|
|||||||
const { getPrefixCls, direction } = React.useContext(ConfigContext);
|
const { getPrefixCls, direction } = React.useContext(ConfigContext);
|
||||||
const { prefixCls: customizePrefixCls, className = '', bordered = true, ghost } = props;
|
const { prefixCls: customizePrefixCls, className = '', bordered = true, ghost } = props;
|
||||||
const prefixCls = getPrefixCls('collapse', customizePrefixCls);
|
const prefixCls = getPrefixCls('collapse', customizePrefixCls);
|
||||||
|
const [wrapSSR, hashId] = useStyle(prefixCls);
|
||||||
|
|
||||||
const getIconPosition = () => {
|
const getIconPosition = () => {
|
||||||
const { expandIconPosition } = props;
|
const { expandIconPosition } = props;
|
||||||
@ -90,6 +92,7 @@ const Collapse: CollapseInterface = props => {
|
|||||||
[`${prefixCls}-ghost`]: !!ghost,
|
[`${prefixCls}-ghost`]: !!ghost,
|
||||||
},
|
},
|
||||||
className,
|
className,
|
||||||
|
hashId,
|
||||||
);
|
);
|
||||||
const openMotion: CSSMotionProps = {
|
const openMotion: CSSMotionProps = {
|
||||||
...collapseMotion,
|
...collapseMotion,
|
||||||
@ -114,7 +117,7 @@ const Collapse: CollapseInterface = props => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return wrapSSR(
|
||||||
<RcCollapse
|
<RcCollapse
|
||||||
openMotion={openMotion}
|
openMotion={openMotion}
|
||||||
{...props}
|
{...props}
|
||||||
@ -123,7 +126,7 @@ const Collapse: CollapseInterface = props => {
|
|||||||
className={collapseClassName}
|
className={collapseClassName}
|
||||||
>
|
>
|
||||||
{getItems()}
|
{getItems()}
|
||||||
</RcCollapse>
|
</RcCollapse>,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ export interface CollapsePanelProps {
|
|||||||
id?: string;
|
id?: string;
|
||||||
extra?: React.ReactNode;
|
extra?: React.ReactNode;
|
||||||
collapsible?: CollapsibleType;
|
collapsible?: CollapsibleType;
|
||||||
|
children?: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CollapsePanel: React.FC<CollapsePanelProps> = props => {
|
const CollapsePanel: React.FC<CollapsePanelProps> = props => {
|
||||||
|
@ -814,7 +814,7 @@ Array [
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-select-dropdown"
|
class="ant-select-dropdown"
|
||||||
style="opacity:0;pointer-events:none"
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
|
@ -51,7 +51,7 @@ export default () => (
|
|||||||
margin-bottom: 24px;
|
margin-bottom: 24px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: #f7f7f7;
|
background: #f7f7f7;
|
||||||
border: 0px;
|
border: 0px !important;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -82,5 +82,5 @@ class Demo extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default () => <Demo />;
|
export default Demo;
|
||||||
```
|
```
|
||||||
|
@ -1,162 +1,162 @@
|
|||||||
@import '../../style/themes/index';
|
// @import '../../style/themes/index';
|
||||||
@import '../../style/mixins/index';
|
// @import '../../style/mixins/index';
|
||||||
|
|
||||||
@collapse-prefix-cls: ~'@{ant-prefix}-collapse';
|
// @collapse-prefix-cls: ~'@{ant-prefix}-collapse';
|
||||||
|
|
||||||
.@{collapse-prefix-cls} {
|
// .@{collapse-prefix-cls} {
|
||||||
.reset-component();
|
// .reset-component();
|
||||||
|
|
||||||
background-color: @collapse-header-bg;
|
// background-color: @collapse-header-bg;
|
||||||
border: @border-width-base @border-style-base @border-color-base;
|
// border: @border-width-base @border-style-base @border-color-base;
|
||||||
border-bottom: 0;
|
// border-bottom: 0;
|
||||||
border-radius: @collapse-panel-border-radius;
|
// border-radius: @collapse-panel-border-radius;
|
||||||
|
|
||||||
& > &-item {
|
// & > &-item {
|
||||||
border-bottom: @border-width-base @border-style-base @border-color-base;
|
// border-bottom: @border-width-base @border-style-base @border-color-base;
|
||||||
|
|
||||||
&:last-child {
|
// &:last-child {
|
||||||
&,
|
// &,
|
||||||
& > .@{collapse-prefix-cls}-header {
|
// & > .@{collapse-prefix-cls}-header {
|
||||||
border-radius: 0 0 @collapse-panel-border-radius @collapse-panel-border-radius;
|
// border-radius: 0 0 @collapse-panel-border-radius @collapse-panel-border-radius;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
> .@{collapse-prefix-cls}-header {
|
// > .@{collapse-prefix-cls}-header {
|
||||||
position: relative; // Compatible with old version of antd, should remove in next version
|
// position: relative; // Compatible with old version of antd, should remove in next version
|
||||||
display: flex;
|
// display: flex;
|
||||||
flex-wrap: nowrap;
|
// flex-wrap: nowrap;
|
||||||
align-items: flex-start;
|
// align-items: flex-start;
|
||||||
padding: @collapse-header-padding;
|
// padding: @collapse-header-padding;
|
||||||
color: @heading-color;
|
// color: @heading-color;
|
||||||
line-height: @line-height-base;
|
// line-height: @line-height-base;
|
||||||
cursor: pointer;
|
// cursor: pointer;
|
||||||
transition: all 0.3s, visibility 0s;
|
// transition: all 0.3s, visibility 0s;
|
||||||
|
|
||||||
.@{collapse-prefix-cls}-arrow {
|
// .@{collapse-prefix-cls}-arrow {
|
||||||
display: inline-block;
|
// display: inline-block;
|
||||||
margin-right: @margin-sm;
|
// margin-right: @margin-sm;
|
||||||
font-size: @font-size-sm;
|
// font-size: @font-size-sm;
|
||||||
vertical-align: -1px;
|
// vertical-align: -1px;
|
||||||
|
|
||||||
& svg {
|
// & svg {
|
||||||
transition: transform 0.24s;
|
// transition: transform 0.24s;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
.@{collapse-prefix-cls}-extra {
|
// .@{collapse-prefix-cls}-extra {
|
||||||
margin-left: auto;
|
// margin-left: auto;
|
||||||
}
|
// }
|
||||||
|
|
||||||
&:focus {
|
// &:focus {
|
||||||
outline: none;
|
// outline: none;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
.@{collapse-prefix-cls}-header-collapsible-only {
|
// .@{collapse-prefix-cls}-header-collapsible-only {
|
||||||
cursor: default;
|
// cursor: default;
|
||||||
.@{collapse-prefix-cls}-header-text {
|
// .@{collapse-prefix-cls}-header-text {
|
||||||
cursor: pointer;
|
// cursor: pointer;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
&.@{collapse-prefix-cls}-no-arrow {
|
// &.@{collapse-prefix-cls}-no-arrow {
|
||||||
> .@{collapse-prefix-cls}-header {
|
// > .@{collapse-prefix-cls}-header {
|
||||||
padding-left: @padding-sm;
|
// padding-left: @padding-sm;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Expand Icon right
|
// // Expand Icon right
|
||||||
&-icon-position-right {
|
// &-icon-position-right {
|
||||||
& > .@{collapse-prefix-cls}-item {
|
// & > .@{collapse-prefix-cls}-item {
|
||||||
> .@{collapse-prefix-cls}-header {
|
// > .@{collapse-prefix-cls}-header {
|
||||||
position: relative;
|
// position: relative;
|
||||||
padding: @collapse-header-padding;
|
// padding: @collapse-header-padding;
|
||||||
padding-right: @collapse-header-padding-extra;
|
// padding-right: @collapse-header-padding-extra;
|
||||||
|
|
||||||
.@{collapse-prefix-cls}-arrow {
|
// .@{collapse-prefix-cls}-arrow {
|
||||||
position: absolute;
|
// position: absolute;
|
||||||
top: 50%;
|
// top: 50%;
|
||||||
right: @padding-md;
|
// right: @padding-md;
|
||||||
left: auto;
|
// left: auto;
|
||||||
margin: 0;
|
// margin: 0;
|
||||||
transform: translateY(-50%);
|
// transform: translateY(-50%);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-content {
|
// &-content {
|
||||||
color: @text-color;
|
// color: @text-color;
|
||||||
background-color: @collapse-content-bg;
|
// background-color: @collapse-content-bg;
|
||||||
border-top: @border-width-base @border-style-base @border-color-base;
|
// border-top: @border-width-base @border-style-base @border-color-base;
|
||||||
|
|
||||||
& > &-box {
|
// & > &-box {
|
||||||
padding: @collapse-content-padding;
|
// padding: @collapse-content-padding;
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-hidden {
|
// &-hidden {
|
||||||
display: none;
|
// display: none;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-item:last-child {
|
// &-item:last-child {
|
||||||
> .@{collapse-prefix-cls}-content {
|
// > .@{collapse-prefix-cls}-content {
|
||||||
border-radius: 0 0 @collapse-panel-border-radius @collapse-panel-border-radius;
|
// border-radius: 0 0 @collapse-panel-border-radius @collapse-panel-border-radius;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-borderless {
|
// &-borderless {
|
||||||
background-color: @collapse-header-bg;
|
// background-color: @collapse-header-bg;
|
||||||
border: 0;
|
// border: 0;
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-borderless > &-item {
|
// &-borderless > &-item {
|
||||||
border-bottom: 1px solid @border-color-base;
|
// border-bottom: 1px solid @border-color-base;
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-borderless > &-item:last-child,
|
// &-borderless > &-item:last-child,
|
||||||
&-borderless > &-item:last-child &-header {
|
// &-borderless > &-item:last-child &-header {
|
||||||
border-radius: 0;
|
// border-radius: 0;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// hide the last border-bottom in borderless mode
|
// // hide the last border-bottom in borderless mode
|
||||||
&-borderless > &-item:last-child {
|
// &-borderless > &-item:last-child {
|
||||||
border-bottom: 0;
|
// border-bottom: 0;
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-borderless > &-item > &-content {
|
// &-borderless > &-item > &-content {
|
||||||
background-color: transparent;
|
// background-color: transparent;
|
||||||
border-top: 0;
|
// border-top: 0;
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-borderless > &-item > &-content > &-content-box {
|
// &-borderless > &-item > &-content > &-content-box {
|
||||||
padding-top: 4px;
|
// padding-top: 4px;
|
||||||
}
|
// }
|
||||||
|
|
||||||
&-ghost {
|
// &-ghost {
|
||||||
background-color: transparent;
|
// background-color: transparent;
|
||||||
border: 0;
|
// border: 0;
|
||||||
> .@{collapse-prefix-cls}-item {
|
// > .@{collapse-prefix-cls}-item {
|
||||||
border-bottom: 0;
|
// border-bottom: 0;
|
||||||
> .@{collapse-prefix-cls}-content {
|
// > .@{collapse-prefix-cls}-content {
|
||||||
background-color: transparent;
|
// background-color: transparent;
|
||||||
border-top: 0;
|
// border-top: 0;
|
||||||
> .@{collapse-prefix-cls}-content-box {
|
// > .@{collapse-prefix-cls}-content-box {
|
||||||
padding-top: 12px;
|
// padding-top: 12px;
|
||||||
padding-bottom: 12px;
|
// padding-bottom: 12px;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
& &-item-disabled > &-header {
|
// & &-item-disabled > &-header {
|
||||||
&,
|
// &,
|
||||||
& > .arrow {
|
// & > .arrow {
|
||||||
color: @disabled-color;
|
// color: @disabled-color;
|
||||||
cursor: not-allowed;
|
// cursor: not-allowed;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
@import './rtl';
|
// @import './rtl';
|
||||||
|
@ -1,2 +1,246 @@
|
|||||||
import '../../style/index.less';
|
// import '../../style/index.less';
|
||||||
import './index.less';
|
// import './index.less';
|
||||||
|
|
||||||
|
// deps-lint-skip-all
|
||||||
|
import { CSSInterpolation } from '@ant-design/cssinjs';
|
||||||
|
import {
|
||||||
|
GenerateStyle,
|
||||||
|
resetComponent,
|
||||||
|
genComponentStyleHook,
|
||||||
|
mergeToken,
|
||||||
|
FullToken,
|
||||||
|
} from '../../_util/theme';
|
||||||
|
|
||||||
|
type CollapseToken = FullToken<'Collapse'> & {
|
||||||
|
collapseContentBg: string;
|
||||||
|
collapseContentPadding: number;
|
||||||
|
collapseHeaderBg: string;
|
||||||
|
collapseHeaderPadding: string;
|
||||||
|
collapseHeaderPaddingExtra: number;
|
||||||
|
collapsePanelBorderRadius: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const genBaseStyle: GenerateStyle<CollapseToken> = token => {
|
||||||
|
const {
|
||||||
|
componentCls,
|
||||||
|
collapseContentBg,
|
||||||
|
collapseContentPadding,
|
||||||
|
collapseHeaderBg,
|
||||||
|
collapseHeaderPadding,
|
||||||
|
collapseHeaderPaddingExtra,
|
||||||
|
collapsePanelBorderRadius,
|
||||||
|
|
||||||
|
controlLineWidth,
|
||||||
|
controlLineType,
|
||||||
|
colorBorder,
|
||||||
|
colorText,
|
||||||
|
colorTextHeading,
|
||||||
|
colorTextDisabled,
|
||||||
|
lineHeight,
|
||||||
|
marginSM,
|
||||||
|
padding,
|
||||||
|
paddingSM,
|
||||||
|
fontSizeSM,
|
||||||
|
} = token;
|
||||||
|
|
||||||
|
const borderBase = `${controlLineWidth}px ${controlLineType} ${colorBorder}`;
|
||||||
|
|
||||||
|
return {
|
||||||
|
[componentCls]: {
|
||||||
|
...resetComponent(token),
|
||||||
|
backgroundColor: collapseHeaderBg,
|
||||||
|
border: borderBase,
|
||||||
|
borderBottom: 0,
|
||||||
|
borderRadius: `${collapsePanelBorderRadius}px`,
|
||||||
|
|
||||||
|
[`&-rtl`]: {
|
||||||
|
direction: 'rtl',
|
||||||
|
},
|
||||||
|
|
||||||
|
[`& > ${componentCls}-item`]: {
|
||||||
|
borderBottom: borderBase,
|
||||||
|
[`&:last-child`]: {
|
||||||
|
[`
|
||||||
|
&,
|
||||||
|
& > ${componentCls}-header`]: {
|
||||||
|
borderRadius: `0 0 ${collapsePanelBorderRadius}px ${collapsePanelBorderRadius}px`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`> ${componentCls}-header`]: {
|
||||||
|
position: 'relative', // Compatible with old version of antd, should remove in next version
|
||||||
|
display: 'flex',
|
||||||
|
flexWrap: 'nowrap',
|
||||||
|
alignItems: 'flex-start',
|
||||||
|
padding: collapseHeaderPadding,
|
||||||
|
color: colorTextHeading,
|
||||||
|
lineHeight,
|
||||||
|
cursor: 'pointer',
|
||||||
|
transition: `all 0.3s, visibility 0s`,
|
||||||
|
|
||||||
|
[`${componentCls}-arrow`]: {
|
||||||
|
display: 'inline-block',
|
||||||
|
marginInlineEnd: marginSM,
|
||||||
|
fontSize: fontSizeSM,
|
||||||
|
// FIXME
|
||||||
|
verticalAlign: '-1px',
|
||||||
|
|
||||||
|
[`${componentCls}-rtl &`]: {},
|
||||||
|
|
||||||
|
[`& svg`]: {
|
||||||
|
// FIXME
|
||||||
|
transition: 'transform 0.24s',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-extra`]: {
|
||||||
|
marginInlineStart: 'auto',
|
||||||
|
},
|
||||||
|
|
||||||
|
[`&:focus`]: {
|
||||||
|
outline: 'none',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-header-collapsible-only`]: {
|
||||||
|
cursor: 'default',
|
||||||
|
|
||||||
|
[`${componentCls}-header-text`]: {
|
||||||
|
cursor: 'pointer',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`&${componentCls}-no-arrow`]: {
|
||||||
|
[`> ${componentCls}-header`]: {
|
||||||
|
paddingInlineStart: paddingSM,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`&-icon-position-right`]: {
|
||||||
|
[`& > ${componentCls}-item `]: {
|
||||||
|
[`> ${componentCls}-header`]: {
|
||||||
|
position: 'relative',
|
||||||
|
padding: collapseHeaderPadding,
|
||||||
|
paddingInlineEnd: collapseHeaderPaddingExtra,
|
||||||
|
|
||||||
|
[`${componentCls}-arrow`]: {
|
||||||
|
position: 'absolute',
|
||||||
|
top: '50%',
|
||||||
|
insetInlineEnd: padding,
|
||||||
|
insetInlineStart: 'auto',
|
||||||
|
margin: 0,
|
||||||
|
transform: 'translateY(-50%)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-content`]: {
|
||||||
|
color: colorText,
|
||||||
|
backgroundColor: collapseContentBg,
|
||||||
|
borderTop: borderBase,
|
||||||
|
|
||||||
|
[`& > ${componentCls}-content-box`]: {
|
||||||
|
padding: collapseContentPadding,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`&-hidden`]: {
|
||||||
|
display: 'none',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-item:last-child`]: {
|
||||||
|
[`> ${componentCls}-content`]: {
|
||||||
|
borderRadius: `0 0 ${collapsePanelBorderRadius}px ${collapsePanelBorderRadius}px`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`& ${componentCls}-item-disabled > ${componentCls}-header`]: {
|
||||||
|
[`
|
||||||
|
&,
|
||||||
|
& > .arrow
|
||||||
|
`]: {
|
||||||
|
color: colorTextDisabled,
|
||||||
|
cursor: 'not-allowed',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`&-ghost`]: {
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
border: 0,
|
||||||
|
[`> ${componentCls}-item`]: {
|
||||||
|
borderBottom: 0,
|
||||||
|
[`> ${componentCls}-content`]: {
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
border: 0,
|
||||||
|
[`> ${componentCls}-content-box`]: {
|
||||||
|
// FIXME
|
||||||
|
paddingTop: 12,
|
||||||
|
paddingBottom: 12,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const genBorderlessStyle: GenerateStyle<CollapseToken> = token => {
|
||||||
|
const {
|
||||||
|
componentCls,
|
||||||
|
collapseHeaderBg,
|
||||||
|
|
||||||
|
colorBorder,
|
||||||
|
} = token;
|
||||||
|
|
||||||
|
return {
|
||||||
|
[`${componentCls}-borderless`]: {
|
||||||
|
backgroundColor: collapseHeaderBg,
|
||||||
|
border: 0,
|
||||||
|
|
||||||
|
[`> ${componentCls}-item`]: {
|
||||||
|
borderBottom: `1px solid ${colorBorder}`,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`
|
||||||
|
> ${componentCls}-item:last-child,
|
||||||
|
> ${componentCls}-item:last-child ${componentCls}-header
|
||||||
|
`]: {
|
||||||
|
borderRadius: 0,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`> ${componentCls}-item:last-child`]: {
|
||||||
|
borderBottom: 0,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`> ${componentCls}-item > ${componentCls}-content`]: {
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
borderTop: 0,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`> ${componentCls}-item > ${componentCls}-content > ${componentCls}-content-box`]: {
|
||||||
|
// FIXME
|
||||||
|
paddingTop: 4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const genCollapseStyle: GenerateStyle<CollapseToken> = (
|
||||||
|
token: CollapseToken,
|
||||||
|
): CSSInterpolation => [genBaseStyle(token), genBorderlessStyle(token)];
|
||||||
|
|
||||||
|
export default genComponentStyleHook('Collapse', token => {
|
||||||
|
const collapseToken = mergeToken<CollapseToken>(token, {
|
||||||
|
collapseContentBg: token.colorBgComponent,
|
||||||
|
collapseContentPadding: token.padding,
|
||||||
|
collapseHeaderBg: token.colorBgComponentSecondary,
|
||||||
|
collapseHeaderPadding: `${token.paddingSM}px ${token.padding}px`,
|
||||||
|
// FIXME
|
||||||
|
collapseHeaderPaddingExtra: 40,
|
||||||
|
collapsePanelBorderRadius: token.radiusBase,
|
||||||
|
});
|
||||||
|
|
||||||
|
return [genCollapseStyle(collapseToken)];
|
||||||
|
});
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user