merge master

This commit is contained in:
zombiej 2019-12-25 19:09:17 +08:00
commit 9e8ce489e9
107 changed files with 102955 additions and 222 deletions

View File

@ -1,3 +1,3 @@
{
"sandboxes": ["wk04r016q8"]
"sandboxes": ["antd-reproduction-template-6e93z"]
}

View File

@ -1,6 +1,5 @@
components/**/*.js
components/**/*.jsx
components/*/__tests__/type.tsx
!components/*/__tests__/**/*.js
!components/*/demo/*
!.*.js

View File

@ -56,6 +56,7 @@ const eslintrc = {
'jsx-a11y/anchor-has-content': 0,
'jsx-a11y/click-events-have-key-events': 0,
'jsx-a11y/anchor-is-valid': 0,
'jsx-a11y/no-noninteractive-element-interactions': 0,
'comma-dangle': ['error', 'always-multiline'],
'react/jsx-filename-extension': 0,
'react/state-in-constructor': 0,
@ -87,6 +88,7 @@ const eslintrc = {
'react/static-property-placement': 0,
'jest/no-test-callback': 0,
'jest/expect-expect': 0,
'import/extensions': 0,
},
globals: {
gtag: true,

View File

@ -19,9 +19,11 @@ jobs:
run: npm run predeploy
- name: deploy
uses: peaceiris/actions-gh-pages@v2.5.0
uses: peaceiris/actions-gh-pages@v2
env:
ACTIONS_DEPLOY_KEY: ${{ secrets.ACCESS_TOKEN }}
ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
# PERSONAL_TOKEN: ${{ secrets.PERSONAL_TOKEN }}
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PUBLISH_BRANCH: gh-pages
PUBLISH_DIR: ./_site
with:

19
.github/workflows/lighthouse-ci.yml vendored Normal file
View File

@ -0,0 +1,19 @@
name: Lighthouse
on: push
jobs:
lighthouse:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Audit URLs using Lighthouse
uses: treosh/lighthouse-ci-action@v2
with:
urls: |
https://ant.design
https://ant.design/docs/react/introduce-cn
https://ant.design/components/button-cn
- name: Save results
uses: actions/upload-artifact@v1
with:
name: lighthouse-results
path: '.lighthouseci' # This will save the Lighthouse results as .json files

View File

@ -31,7 +31,7 @@ module.exports = {
'!components/*/style/index.tsx',
'!components/style/index.tsx',
'!components/*/locale/index.tsx',
'!components/*/__tests__/**/type.tsx',
'!components/*/__tests__/type.test.tsx',
'!components/**/*/interface.{ts,tsx}',
],
transformIgnorePatterns,

View File

@ -2,17 +2,26 @@
17073025 <17073025@cnsuning.com>
282159468 <282159468@qq.com>
778758944 <778758944@qq.com>
Aaron Cawte <aaron@bbncreative.co>
Aaron Planell López <aaronplanell@gmail.com>
Aditya Padhi <aditya.padhi@outlook.com>
Adrian Dimitrov <dimitrov.adrian@gmail.com>
Ahmad Abdelaziz <ahmad.abdelaziz@robustastudio.com>
Ahmed AlSammany <ahmed.alsammany@incorta.com>
Aidin <aidin.dadashzadeh@gmail.com>
Aiello <770540123@qq.com>
Alan Braithwaite <asbraithwaite@gmail.com>
Albert Zheng <lisong.zheng@gmail.com>
Albert 理斯特 <shuaizhexu@gmail.com>
Alberto Marchetti <cmaster11@gmail.com>
Aleck Landgraf <aleck.landgraf@gmail.com>
Aleksandr Chernokondratenko <etherreals777@gmail.com>
Alex Simons <alexsimons9999@gmail.com>
Alexander <labriko@yandex.ru>
Alexander Anpleenko <vaeum@yandex.com>
Alexander Kachkaev <alexander@kachkaev.ru>
Alexander Suevalov <suevalov.work@gmail.com>
Alexander.Kosov <Alexander.Kosov@nexign-systems.com>
Alexandre Kirszenberg <a.kirszenberg@gmail.com>
Alexey Yakovlev <yallie@yandex.ru>
Alfred Qiu <sc941203@gmail.com>
@ -28,21 +37,32 @@ Andrew Shearer <andrew@ashearer.com>
Andrey G <plandem@gmail.com>
Andrzej Dybionka <andrzej@arabel.la>
André <mazoni.andre@gmail.com>
Andrés <andresin87@gmail.com>
Ankit Babbar <ankit.babbar@valuebound.com>
Aobo Yang <yangaobo@gmail.com>
Ardo Kusuma <ardo@uber.com>
Arnab Sen <arnabsen@gmail.com>
Arthur Denner Oliveira Santos <arthurdenner7@gmail.com>
Artin <lengthmin@gmail.com>
Arvin Xu <arvinx@foxmail.com>
Ash Kumar <kumar.ashwin@outlook.com>
Ashot Mnatsakanyan <mnatsakanyan.ashot@gmail.com>
Aymen Bouchekoua <bouchekoua.aymen@gmail.com>
BK Heleth <bon.hoo@hotmail.com>
Babajide Fowotade <jide.b.tade@gmail.com>
Barry <barry.yansh@gmail.com>
Bartek <bartek.kozera@gmail.com>
Ben Callaway <me@bencallaway.com>
Benedikt Franke <benedikt@franke.tech>
Benjamin Amelot <bam@activeviam.com>
Benjamin Kniffler <bkniffler@me.com>
Benjy Cui <benjytrys@gmail.com>
Benoît Latinier <benoit@latinier.fr>
Bernie <bernie.wangbj@gmail.com>
Bestie <lucientown@outlook.com>
Bhavesh Chowdhury <bhaveshch20@gmail.com>
Bilal Sirazitdinov <bilalsir@yandex.ru>
Bill Searle <billsearle@gmail.com>
Bill Sheikh <bilawals22@gmail.com>
Bo Chen <bochen2014@yahoo.com>
Bolun Zhang <rzhangbolun@gmail.com>
@ -61,9 +81,11 @@ Cam Song <neosoyn@gmail.com>
Camol <kwwnjujlc@sina.com>
Cang Ta <hoksilato176@gmail.com>
Canwen Xu <canwenxu@126.com>
Carlos Coves Prieto <carlos.coves@interacso.com>
Carter Feldman <carter@carter.at>
Catalin Miron <mironcatalin@gmail.com>
Cee Cirno <i@cee.moe>
Cemre Mengu <cemremengu@gmail.com>
Chandler Moisen <chandlermoisen@gmail.com>
Chang Wang <cheapsteak@gmail.com>
Charles Covey-Brandt <chazcb@gmail.com>
@ -75,8 +97,10 @@ Chris Kelly <cjke.7777@gmail.com>
ChrisFan <chris.fan.dev@gmail.com>
Christian <chr.vadala@gmail.com>
Christian Vadalà <chr.vadala@gmail.com>
Christophe Hurpeau <christophe@hurpeau.com>
Christopher Deutsch <cd@cdeutsch.com>
Chuang Yu <cyu9960@gmail.com>
Chuck <wfhtzcf@gmail.com>
Claudio Restifo <claudio.restifo@gmail.com>
Cody Chan <int64ago@gmail.com>
Colton Pierson <colton@coltonpierson.com>
@ -89,21 +113,32 @@ Daewoong Moon <wiziple@gmail.com>
Damian Green <damian.green@microlease.com>
Damian Green <damian@gcoders.com>
Dan Minshew <ofenixculpa@gmail.com>
Dana Janoskova <dana.janoskova@accenture.com>
Dane David <dndavid102@gmail.com>
Daniel Chang <danielchang2022@u.northwestern.edu>
Daniel Gomez <dgomez@orangeloops.com>
Daniel Harrison <daniel.equiknox@gmail.com>
Danny Hoower Antonio Viasus Avila <danjavia@gmail.com>
Daphne Won <daphne.won@shopee.com>
Daqi Song <dqaria@gmail.com>
Darren Poon <dyhpoon@gmail.com>
David Broder-Rodgers <david.broder-rodgers@softwire.com>
David Hatten <dhatten@covermymeds.com>
David Schneider <davschne@gmail.com>
Dean van Niekerk <deanvniekerk@gmail.com>
DengYun <tdzl2003@gmail.com>
Denis <shumkovdenis@gmail.com>
DiamondYuan <541832074@qq.com>
DiamondYuan <admin@diamondyuan.com>
Dimitri Mitropoulos <dimitrimitropoulos@gmail.com>
Dmitriy <dimusig@gmail.com>
Dmitriy Mironov <dima.dev01@gmail.com>
Dmitry Bolotin <bolotin.dmitriy@gmail.com>
Dmitry Gladkikh <abdurahmanus@gmail.com>
Dmitry Guryev <dmitry.gurjev@gmail.com>
Dmitry Manannikov <email@slonoed.net>
Dmitry Snegirev <rikkitp@gmail.com>
Dmitry Tikhomirov <tikhomirov@element-soft.com>
Dorian <dorian@doma.io>
DosLin <doslino@gmail.com>
Douglas Mason <Demasonjr@gmail.com>
@ -118,34 +153,44 @@ Eden Wang <yociduo@vip.qq.com>
Eduardo Ludi <eduludi@gmail.com>
Edward <7047924@qq.com>
Egor Yurtaev <yurtaev.egor@gmail.com>
Eldar Mustafaiev <eldar.mustafaiev@gmail.com>
Eli White <github@eli-white.com>
Emerson Laurentino <emersonlaurentino@hotmail.com>
Emma <sima.zhang1990@gmail.com>
Ender Lee <chnliquan@163.com>
Eric <84263800@qq.com>
Eric Celeste <efc@clst.org>
Eric Turriff <eric.turriff@gmail.com>
Erwann Mest <m+github@kud.io>
Eusen <179530591@qq.com>
Evgeny Kuznetsov <jackk@ya.ru>
Eward Song <eward.song@gmail.com>
Federico Marcos <marcosfede@gmail.com>
Ferdi Koomen <info@madebyferdi.com>
Fergus Leung <fergusleung96@gmail.com>
Fernando Giarritiello <fgiarritiello@gmail.com>
Florian Orpelière <florian.orpeliere@gmail.com>
Flynn <li.fulin@foxmail.com>
For177 <mengqiang.q@gmail.com>
Frezc <Frezcw@gmail.com>
Gabe Medrash <gabeme@alleninstitute.org>
Gabriel Nunes <gabriel@multiverso.me>
GalenWong <wonggalen1999@gmail.com>
Gao Jiangmiao <tolbkni@gmail.com>
Gautier <rollingautier2@gmail.com>
Geoff Holden <geoff@brightloudnoise.com>
George Gray <george@ummodesign.com>
Gin-X <xcbwyys@hotmail.com>
Go7hic <gtfx0209@qq.com>
Goh Zhao Yang <austinzy@airasia.com>
Graeme Yeates <gyeates@clearpath.ai>
Graeme Yeates <yeatesgraeme@gmail.com>
Grant Klinsing <gklinsing@gmail.com>
Gray Choi <gray.choi.1988@gmail.com>
Guan Hao <raptium@gmail.com>
Guan Yu Pan (Jacky) <jackypan1989@gmail.com>
Guichi Zhao <zgc910619@gmail.com>
Hami Abdi <abdih@users.noreply.github.com>
HJin.me <hjin.me@gmail.com>
Hai Phan Nguyen <pnghai@gmail.com>
Haibin Yu <haibin.yu@oceanwing.com>
@ -155,12 +200,18 @@ Hanz Luo <lhz0516@gmail.com>
Harlan <luoxwen@gmail.com>
HarlanLuo <luoxwen@gmail.com>
Haroen Viaene <fingebimus@me.com>
Harry.Hou <harry.hou@ringcentral.com>
Harshit Mehrotra <harshitmehrotra@hotmail.com>
He Linming <hlm52pk@163.com>
Heaven <ne_smalltown@163.com>
Henri Normak <henri.normak@gmail.com>
HeskeyBaozi <hezhiyu233@foxmail.com>
HiddenMan <1196089730@qq.com>
Hieu Ho <hieu.ho.le@lazada.com>
Hieu Pham <phthhieu@gmail.com>
Higor Araújo dos Anjos <higor.araujo.anjos@gmail.com>
Hsuan Lee <HsuanGM@gmail.com>
Hsuan Lee <hsuangm@gmail.com>
Hubert Argasinski <argasinski.hubert@gmail.com>
Hughen <446370503@163.com>
Hugo LEHMANN <shogi31@gmail.com>
@ -168,12 +219,16 @@ Igor <nemytyshew@yandex.ru>
Igor G <i.gaidai4uk@gmail.com>
Ilan <hasanovtk@gmail.com>
Ilan Hasanov <hasanovtk@gmail.com>
Ilya Bondarenko <bondarenko.ik@gmail.com>
ImJoeHs <865439601@qq.com>
Inclined.Z <zjq0717@163.com>
Infinity <305870677@qq.com>
Inian <inian1234@gmail.com>
Ivan <ivan.pecharitsa@gmail.com>
Ivan Kravets <me@ikravets.com>
Ivan Trofimov <ivan@trofimov.link>
Ivo Stratev <ivo.stratev.tues@gmail.com>
Jack <jacklee82814@gmail.com>
Jack Hsieh <jack@egenware.com>
Jack Lo <jack-lo@foxmail.com>
Jack Works <zjwpeter@gmail.com>
@ -182,19 +237,30 @@ Jacques Kvam <jwkvam@gmail.com>
JaePil Jung <jjp5023@gmail.com>
Jake Richards <jake.richards@genesys.com>
James <james@schoolshape.com>
James Tsang <wentao_zeng1@163.com>
JamesYin <elantion@gmail.com>
Jaroslav Bereza <github.com@bereza.cz>
Jarvis1010 <travis.mair@gmail.com>
Jason <ceocjy@vip.qq.com>
Jason Chen <ceocjy@vip.qq.com>
Jason Chung <shiningjason1989@gmail.com>
Jason Yin <yinjiangsheng@gmail.com>
Jean-Luc Sorak <jlsorak@icloud.com>
Jeffrey Carl Faden <jeffreyatw@gmail.com>
Jelle de Jong <jelle@hoest.nl>
Jennie <jennie.ji@hotmail.com>
JeromeLin <jerome.lin@zhongan.com>
Jerry Bendy <jerry@icewingcc.com>
Jesper We <jesper@journeyman.se>
Jiabin Peng <png.inside@gmail.com>
Jialei <jialeicui@126.com>
Jiawei Huang <hjiawei@gmail.com>
Jieraaa <842533841@qq.com>
Jin ZHANG <jz.zhangjin@gmail.com>
JinXin <m18508218948@163.com>
Jing Ma <mjingm87@qq.com>
Jingsong Gao <kingsongao1221@gmail.com>
Jinke Li <1359518268@qq.com>
Jinxuan Zhu <zhujinxuan@gmail.com>
Joao Rabelo <jrabelo@tech6.com.br>
Joe <qiaolibo@126.com>
@ -202,90 +268,124 @@ Joe Hsu <jhsu.x1@gmail.com>
Johannes Loewe <johannes@loewe.pm>
John Johnson III <john@johnjohnson.cc>
John Nguyen <jtnguyen236@gmail.com>
Johnsen <jiajunzhou1994@163.com>
Jonatas Walker <jonataswalker@gmail.com>
Jonathan Lee <1150974628@qq.com>
Jonny Buchanan <jonathan.buchanan@gmail.com>
Jordan Hornblow <jordan@jch254.com>
Josue Peralta <jperal77@gmail.com>
Josué <ujosuegt@outlook.com>
JribiBelhassen <belha9inzaghi@gmail.com>
JuFeng Zhang <zjffun@gmail.com>
Juan Carlos Lloret H <juan.carlos.lloret@lansweeper.com>
Juan Rodrigo Venegas Boesch <jrvboesch@gmail.com>
Julia Passynkova <ipassynk@hotmail.com>
Julien Confetti <julien.confetti@ulg.ac.be>
Junyu Zhan <irrigator@yeah.net>
Juraj Carnogursky <durisvk2@gmail.com>
Justin Reich <reich.justin@gmail.com>
Kaien Liao <liaokaien@gmail.com>
Kamal Mahmudi <kamalmahmudi@yahoo.co.id>
Kasra Bigdeli <kasra85@gmail.com>
Kelvin Chu <chubillkelvin@gmail.com>
Kenaniah Cerny <kenaniah@gmail.com>
Kenneth Luján Rosas <elgenio.03@gmail.com>
Kenneth Truong <kenneth.e.truong@gmail.com>
KentonYu <975853613@qq.com>
Kevin Ivan <info@kevinivan.com>
Kevin Wang <gumtree200@gmail.com>
Kevinaskin <kevinaskin@minus.live>
KgTong <kgtong1992@gmail.com>
Khaled <k.khalil.94@gmail.com>
Khalifa Lame <khalibloo@gmail.com>
Kian <kian@vsu.cc>
Kieren <kierenveerapen94@gmail.com>
Kiho · Cham <monkindey@163.com>
Kim, Harim <harimkims@gmail.com>
Kimmo Saari <kimmo.saari@compile.fi>
Kimmo Saari <kimmo.saari@revolt.fi>
Kirill Alexander Khalitov <voronar@gmail.com>
Kirill Stiopin <kirill.stiopin@hotmail.com>
Knacktus <knacktus@gmail.com>
Kodai Nakamura <kodai.nakamura.215@gmail.com>
Konrad Machlowski <konrad.machlowski@gmail.com>
Kyle Kelley <rgbkrk@gmail.com>
Kyle Rosenberg <kyle.rosenberg@gmail.com>
LLinFan- <catfoursi@qq.com>
LT246-VINHNPH\vinhnph <vinhnph@blockpass.org>
Laith <laith24@gmail.com>
Larry Laski <larry.laski@gmail.com>
LaySent <laysent@gmail.com>
LeeHarlan <709886167@qq.com>
LeezQ <lizhenq2009@gmail.com>
Leo <clinyong@gmail.com>
Leon Koole <leon@koole.io>
Leon Shi <superRaytin@163.com>
Leon Shi <superRaytin@gmail.com>
Li Chao <rftstars@qq.com>
LilyWakana <873435892@qq.com>
Liming Jin <jinlm@knownsec.com>
Liu Ya <liuya54892@gmail.com>
Liu Yang <zation1@gmail.com>
LongYinan <lynweklm@gmail.com>
Lucien Lee <lkiral7903@gmail.com>
Ludwig Bäcklund <ludli839@student.liu.se>
Lyndon001 <lld207@126.com>
M Mitchell <mail@megmitchell.ca>
MG12 <wuzhao.mail@gmail.com>
Ma Tianxiao <matx2215@outlook.com>
Maciej Czekaj <natanielcz@gmail.com>
Madis Väin <madisvain@gmail.com>
Maksym Mosyura <wmornotwm@gmail.com>
Malven <marcusalven@gmail.com>
Manjit Kumar <manjit1727@gmail.com>
Manweill <mic.liangwenwei@foxmail.com>
MaoYiWei <137308365@qq.com>
Marcel Jackwerth <marceljackwerth@gmail.com>
Marcela Bomfim <mbomfim@live.com>
Marcio Pamplona <marciopamplona79@gmail.com>
Marco Afonso <mafonso333@gmail.com>
Marcus Bransbury <marcus.bransbury@gmail.com>
Marius Ileana <visvadw@gmail.com>
Mars Wong <marswong618@gmail.com>
Marshall Chen <Juniors.fei@gmail.com>
Martin Cermak <crudo@crudo.cz>
Martin Litvaj <kamahl19@gmail.com>
Martin Novák <martinnovak@outlook.com>
Mathew <khayaanimations@gmail.com>
Mathieu Anderson <anderson@talon.one>
Matias Orellana <morellan@gmail.com>
Matt Lein <matt.lein@code42.com>
Max <maksym.mosyura@kruschecompany.com>
Maximilian Meyer <Maximilian.Meyer@br.de>
Meck <yesmeck@gmail.com>
Meck Zhu <yesmeck@gmail.com>
MeiLin <postget.me@gmail.com>
Meow-z <372086270@qq.com>
Miaow <i@zfeng.net>
Michael Adams <mtadams007@gmail.com>
Michael Krog <mic@apaq.dk>
Michael Salaverry <barakplasma@gmail.com>
Michael Salaverry <michaels@axonize.com>
Michael Wang <ylzcylx@gmail.com>
Michal Pekar <pekac45@gmail.com>
Michalis Macheras <diodosier@gmail.com>
Michelle Zhang <michelle.chsy@gmail.com>
Mikasa33 <mikasa33@qq.com>
Min <dicklwm@163.com>
MinJeong Kim <min7859@gmail.com>
MinYuan <s1124yy@gmail.com>
Ming Hann <eldy8888@gmail.com>
Minqi Pan <pmq2001@gmail.com>
Minsung Ryu <ryums0227@gmail.com>
Minwei Xu <faceswilliam@gmail.com>
Mitchell Demler <mitchell.demler@harcourts.net>
Mohamed Seada <mohamed.seada.1994@gmail.com>
Mohammad Faisal <faisalhmohd@gmail.com>
Mohan Ban <banmohan@outlook.com>
Mounish Sai <pvsmounish@gmail.com>
Mr.Tone <vector@malubei.com>
MrHeer <hlm52pk@163.com>
MuYu <mr.muzea@gmail.com>
Mário Gonçalves <mario.mc.goncalves@gmail.com>
Nathan Broadbent <git@ndbroadbent.com>
@ -298,6 +398,8 @@ Nekron <nekron.hyt@gmail.com>
Neverland <chenjiahan@buaa.edu.cn>
Nico <nicolas@freddelacompta.com>
Nidhi Agarwal <nidhi.agarwal@zomato.com>
Nihal Saxena <saxenanihal95@gmail.com>
Nikitenkova <katrin_7nes7@mail.ru>
Niko Autio <niko.autio@fenten.fi>
Nikolay <veseliy07@gmail.com>
Nikolay Solovyov <i@mr-ozio.ru>
@ -306,8 +408,10 @@ Nimo <nimo.jser@gmail.com>
Nishant Arora <na.nishantarora@gmail.com>
Nokecy <Nokecy@163.com>
OAwan <georgio.wan@gmail.com>
Olaniyi Philip Ojeyinka <olaniyiojeyinka@gmail.com>
Oleg Kuzava <olegkuzava@gmail.com>
Oleksandr Kovalchuk <me.olexandr.kovalchuk@gmail.com>
Olivier Louvignes <olivier@mg-crea.com>
Ooi Yee Wei <ywooi@yahoo.com>
Open Next <opennext@126.com>
Oren Kosto <oren@panda-os.com>
@ -320,16 +424,20 @@ Peter <usstpeter@gmail.com>
Peter Berg <atticusberg@gmail.com>
Phanupong Janthapoon <panupong.jtp@gmail.com>
Philip Oliver <philipodev@gmail.com>
Phyllis <escapiststupor@gmail.com>
Pierre <pierre@bazoge.com>
Pierre Neter <pierreneter@gmail.com>
Piotr Monwid-Olechnowicz <hasparus@gmail.com>
Piper Chester <piperchester@gmail.com>
Pixy Yuan <pixy.bupt@gmail.com>
Pooya Parsa <pyapar@gmail.com>
Pyiner <lijiuyang1992@gmail.com>
Pyroboomka <qwaarty@mail.ru>
QC-L <github@liqichang.com>
Qhan W <whenhan@foxmail.com>
Qiaosen Huang <joesonw@gmail.com>
Qingrong Ke <keqingrong1992@gmail.com>
Radomir Skrzepij <zyziu10@gmail.com>
Rafael Cosman <rafaelcosman@alumni.stanford.edu>
Rahul Gurung <gurungrahul2@gmail.com>
Rallets <rallet@rallets.com>
@ -338,47 +446,70 @@ Ran Byron <ranbena@gmail.com>
Randy <randypriv@gmail.com>
RaoHai <surgesoft@gmail.com>
Raphael Chauveau <raph.chauveau@gmail.com>
Ray Booysen <ray.booysen@baikalmkt.com>
Ray Booysen <raybooysen@gmail.com>
Rayron Victor <rayronvictor@gmail.com>
Reed Sun <superreedsun@gmail.com>
Regan Langford <regan.reihana@gmail.com>
Renovate Bot <bot@renovateapp.com>
Rex <zhangzilong.zzl@163.com>
Ricardo Raphael Joson <rrjoson08@gmail.com>
Richard D. Worth <rdworth@gmail.com>
Rick Zhou <rinick@gmail.com>
Robert Wilkinson <wilkinson.robert.a@gmail.com>
Rodrigo Ehlers <rodrigoehlers@outlook.com>
Rohan Malhotra <rohan.root@gmail.com>
Rongjian Zhang <pd4d10@gmail.com>
Rrrandom <emanonhere@gmail.com>
RunningCoderLee <sprint_l@aliyun.com>
Rustin <rustin.liu@gmail.com>
Rustin-Liu <rustin.liu@gmail.com>
RyanHui <ryanhui1996@gmail.com>
SHEN Lin <shenlin192@gmail.com>
Sagar Jain <sagar7993@gmail.com>
Sakol Assawasagool <koobitor@gmail.com>
Salavat Gizatov <100ishundred@gmail.com>
Sam Chen <chenxsan@gmail.com>
Sam Lanning <sam@samlanning.com>
Sam Maxwell <sam@paybase.io>
Samuel Gaus <sam@gaus.co.uk>
Sanghyeon Lee <yongdamsh@gmail.com>
Sangle <whb97@163.com>
Sanjay Kumar <kris.gooner@gmail.com>
Sanjay Kumar <sk@tectusdreamlab.com>
Scott Sturgeon <scott@tugboatlogic.com>
Sean Lin <sean@ejoy.com>
Sean Sun <pinggodstudio@gmail.com>
Sean Willis <sean.willis@incorta.com>
Sebastian Blade <blade254353074@hotmail.com>
Sebastian Busch <mail@sebastian-bus.ch>
Sebastian Busch <s.busch@obg-gruppe.de>
Sebastian Busch <s.busch@qbus-enet.de>
Sergey Levkovich <gosu.87@mail.ru>
Sergey Volynkin <sergey.volynkin@akvelon.com>
Sergio Crisostomo <sergiosbox@gmail.com>
Sevak <shaderzak@gmail.com>
Shawn Sit <xueqingxiao@gmail.com>
ShiCheng <nnecec@outlook.com>
ShiTengFei <shitengfei@goyoo.com>
ShuYu Wang <andelf@gmail.com>
Shuai Chen <wasd2144@hotmail.com>
Shubham Kanodia <shubhamsizzles@gmail.com>
Shun <polytechnics.shun@gmail.com>
Shuvalov Anton <anton@shuvalov.info>
SimaQ <sima.zhang1990@gmail.com>
Simo Aleksandrov <simo3003@me.com>
Sivaraj S <sivaraj@sdev.in>
Sivaraj <contact@sdev.in>
SoraYama <sorayamahou@gmail.com>
Spencer <spjy@hawaii.edu>
Stanley Thijssen <stanley.thijssen@energybox.com>
Stanley Thijssen <stanley.thijssen@gmail.com>
Stephen Esser <Stephen.Esser@gmail.com>
Stevche Radevski <sradevski@live.com>
Subroto <shub1493biswas@gmail.com>
Sven Efftinge <sven.efftinge@typefox.io>
SylvanasGone <397009765@qq.com>
TTC <345866517@qq.com>
Tao <magicdawn@qq.com>
Tao Zhang <windse7en@gmail.com>
Taylor Sabell <taylorsabell@gmail.com>
@ -387,18 +518,22 @@ Teng YANG <yangteng@me.com>
Tengjiao Cai <caitengjiao1987@gmail.com>
Terence <trence320@163.com>
The Rock <zhoguoxin@126.com>
Theo Satloff <1golfball@gmail.com>
Thibault Derousseaux <tde@activeviam.com>
Thiebaud Thomas <thiebaud.tom@gmail.com>
Thomas <tom@axisj.com>
Thomas Ladd <thomas.ladd@stackpath.com>
Tino D <ginodeis@gmail.com>
Tom Gao <tom@zoomsoft.cc>
Tom Xu <tom.xu@antcosa.com>
Tom Xu <ycxzhkx@gmail.com>
TomIsion <isiontom@gmail.com>
Tomás Francisco <mail@tomasfrancisco.com>
Tomáš Hylský <thylsky@gmail.com>
Tomáš Szabo <tomas.szabo@deftomat.com>
Trotyl Yu <trotyl@qq.com>
Troy Thompson <troynt@gmail.com>
TsesamLi <tsesamli17@gmail.com>
Tyler <chaotyler@gmail.com>
Ubaldo Quintana <blkdr@hotmail.com>
Vadim Macagon <vadim.macagon@gmail.com>
@ -406,6 +541,8 @@ Valentin Vichnal <valentin@vichnal.com>
Van Nguyen <vnguyen94@gmail.com>
Vemund Santi <vemund@santi.no>
Vic <709147950@qq.com>
Victor Repkow <repkowvictor@gmail.com>
Vijay Thirugnanam <vijayst@gmail.com>
Vincent Zhang <vxzhong@qq.com>
Vitaliy Mazurenko <vitaliymazurenko@gmail.com>
ViviaRui <zr1450995198@163.com>
@ -420,17 +557,23 @@ Warren Seymour <warren@fountainhead.tech>
Wei Zhu <yesmeck@gmail.com>
Wenchao Hu <zjuhwc@gmail.com>
Wendell <wendzhue@gmail.com>
Wensheng Xu <xws@superid.cn>
Will <will_workhard@163.com>
Will Chen <willchen90@gmail.com>
William Cai <williamcai@easyops.cn>
WingGao <wing.gao@live.com>
Wu Haotian <whtsky@gmail.com>
XBTop1! <xbtop1@gmail.com>
XTY <^@xty.dev>
Xiaoming <yokiming1994@gmail.com>
Xie Guanglei <xieguanglei@hotmail.com>
Xinxing Li <lixinxing.2019@bytedance.com>
Xiping.wang <527409987@qq.com>
XuMM_12 <owiatsq@sina.cn>
Yang <504021398@qq.com>
Yang Bin <yangkghjh@gmail.com>
Yangzhedi <uiryzd@163.com>
Yann Normand <yann.normand@gmail.com>
Yasin Uslu <nepjua@gmail.com>
Yevhen Hryhorevskyi <evgeniygrigorevskiy@gmail.com>
Yiming <ymjrcc@qq.com>
@ -445,27 +588,36 @@ Yusuke Ito <novi.mad@gmail.com>
Yuwei Ba <i@xiaoba.me>
Yuxuan Huo <yuxuan.huo2011@gmail.com>
YuyingWu <wuyuying1128@gmail.com>
ZYSzys <zyszys98@gmail.com>
Zack Craig <zack@zack6849.com>
Zap <a124116186@qq.com>
Zhang Zhi <fytriht@gmail.com>
Zheeeng <hi@zheeeng.me>
Zhiqiang Gong <elory0513@hotmail.com>
Zhuo Chen <chenzhuo@caicloud.io>
Ziluo <gyfzzu@gmail.com>
Zohaib Ijaz <mzohaib.qc@gmail.com>
Zzzen <843968788@qq.com>
aashutoshrathi <aashutoshrathi@gmail.com>
adam <adamwu1992@163.com>
afc163 <afc163@gmail.com>
agent-z <1607291079@qq.com>
ahalimkara <ahalimkara@gmail.com>
alekslario <aleksandlario@gmail.com>
alex <379118572@qq.com>
alex89lj <379118572@qq.com>
alexchen <alexchen@easyops.cn>
amedora <americandragsterracing@gmail.com>
arifemrecelik <ce.arifemre@gmail.com>
ascoders <576625322@qq.com>
ashishg-qburst <ashishg@qburst.com>
atomoo <yangpein@gmail.com>
bLue <tbdblue@gmail.com>
babycannotsay <335658202@qq.com>
bang <sqibang@gmail.com>
bang88 <sqibang@gmail.com>
baozefeng <727751065@qq.com>
binyellow <571704908@qq.com>
blankzust <450811238@qq.com>
bukas <yhz1219@gmail.com>
byuanama <byuan@ama.com.au>
@ -477,14 +629,22 @@ cathayandy <wzm_andy@126.com>
cc189 <cc189dev@gmail.com>
chaofeis <408067385@qq.com>
chchen <cc272309126@gmail.com>
chen shuai <qixian.cs@outlook.com>
chen wen jun <731028571@qq.com>
chencheng (云谦) <sorrycc@gmail.com>
chencheng <sorrycc@gmail.com>
chenlong <long.chen@abssqr.com>
chenshuai2144 <qixian.cs@outlook.com>
chisus <chisus@smartstudy.co.kr>
chunlea <ichunlea@me.com>
cjahv <cjahv@qq.com>
clinyong <clinyong@gmail.com>
cnjs <1269075501@qq.com>
codesign <zuishiguang@126.com>
corneyl <cornieljoosse@gmail.com>
damon.chen <chj_0507_dz@sina.com>
david.lv <code4funlnyx@gmail.com>
david.lv <lvdawei1970@gmail.com>
davidhatten <david.r.hatten@gmail.com>
ddcat1115 <ddcat1115@gmail.com>
decade <decadef20@gmail.com>
@ -493,6 +653,7 @@ denzw <denzw@21cn.com>
dependabot[bot] <support@dependabot.com>
detailyang <detailyang@gmail.com>
devqin <devqin@gmail.com>
dian.li <dian.li@yunzhanghu.com>
digz6666 <digz6666@gmail.com>
djorkaeff <djorkae55@gmail.com>
duzliang <duzliang@gmail.com>
@ -501,15 +662,21 @@ edgji <j.edgji@gmail.com>
eidonjoe <806488716@qq.com>
elios <elios264@hotmail.com>
elrrrrrrr <elrrrrrrr@gmail.com>
eruca <nickwill1984@126.com>
ezpub <ez.foro@gmail.com>
feng zhi hao <fzhihao@outlook.com>
fengmk2 <m@fengmk2.com>
fkysly <fkysly@gmail.com>
flashback313 <windmark2012@gmail.com>
frezc <504021398@qq.com>
genie <genie88@163.com>
gregahren <grega.hren@gmail.com>
guifu <picodoth@gmail.com>
gxvv <gaoxin18000@gmail.com>
gyh9457 <gyh9457@163.com>
haianweifeng <1531297152@qq.com>
haimrait <haimrait@gmail.com>
handy <lihandi@gmail.com>
handycode <lihandi@gmail.com>
hank <stonehank310@gmail.com>
hanpei <75189218@qq.com>
@ -522,10 +689,13 @@ hengkx <ycxzhkx@gmail.com>
henryv0 <henryvo94@gmail.com>
hi-caicai <hi@cai-cai.me>
hongxuWei <hongxu.wei@outlook.com>
howard <geograous@126.com>
huangyan.py <huangyan.py@bytedance.com>
huishiyi <zhou1maple@gmail.com>
huzzbuzz <huzzbuzz@outlook.com>
iamcastelli <sowed@cyberdude.com>
iamkun <kunhello@outlook.com>
ikobe <ikobe621@gmail.com>
ilanus <hasanovtk@gmail.com>
imhele <work@imhele.com>
imosapatryk <imosa.patryk@gmail.com>
@ -539,6 +709,7 @@ jasonslyvia <jasonslyvia@gmail.com>
jasonxia23 <xia.jason23@gmail.com>
jiajiangxu <minesaner@163.com>
jiang <155259966@qq.com>
jiang.an <jarancn@gmail.com>
jim <wasd2144@hotmail.com>
jinouwuque <ee2win@gmail.com>
jinyaqiao1102 <405782493@QQ.com>
@ -547,13 +718,20 @@ junjing.zhang <zhangjunjing@gmail.com>
kacjay <45483388@qq.com>
kagawagao <kingsongao1221@gmail.com>
kaifei <150641329@qq.com>
kailunyao <kailunyao@163.com>
kanweiwei <475801900@qq.com>
kanweiwei <kwwnjujlc@sina.com>
kapiroska <etherreals777@gmail.com>
kasinooya <kasinooya@gmail.com>
kavin <kavin.huang@alphaliongroup.com>
kayw <kayw@outlook.com>
kdenz <ksnz93@gmail.com>
kdepp <kdepp.cd@gmail.com>
keng <keng@renderinghouse.com>
kenve <zwei.xie@gmail.com>
keqingrong <keqingrong1992@gmail.com>
kermolaev <kermolaev@cloudally.com>
klouskingsley <harry_tse@163.com>
ko <git@yaksok.net>
konakona <lovekonakona@gmail.com>
kossel <lis.yichao@gmail.com>
@ -565,13 +743,18 @@ leadream <857098475@qq.com>
lehug <zcszuo5811@126.com>
leijingdao <leijingdao@163.com>
leon.shi <superRaytin@163.com>
lewis liu <897473127@qq.com>
lgmcolin <gengmin.lgm@gmail.com>
lgmcolin <lgmcolin@gmail.com>
lhx <liuhongxi0000@163.com>
lhyt <515593899@qq.com>
liangfei <njliangfei@gmail.com>
liekkas <zjq0717@163.com>
lihqi <455711093@qq.com>
lilun <lilun_cd@keruyun.com>
littleLane <857183384@qq.com>
liuchuzhang <liuweiminer@126.com>
liuchuzhang <liuweiminer@hotmail.com>
lixiaochou077 <qi.liqi07@gmail.com>
lixiaoyang <lixiaoyang2345@gmail.com>
lixiaoyang1992 <lixiaoyang2345@gmail.com>
@ -580,16 +763,21 @@ lizhen <lizhen@youzan.com>
loganpowell <loganp@tepper.cmu.edu>
luyiming <luyimingchn@gmail.com>
lvren <luren6049@qq.com>
lxnxbnq <yuanddmail@163.com>
lyhper <lyhper@gmail.com>
mArker <252133226@qq.com>
maks <pine3ree@gmail.com>
maximest-pierre <me@maximest-pierre.me>
melchior voidwolf <kmno4k2mno4@gmail.com>
memoryza <jincai.wang@foxmail.com>
mgrdevport <mgrdevport@gmail.com>
mingyan.yu <mingyan.yu@wormpex.com>
mitchell.demler <mitchell.demler@harcourts.net>
mkermani144 <mkermani144@gmail.com>
mmmveggies <jakeselig@gmail.com>
mofelee <mofe@me.com>
monkindey <monkindey@163.com>
moonrailgun <moonrailgun@gmail.com>
mraiguo <810158465@qq.com>
mraiguo <mraiguo@gmail.com>
mushan0x0 <mushan0x0@gmail.com>
@ -597,21 +785,27 @@ muzea <mr.muzea@gmail.com>
muzuiget <muzuiget@gmail.com>
natergj <nater_nater@me.com>
neekey <ni184775761@gmail.com>
ngolin <poodll@163.com>
nick-ChenZe <chenze2168@gmail.com>
niko <644506165@qq.com>
nikogu <644506165@qq.com>
nnecec <nnecec@outlook.com>
nuintun <nuintun@qq.com>
ohhoney1 <1269075501@qq.com>
oldchicken <www.chao3208525@qq.com>
orzorzorzorz <zy410419243@gmail.com>
orzyyyy <zy410419243@gmail.com>
paranoidjk <hust2012jiangkai@gmail.com>
parlop <parlop@gmail.com>
pbrink231 <pbrink231@gmail.com>
pd4d10 <pd4d10@gmail.com>
peiming <hyrijk@gmail.com>
pengtikui <949828390@qq.com>
picodoth <picodoth@gmail.com>
picodoth <pikaleize@gmail.com>
pinggod <pinggodstudio@gmail.com>
pizn <pizner@gmail.com>
plainnany <plainnany@gmail.com>
plandem <plandem@gmail.com>
popomore <sakura9515@gmail.com>
qiaojie <1454763497@qq.com>
@ -620,14 +814,18 @@ qliu <1403927509@qq.com>
qubaoming <qubaoming@didichuxing.com>
ravirambles <ravirambles@gmail.com>
richardison <richard.ison@carleton.ca>
riho <873435892@qq.com>
ryangun <ryangun@foxmail.com>
ryanhoho <hswacoal@gmail.com>
ryannz <c5e1856@gmail.com>
sadmark <zhoubin@laidian360.com>
sallen450 <jqh101@sina.com>
saxenanihal95 <saxenanihal95@gmail.com>
sdli <1669375803@qq.com>
sfturing <sfturing@gmail.com>
shangyuan.ning <shangyuan.ning@manaowan.com>
shao <darryshaw@gmail.com>
shaodahong <darryshaw@gmail.com>
shawtung <shawtung@qq.com>
shelwin <wxfans@gmail.com>
shenlin192@gmail.com <shenlin192@gmail.com>
@ -645,9 +843,11 @@ sosohime <theziming@126.com>
spideeee <spideeee@github.com>
stevenyuysy <stevenyuysy@gmail.com>
stickmy <stickmyc@gmail.com>
susiwen <susiwen8@gmail.com>
swindme <swindme@163.com>
sylvanasGone <397009765@qq.com>
syssam <s.y.s.sam.sys@gmail.com>
tangjinzhou <21251118@zju.edu.cn>
tangjinzhou <415800467@qq.com>
tangjinzhou <tangjinzhou@yidian-inc.com>
taoweicn <twchn@live.com>
@ -655,52 +855,76 @@ thegatheringstorm <tgs@tgs.blue>
thilo-behnke <jan-thilo.behnke@gmx.de>
tianli.zhao <275287902@qq.com>
tom <caolvchong@gmail.com>
tom <gaoqiang19514@163.com>
toshi1127 <toshi.matsumoto.2n@stu.hosei.ac.jp>
twobin <twobin@live.com>
u3u <qwq@qwq.cat>
undefined <undefined>
unknown <chenyizhongx@gmail.com>
ustccjw <317713370@qq.com>
vagusX <vagusxl@gmail.com>
valleykid <valleykiddy@gmail.com>
vaytsel <vaytsel@gmail.com>
veveue <veveue@dingtalk.com>
vgeyi <vgeyiz@126.com>
wadezhan <wadezhan@tencent.com>
wangshantao <605682551@qq.com>
wangshuai <wangshuai@momenta.ai>
wangtao0101 <yuecjn@gmail.com>
wangxiaolei <fatelei@gmail.com>
wangxing <wangxing@nroad.com.cn>
wangxingkang <156148958@qq.com>
wangxingkang <wangxingkang@sensoro.com>
wangxueliang <wangxueliang@yidian-inc.com>
wanli <wanli@qunhemail.com>
warmhug <hualei5280@gmail.com>
wenhong <wenhong.zw@antfin.com>
whinc <whincwu@163.com>
whtang906 <whtang906@gmail.com>
willc001 <will.c001@163.com>
wizawu <wizawu@gmail.com>
wleven <408493323@qq.com>
wonyun <wy393767068@163.com>
woodsand <ballerpk70@gmail.com>
wtzeng1 <wentao_zeng1@163.com>
wwwxy <xiaowangziwxy@gmail.com>
wwwxy80s <xiaowangziwxy@gmail.com>
wx1322 <289758716@qq.com>
xiaofan2406 <xiaofan2406@gmail.com>
xiaohuoni <448627663@qq.com>
xrkffgg <xrkffgg@vip.qq.com>
xuqiang <xuqiang@xiaoshouyi.com>
y-take <y.takey@gmail.com>
yangwukang <yangwukang@boco.com.cn>
yangxiaolin <yangxiao2810279802@gmail.com>
ycjcl868 <45808948@qq.com>
ye4241 <ye4241@gmail.com>
yeliex <yeliex@yeliex.com>
yibu.wang <yibu.wang@orion.co.com>
yiminanci <yiminanci@gmail.com>
yiminghe <yiminghe@gmail.com>
yinjs <yinjiangsheng@gmail.com>
yociduo <yociduo@vip.qq.com>
yoyo837 <yoyo837@hotmail.com>
yubozhao <yubz86@gmail.com>
yuche <i@yuche.me>
yuezk <yuezk001@gmail.com>
z <haig8@msn.com>
zack <zxyah@126.com>
zefeng <zefengbao@outlook.com>
zelongc <nickcong123@gmail.com>
zerob4wl <zerob4wl@gmail.com>
zhangguanyu02 <zhangguanyu02@meituan.com>
zhangpc <zhangpc@tenxcloud.com>
zhangyangxue <383632607@qq.com>
zhangzh <zhangzh@cnlemon.net>
zhaocai <lzc09008@gmail.com>
zhaopeidong <lwindscar@gmail.com>
zhujun24 <zhujun87654321@gmail.com>
zhuyue <fuping.dfp@antfin.com>
zilong <jzlxiaohei@163.com>
zinkey <yaya@uloveit.com.cn>
zjf <zjffun@gmail.com>
zlljqn <zlljqn@gmail.com>
zollero <corona7@163.com>
zombieJ <smith3816@gmail.com>
@ -708,22 +932,31 @@ zombiej <smith3816@gmail.com>
zongzi531 <zongzi.xy@gmail.com>
ztplz <mysticzt@gmail.com>
zuiidea <zuiiidea@gmail.com>
zx6658 <zx6658@naver.com>
zy410419243 <zy410419243@gmail.com>
zytjs <yitongzhao@163.com>
°))))彡 <fisherspy@live.com>
邦 <sqibang@gmail.com>
爱but的苍蝇 <354788473@qq.com>
Ștefan Filip <stefy.filip@gmail.com>
高力 <3071730@qq.com>
郑旭 <332171564@qq.com>
拷钉 <41830859@qq.com>
蒋璇 <645762213@qq.com>
苏秦 <646382806@qq.com>
陈杰 <810158465@qq.com>
竹尔 <Juelchiang@gmail.com>
偏右 <afc163@gmail.com>
黄斌 <bin.huang02@hand-china.com>
英布 <chaoren1641@gmail.com>
朮厃 <cn.ah.liu@gmail.com>
张聪 <dancerphil1994@gmail.com>
诸岳 <dengfuping_develop@163.com>
诸岳 <dengfuping_private@163.com>
逸达 <dqaria@gmail.com>
诸岳 <fuping.dfp@antfin.com>
啸生 <ikobe621@gmail.com>
迷渡 <justjavac@gmail.com>
二哲 <kodo@forchange.cn>
廖星 <liaoxing.lx@bytedance.com>
刘红 <liuhong1.happy@163.com>
@ -736,6 +969,7 @@ zy410419243 <zy410419243@gmail.com>
松子 <window.pibarr@gmail.com>
何乐 <work@imhele.com>
付引 <xxxquotes@gmail.com>
萧琚 <yizhi.lyz@antfin.com>
可乐 <zaxlct@foxmail.com>
山客 <zeakhold@gmail.com>
曾凯 <zengkai2009@foxmail.com>
@ -743,6 +977,8 @@ zy410419243 <zy410419243@gmail.com>
信鑫-King <45808948@qq.com>
广彬-梁 <326741518@qq.com>
小哈husky <951565664@qq.com>
诸葛龙 <158362530@qq.com>
李环冀 <158757774@qq.com>
何志勇 <15988134176@163.com>
徐坤龙 <272992168@qq.com>
黄子毅 <576625322@qq.com>
@ -750,22 +986,27 @@ zy410419243 <zy410419243@gmail.com>
崔宏森 <948346354@qq.com>
黄文鉴 <concefly@foxmail.com>
董天成 <dongtiangche@outlook.com>
龚方闻 <fangwen.gong@baishancloud.com>
方剑成 <fjc0kb@gmail.com>
陈广亮 <geraldchen890806@gmail.com>
包子熊 <hezhiyu233@foxmail.com>
闲耘™ <hotoo.cn@gmail.com>
一喵呜 <hyb628@gmail.com>
王林涛 <hzwanglintao@corp.netease.com>
黄俊亮 <jayhuang@easyops.cn>
吕立青 <jimmy.jinglv@gmail.com>
隋鑫磊 <joshuasui@gmail.com>
米老朱 <laozhu.me@gmail.com>
刘宏玺 <liuhongxi0000@163.com>
乔奕轩 <qiao_yixuan@163.com>
马斯特 <sd4399340@126.com>
廖应龙 <vigossliao@gmail.com>
王集鹄 <wjhu111@21cn.com>
徐新航 <xuxinhang@bytedance.com>
杨哲迪 <yangzhedi@yidian-inc.com>
柚子男 <yozman@sina.com>
愚指导 <yutingzhao1991@sina.com>
只捱宅 <zy410419243@gmail.com>
郭延豪(708674) <gyh9457@163.com>
愚指导-TZ <yutingzhao1991@sina.com>
杨小事er <Uiryzd@163.com>
@ -773,5 +1014,8 @@ zy410419243 <zy410419243@gmail.com>
超能刚哥 <margox@foxmail.com>
马金花儿 <o.o@mug.dog>
रोहन मल्होत्रा <rohan.malhotra@adwyze.com>
芝华塔尼欧 <1150974628@qq.com>
白羊座小葛 <abeyuhang@gmail.com>
薛定谔的猫 <hh_2013@foxmail.com>
二货机器人 <smith3816@gmail.com>
骗你是小猫咪 <darryshaw@gmail.com>

View File

@ -15,6 +15,56 @@ timeline: true
---
## 3.26.4
`2019-12-22`
- 💄 Optimize Steps `subTitle` UI when `labelPlacement="vertical"`. [#20325](https://github.com/ant-design/ant-design/pull/20325)
- 🐞 Fix upload preview not support ico file type issue. [#20375](https://github.com/ant-design/ant-design/pull/20375) [@Rustin-Liu](https://github.com/Rustin-Liu)
- 🐞 Fix Form feedback icon combine Input `suffix` display not correct. [#20363](https://github.com/ant-design/ant-design/pull/20363)
- 🐞 Fix Tag `onClick` been triggered when close it. [#20355](https://github.com/ant-design/ant-design/pull/20355)
- 🐞 Fix Cascader component form check color trigger issue. [#20347](https://github.com/ant-design/ant-design/pull/20347) [@xrkffgg](https://github.com/xrkffgg)
- 🐞 Disallow auto focus input after triggering `onSearch` event in mobile and tablet devices. [#20332](https://github.com/ant-design/ant-design/pull/20332) [@YaoKaiLun](https://github.com/YaoKaiLun)
- 🐞 Fix Tabs ink bar missing transition animation. [#20283](https://github.com/ant-design/ant-design/pull/20283)
- 🐞 Fix TreeNode without `icon` show white block in `showIcon` mode. [#20274](https://github.com/ant-design/ant-design/pull/20274)
- TypeScript
- ⚡️ Update filters define in Table `onChange`. [#20337](https://github.com/ant-design/ant-design/pull/20337) [@MrHeer](https://github.com/MrHeer)
## 3.26.3
`2019-12-14`
- 🛠 support `unpkg` field in `package.json`. [#20193](https://github.com/ant-design/ant-design/pull/20193)
- 🐞 Fix Tree `showLine` and `showIcon` missing icon. [#20196](https://github.com/ant-design/ant-design/pull/20196)
- 🐞 Fix Modal combine Drawer cause invalid scroll problem. [#20242](https://github.com/ant-design/ant-design/pull/20242)
- 🐞 Fix Drawer `switchScrollingEffect prop on a DOM element` warning. [#20175](https://github.com/ant-design/ant-design/pull/20175)
- 🐞 Fix Select Option `label` definition. [#20190](https://github.com/ant-design/ant-design/pull/20190) [@ZhechenLi](https://github.com/ZhechenLi)
- 💄 Optimize Form feedback icon padding. [#20164](https://github.com/ant-design/ant-design/pull/20164) [@Satloff](https://github.com/Satloff)
- 💄 Add less variables for Select/Cascader to optimize dropdown padding and border radius. [#20156](https://github.com/ant-design/ant-design/pull/20156) [@Satloff](https://github.com/Satloff)
## 3.26.2
`2019-12-10`
- 🐞 Fix DatePicker `disabledTime` TypeScript definition to be optional. [#20153](https://github.com/ant-design/ant-design/pull/20153) [@khaledkhalil94](https://github.com/khaledkhalil94)
- 🐞 Fix Transfer's `title` of `dataSource` TypeScript definition to be optional. [#20144](https://github.com/ant-design/ant-design/pull/20144) [@mraiguo](https://github.com/mraiguo)
## 3.26.1
`2019-12-09`
- 🐞 Fix List pagination options text align. [#20037](https://github.com/ant-design/ant-design/issues/20037)
- 🐞 Fix Button text not align well in Chrome. [#20059](https://github.com/ant-design/ant-design/pull/20059)
- 🐞 Fix DescriptionItem `className` error applied to label. [#20067](https://github.com/ant-design/ant-design/pull/20067) [@Liu-Ya](https://github.com/Liu-Ya)
- 🐞 Fix Tree duplicated icons when `showLine` is true. [#20090](https://github.com/ant-design/ant-design/issues/20090)
- 🐞 Fix Editable Typography flush in Firefox. [#20118](https://github.com/ant-design/ant-design/pull/20118)
- 🐞 Improve Icon `component` definition to be compatible with create-react-app svg component. [#20142](https://github.com/ant-design/ant-design/pull/20142)
- Table
- 🐞 Fix small table header border missing. [#20030](https://github.com/ant-design/ant-design/issues/20030)
- 🐞 Fix `filterIcon` throws error when render string or number.
- 🐞 Fix `filterIcon` shows wrong title when returns Tooltip. [#20049](https://github.com/ant-design/ant-design/issues/20049)
- 🐞 Fix columns have 9px align issue in Windows Chrome. [#19952](https://github.com/ant-design/ant-design/issues/19952)
## 3.26.0
`2019-12-01`

View File

@ -15,6 +15,56 @@ timeline: true
---
## 3.26.4
`2019-12-22`
- 💄 优化 Steps `subTitle``labelPlacement="vertical"` 下的展现方式。[#20325](https://github.com/ant-design/ant-design/pull/20325)
- 🐞 修复 Upload 组件预览不支持 `.ico` 文件问题。[#20375](https://github.com/ant-design/ant-design/pull/20375) [@Rustin-Liu](https://github.com/Rustin-Liu)
- 🐞 修复 Form feedback 图标结合 Input `suffix` 显示不正确。[#20363](https://github.com/ant-design/ant-design/pull/20363)
- 🐞 修复 Tag 关闭时 `onClick` 被触发的问题。[#20355](https://github.com/ant-design/ant-design/pull/20355)
- 🐞 修复 Cascader 组件 Form 校验触发时,鼠标悬浮显示颜色问题。[#20347](https://github.com/ant-design/ant-design/pull/20347) [@xrkffgg](https://github.com/xrkffgg)
- 🐞 修复移动端点击搜索后,自动聚焦输入框,导致弹出键盘的问题。[#20332](https://github.com/ant-design/ant-design/pull/20332) [@YaoKaiLun](https://github.com/YaoKaiLun)
- 🐞 修复 Tabs 高亮条宽度的 `transition` 过度动画失效的问题。[#20283](https://github.com/ant-design/ant-design/pull/20283)
- 🐞 修复 TreeNode 不设置 `icon` 时会展示一个空白占位的问题。[#20274](https://github.com/ant-design/ant-design/pull/20274)
- TypeScript
- ⚡️ 更新 Table `onChange``filters` 的定义。[#20337](https://github.com/ant-design/ant-design/pull/20337) [@MrHeer](https://github.com/MrHeer)
## 3.26.3
`2019-12-14`
- 🛠 antd `package.json` 中补充 `unpkg` 字段。[#20193](https://github.com/ant-design/ant-design/pull/20193)
- 🐞 修复 Tree `showLine``showIcon` 同时开启时 `[+]` `[-]` 图标丢失的问题。[#20196](https://github.com/ant-design/ant-design/pull/20196)
- 🐞 修复 Modal 和 Drawer 结合使用时导致滚动失效的问题。[#20242](https://github.com/ant-design/ant-design/pull/20242)
- 🐞 修复 Drawer `switchScrollingEffect prop on a DOM element` 警告。[#20175](https://github.com/ant-design/ant-design/pull/20175)
- 🐞 修复 Select Option 的 `label` 属性定义。[#20190](https://github.com/ant-design/ant-design/pull/20190) [@ZhechenLi](https://github.com/ZhechenLi)
- 💄 优化 Form 反馈图标的间距样式。[#20164](https://github.com/ant-design/ant-design/pull/20164) [@Satloff](https://github.com/Satloff)
- 💄 Select/Cascader 新增和优化边距 padding 和圆角的相关 less 变量。[#20156](https://github.com/ant-design/ant-design/pull/20156) [@Satloff](https://github.com/Satloff)
## 3.26.2
`2019-12-10`
- 🐞 修正 DatePicker `disabledTime` 属性 TypeScript 定义为可选。[#20153](https://github.com/ant-design/ant-design/pull/20153) [@khaledkhalil94](https://github.com/khaledkhalil94)
- 🐞 修正 Transfer `dataSource``title` 属性 TypeScript 定义为可选。[#20144](https://github.com/ant-design/ant-design/pull/20144) [@mraiguo](https://github.com/mraiguo)
## 3.26.1
`2019-12-09`
- 🐞 修复 List 下分页选项文本对齐问题。[#20037](https://github.com/ant-design/ant-design/issues/20037)
- 🐞 修复 Chrome 下 Button 文字没有垂直居中的问题。[#20059](https://github.com/ant-design/ant-design/pull/20059)
- 🐞 修复 DescriptionItem 的 `className` 错误应用于 label。[#20067](https://github.com/ant-design/ant-design/pull/20067) [@Liu-Ya](https://github.com/Liu-Ya)
- 🐞 修复 Tree `showLine` 为 true 时展示多余图标的问题。[#20090](https://github.com/ant-design/ant-design/issues/20090)
- 🐞 修复 Typography 可编辑组件在 Firefox 下闪动的问题。[#20118](https://github.com/ant-design/ant-design/pull/20118)
- 🐞 修复 Icon `component` 的定义,使其兼容于 create-react-app 的 svg 组件定义。[#20142](https://github.com/ant-design/ant-design/pull/20142)
- Table
- 🐞 修复小号 Table 表头边框丢失的问题。[#20030](https://github.com/ant-design/ant-design/issues/20030)
- 🐞 修复 `filterIcon` 返回字符串或数字时报错的问题。
- 🐞 修复 `filterIcon` 返回 Tooltip 时显示了错误的 `title`。[#20049](https://github.com/ant-design/ant-design/issues/20049)
- 🐞 修复在 Windows Chrome 下固定列有 9px 的对齐问题。[#19952](https://github.com/ant-design/ant-design/issues/19952)
## 3.26.0
`2019-12-01`

View File

@ -24,10 +24,12 @@
## ✨ 特性
- 提炼自企业级中后台产品的交互语言和视觉风格。
- 开箱即用的高质量 React 组件。
- 使用 TypeScript 构建,提供完整的类型定义文件。
- 全链路开发和设计工具体系。
- 🌈 提炼自企业级中后台产品的交互语言和视觉风格。
- 📦 开箱即用的高质量 React 组件。
- 🛡 使用 TypeScript 开发,提供完整的类型定义文件。
- ⚙️ 全链路开发和设计工具体系。
- 🌍 数十个国际化语言支持。
- 🎨 深入每个细节的主题定制能力。
## 🖥 支持环境
@ -51,20 +53,25 @@ yarn add antd
## 🔨 示例
```jsx
import { DatePicker } from 'antd';
ReactDOM.render(<DatePicker />, mountNode);
```
````jsx
import { Button, DatePicker } from 'antd';
const App = () => (
<>
<Button type="primary">PRESS ME</Button>
<DatePicker />
</>
);
引入样式:
```jsx
import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
```
````
你也可以 [按需加载组件](https://ant.design/docs/react/getting-started-cn#按需加载)。
你也可以使用 [babel-plugin-import](https://ant.design/docs/react/getting-started-cn#按需加载)。
### TypeScript
### 🛡 TypeScript
参考 [在 TypeScript 中使用](https://ant.design/docs/react/use-in-typescript-cn)
@ -121,7 +128,7 @@ $ npm start
[![Let's fund issues in this repository](https://issuehunt.io/static/embed/issuehunt-button-v1.svg)](https://issuehunt.io/repos/34526884)
## 社区互助
## 👥 社区互助
如果您在使用的过程中碰到问题,可以通过下面几个途径寻求帮助,同时我们也鼓励资深用户通过下面的途径给新人提供帮助。

View File

@ -24,10 +24,12 @@ English | [简体中文](./README-zh_CN.md)
## ✨ Features
- An enterprise-class UI design system for web applications.
- A set of high-quality React components out of the box.
- Written in TypeScript with predictable static types.
- The whole package of development and design resources and tools.
- 🌈 Enterprise-class UI designed for web applications.
- 📦 A set of high-quality React components out of the box.
- 🛡 Written in TypeScript with predictable static types.
- ⚙️ Whole package of design resources and development tools.
- 🌍 Internationalization support for dozens of languages.
- 🎨 Powerful theme customization in every detail.
## 🖥 Environment Support
@ -52,8 +54,14 @@ yarn add antd
## 🔨 Usage
```jsx
import { DatePicker } from 'antd';
ReactDOM.render(<DatePicker />, mountNode);
import { Button, DatePicker } from 'antd';
const App = () => (
<>
<Button type="primary">PRESS ME</Button>
<DatePicker />
</>
);
```
And import style manually:
@ -62,7 +70,7 @@ And import style manually:
import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
```
Or [import components on demand](https://ant.design/docs/react/getting-started#Import-on-Demand).
Or use [babel-plugin-import](https://ant.design/docs/react/getting-started#Import-on-Demand).
### TypeScript

View File

@ -12,7 +12,15 @@
// Button styles
// -----------------------------
.@{btn-prefix-cls} {
line-height: @line-height-base;
// Fixing https://github.com/ant-design/ant-design/issues/12978
// Fixing https://github.com/ant-design/ant-design/issues/20058
// Fixing https://github.com/ant-design/ant-design/issues/19972
// Fixing https://github.com/ant-design/ant-design/issues/12978
// Fixing https://github.com/ant-design/ant-design/issues/18107
// Fixing https://github.com/ant-design/ant-design/issues/13214
// It is a render problem of chrome, which is only happened in the codesandbox demo
// 0.001px solution works and I don't why
line-height: @line-height-base - 0.001;
.btn;
.btn-default;
@ -87,6 +95,10 @@
&-icon-only {
.btn-square(@btn-prefix-cls);
> i {
vertical-align: middle;
}
}
&-round {

View File

@ -125,7 +125,7 @@
&-menus {
position: absolute;
z-index: @zindex-dropdown;
font-size: @font-size-base;
font-size: @cascader-dropdown-font-size;
white-space: nowrap;
background: @cascader-menu-bg;
border-radius: @border-radius-base;
@ -134,7 +134,6 @@
ul,
ol {
margin: 0;
padding: 0;
list-style: none;
}
@ -165,7 +164,7 @@
min-width: 111px;
height: 180px;
margin: 0;
padding: 0;
padding: @cascader-dropdown-edge-child-vertical-padding 0;
overflow: auto;
vertical-align: top;
list-style: none;
@ -185,8 +184,8 @@
}
}
&-menu-item {
padding: 5px @control-padding-horizontal;
line-height: 22px;
padding: @cascader-dropdown-vertical-padding @control-padding-horizontal;
line-height: @cascader-dropdown-line-height;
white-space: nowrap;
cursor: pointer;
transition: all 0.3s;

View File

@ -51,3 +51,23 @@ Some components use dynamic style to support wave effect. You can config `csp` p
#### Does the locale problem still exist in DatePicker even if ConfigProvider `locale` is used?
Please make sure you set moment locale by `moment.locale('zh-cn')` or that you don't have two different versions of moment.
#### Modal throw error when setting `getPopupContainer`?
Related issue: https://github.com/ant-design/ant-design/issues/19974
When you config `getPopupContainer` to parentNode globally, Modal will throw error of `triggerNode is undefined` because it did not have a triggerNode. You can try the [fix](https://github.com/afc163/feedback-antd/commit/3e4d1ad1bc1a38460dc3bf3c56517f737fe7d44a) below.
```diff
<ConfigProvider
- getPopupContainer={triggerNode => triggerNode.parentNode}
+ getPopupContainer={node => {
+ if (node) {
+ return node.parentNode;
+ }
+ return document.body;
+ }}
>
<App />
</ConfigProvider>
```

View File

@ -52,3 +52,23 @@ return (
#### 为什么我使用了 ConfigProvider `locale`,时间类组件的国际化还有问题?
请检查是否设置了 `moment.locale('zh-cn')`,或者是否有两个版本的 moment 共存。
#### 配置 `getPopupContainer` 导致 Modal 报错?
相关 issuehttps://github.com/ant-design/ant-design/issues/19974
当如下全局设置 `getPopupContainer` 为触发节点的 parentNode 时,由于 Modal 的用法不存在 `triggerNode`,这样会导致 `triggerNode is undefined` 的报错,需要增加一个[判断条件](https://github.com/afc163/feedback-antd/commit/3e4d1ad1bc1a38460dc3bf3c56517f737fe7d44a)。
```diff
<ConfigProvider
- getPopupContainer={triggerNode => triggerNode.parentNode}
+ getPopupContainer={node => {
+ if (node) {
+ return node.parentNode;
+ }
+ return document.body;
+ }}
>
<App />
</ConfigProvider>
```

View File

@ -0,0 +1,448 @@
/* tslint:disable jsx-no-multiline-js */
import * as React from 'react';
import * as moment from 'moment';
import { polyfill } from 'react-lifecycles-compat';
import RangeCalendar from 'rc-calendar/lib/RangeCalendar';
import RcDatePicker from 'rc-calendar/lib/Picker';
import classNames from 'classnames';
import shallowequal from 'shallowequal';
import Icon from '../icon';
import Tag from '../tag';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import warning from '../_util/warning';
import interopDefault from '../_util/interopDefault';
import { RangePickerValue, RangePickerPresetRange, RangePickerProps } from './interface';
import { formatDate } from './utils';
import InputIcon from './InputIcon';
export interface RangePickerState {
value?: RangePickerValue;
showDate?: RangePickerValue;
open?: boolean;
hoverValue?: RangePickerValue;
}
function getShowDateFromValue(value: RangePickerValue, mode?: string | string[]) {
const [start, end] = value;
// value could be an empty array, then we should not reset showDate
if (!start && !end) {
return;
}
if (mode && mode[0] === 'month') {
return [start, end] as RangePickerValue;
}
const newEnd = end && end.isSame(start!, 'month') ? end.clone().add(1, 'month') : end;
return [start, newEnd] as RangePickerValue;
}
function pickerValueAdapter(
value?: moment.Moment | RangePickerValue,
): RangePickerValue | undefined {
if (!value) {
return;
}
if (Array.isArray(value)) {
return value;
}
return [value, value.clone().add(1, 'month')];
}
function isEmptyArray(arr: any) {
if (Array.isArray(arr)) {
return arr.length === 0 || arr.every(i => !i);
}
return false;
}
function fixLocale(value: RangePickerValue | undefined, localeCode: string | undefined) {
if (!localeCode) {
return;
}
if (!value || value.length === 0) {
return;
}
const [start, end] = value;
if (start) {
start!.locale(localeCode);
}
if (end) {
end!.locale(localeCode);
}
}
class RangePicker extends React.Component<RangePickerProps, RangePickerState> {
static defaultProps = {
allowClear: true,
showToday: false,
separator: '~',
};
static getDerivedStateFromProps(nextProps: RangePickerProps, prevState: RangePickerState) {
let state = null;
if ('value' in nextProps) {
const value = nextProps.value || [];
state = {
value,
};
if (!shallowequal(nextProps.value, prevState.value)) {
state = {
...state,
showDate: getShowDateFromValue(value, nextProps.mode) || prevState.showDate,
};
}
}
if ('open' in nextProps && prevState.open !== nextProps.open) {
state = {
...state,
open: nextProps.open,
};
}
return state;
}
private picker: HTMLSpanElement;
private prefixCls?: string;
private tagPrefixCls?: string;
constructor(props: any) {
super(props);
const value = props.value || props.defaultValue || [];
const [start, end] = value;
if (
(start && !interopDefault(moment).isMoment(start)) ||
(end && !interopDefault(moment).isMoment(end))
) {
throw new Error(
'The value/defaultValue of RangePicker must be a moment object array after `antd@2.0`, ' +
'see: https://u.ant.design/date-picker-value',
);
}
const pickerValue = !value || isEmptyArray(value) ? props.defaultPickerValue : value;
this.state = {
value,
showDate: pickerValueAdapter(pickerValue || interopDefault(moment)()),
open: props.open,
hoverValue: [],
};
}
componentDidUpdate(_: any, prevState: RangePickerState) {
if (!('open' in this.props) && prevState.open && !this.state.open) {
this.focus();
}
}
setValue(value: RangePickerValue, hidePanel?: boolean) {
this.handleChange(value);
if ((hidePanel || !this.props.showTime) && !('open' in this.props)) {
this.setState({ open: false });
}
}
savePicker = (node: HTMLSpanElement) => {
this.picker = node;
};
clearSelection = (e: React.MouseEvent<HTMLElement>) => {
e.preventDefault();
e.stopPropagation();
this.setState({ value: [] });
this.handleChange([]);
};
clearHoverValue = () => this.setState({ hoverValue: [] });
handleChange = (value: RangePickerValue) => {
const { props } = this;
if (!('value' in props)) {
this.setState(({ showDate }) => ({
value,
showDate: getShowDateFromValue(value) || showDate,
}));
}
if (value[0] && value[1] && value[0].diff(value[1]) > 0) {
value[1] = undefined;
}
const [start, end] = value;
if (typeof props.onChange === 'function') {
props.onChange(value, [formatDate(start, props.format), formatDate(end, props.format)]);
}
};
handleOpenChange = (open: boolean) => {
if (!('open' in this.props)) {
this.setState({ open });
}
if (open === false) {
this.clearHoverValue();
}
const { onOpenChange } = this.props;
if (onOpenChange) {
onOpenChange(open);
}
};
handleShowDateChange = (showDate: RangePickerValue) => this.setState({ showDate });
handleHoverChange = (hoverValue: any) => this.setState({ hoverValue });
handleRangeMouseLeave = () => {
if (this.state.open) {
this.clearHoverValue();
}
};
handleCalendarInputSelect = (value: RangePickerValue) => {
const [start] = value;
if (!start) {
return;
}
this.setState(({ showDate }) => ({
value,
showDate: getShowDateFromValue(value) || showDate,
}));
};
handleRangeClick = (value: RangePickerPresetRange) => {
if (typeof value === 'function') {
value = value();
}
this.setValue(value, true);
const { onOk, onOpenChange } = this.props;
if (onOk) {
onOk(value);
}
if (onOpenChange) {
onOpenChange(false);
}
};
focus() {
this.picker.focus();
}
blur() {
this.picker.blur();
}
renderFooter = () => {
const { ranges, renderExtraFooter } = this.props;
const { prefixCls, tagPrefixCls } = this;
if (!ranges && !renderExtraFooter) {
return null;
}
const customFooter = renderExtraFooter ? (
<div className={`${prefixCls}-footer-extra`} key="extra">
{renderExtraFooter()}
</div>
) : null;
const operations =
ranges &&
Object.keys(ranges).map(range => {
const value = ranges[range];
const hoverValue = typeof value === 'function' ? value.call(this) : value;
return (
<Tag
key={range}
prefixCls={tagPrefixCls}
color="blue"
onClick={() => this.handleRangeClick(value)}
onMouseEnter={() => this.setState({ hoverValue })}
onMouseLeave={this.handleRangeMouseLeave}
>
{range}
</Tag>
);
});
const rangeNode =
operations && operations.length > 0 ? (
<div className={`${prefixCls}-footer-extra ${prefixCls}-range-quick-selector`} key="range">
{operations}
</div>
) : null;
return [rangeNode, customFooter];
};
renderRangePicker = ({ getPrefixCls }: ConfigConsumerProps) => {
const { state, props } = this;
const { value, showDate, hoverValue, open } = state;
const {
prefixCls: customizePrefixCls,
tagPrefixCls: customizeTagPrefixCls,
popupStyle,
style,
disabledDate,
disabledTime,
showTime,
showToday,
ranges,
onOk,
locale,
// @ts-ignore
localeCode,
format,
dateRender,
onCalendarChange,
suffixIcon,
separator,
} = props;
const prefixCls = getPrefixCls('calendar', customizePrefixCls);
const tagPrefixCls = getPrefixCls('tag', customizeTagPrefixCls);
// To support old version react.
// Have to add prefixCls on the instance.
// https://github.com/facebook/react/issues/12397
this.prefixCls = prefixCls;
this.tagPrefixCls = tagPrefixCls;
fixLocale(value, localeCode);
fixLocale(showDate, localeCode);
warning(
!('onOK' in props),
'RangePicker',
'It should be `RangePicker[onOk]`, instead of `onOK`!',
);
const calendarClassName = classNames({
[`${prefixCls}-time`]: showTime,
[`${prefixCls}-range-with-ranges`]: ranges,
});
// 需要选择时间时,点击 ok 时才触发 onChange
const pickerChangeHandler = {
onChange: this.handleChange,
};
let calendarProps: any = {
onOk: this.handleChange,
};
if (props.timePicker) {
pickerChangeHandler.onChange = changedValue => this.handleChange(changedValue);
} else {
calendarProps = {};
}
if ('mode' in props) {
calendarProps.mode = props.mode;
}
const startPlaceholder = Array.isArray(props.placeholder)
? props.placeholder[0]
: locale.lang.rangePlaceholder[0];
const endPlaceholder = Array.isArray(props.placeholder)
? props.placeholder[1]
: locale.lang.rangePlaceholder[1];
const calendar = (
<RangeCalendar
{...calendarProps}
seperator={separator}
onChange={onCalendarChange}
format={format}
prefixCls={prefixCls}
className={calendarClassName}
renderFooter={this.renderFooter}
timePicker={props.timePicker}
disabledDate={disabledDate}
disabledTime={disabledTime}
dateInputPlaceholder={[startPlaceholder, endPlaceholder]}
locale={locale.lang}
onOk={onOk}
dateRender={dateRender}
value={showDate}
onValueChange={this.handleShowDateChange}
hoverValue={hoverValue}
onHoverChange={this.handleHoverChange}
onPanelChange={props.onPanelChange}
showToday={showToday}
onInputSelect={this.handleCalendarInputSelect}
/>
);
// default width for showTime
const pickerStyle = {} as any;
if (props.showTime) {
pickerStyle.width = (style && style.width) || 350;
}
const [startValue, endValue] = value as RangePickerValue;
const clearIcon =
!props.disabled && props.allowClear && value && (startValue || endValue) ? (
<Icon
type="close-circle"
className={`${prefixCls}-picker-clear`}
onClick={this.clearSelection}
theme="filled"
/>
) : null;
const inputIcon = <InputIcon suffixIcon={suffixIcon} prefixCls={prefixCls} />;
const input = ({ value: inputValue }: { value: any }) => {
const [start, end] = inputValue;
return (
<span className={props.pickerInputClass}>
<input
disabled={props.disabled}
readOnly
value={formatDate(start, props.format)}
placeholder={startPlaceholder}
className={`${prefixCls}-range-picker-input`}
tabIndex={-1}
/>
<span className={`${prefixCls}-range-picker-separator`}> {separator} </span>
<input
disabled={props.disabled}
readOnly
value={formatDate(end, props.format)}
placeholder={endPlaceholder}
className={`${prefixCls}-range-picker-input`}
tabIndex={-1}
/>
{clearIcon}
{inputIcon}
</span>
);
};
return (
<span
ref={this.savePicker}
id={typeof props.id === 'number' ? props.id.toString() : props.id}
className={classNames(props.className, props.pickerClass)}
style={{ ...style, ...pickerStyle }}
tabIndex={props.disabled ? -1 : 0}
onFocus={props.onFocus}
onBlur={props.onBlur}
onMouseEnter={props.onMouseEnter}
onMouseLeave={props.onMouseLeave}
>
<RcDatePicker
{...props}
{...pickerChangeHandler}
calendar={calendar}
value={value}
open={open}
onOpenChange={this.handleOpenChange}
prefixCls={`${prefixCls}-picker-container`}
style={popupStyle}
>
{input}
</RcDatePicker>
</span>
);
};
render() {
return <ConfigConsumer>{this.renderRangePicker}</ConfigConsumer>;
}
}
polyfill(RangePicker);
export default RangePicker;

View File

@ -0,0 +1,117 @@
import * as React from 'react';
import * as moment from 'moment';
import { TimePickerProps } from '../time-picker';
import { tuple } from '../_util/type';
export interface PickerProps {
id?: number | string;
name?: string;
prefixCls?: string;
inputPrefixCls?: string;
format?: string | string[];
disabled?: boolean;
allowClear?: boolean;
className?: string;
pickerClass?: string;
pickerInputClass?: string;
suffixIcon?: React.ReactNode;
style?: React.CSSProperties;
popupStyle?: React.CSSProperties;
dropdownClassName?: string;
locale?: any;
size?: 'large' | 'small' | 'default';
getCalendarContainer?: (triggerNode: Element) => HTMLElement;
open?: boolean;
onOpenChange?: (status: boolean) => void;
disabledDate?: (current: moment.Moment | null) => boolean;
dateRender?: (current: moment.Moment, today: moment.Moment) => React.ReactNode;
autoFocus?: boolean;
onFocus?: React.FocusEventHandler;
onBlur?: (e: React.SyntheticEvent) => void;
}
export interface SinglePickerProps {
value?: moment.Moment | null;
defaultValue?: moment.Moment | null;
defaultPickerValue?: moment.Moment | null;
placeholder?: string;
renderExtraFooter?: (mode: DatePickerMode) => React.ReactNode;
onChange?: (date: moment.Moment | null, dateString: string) => void;
}
const DatePickerModes = tuple('time', 'date', 'month', 'year', 'decade');
export type DatePickerMode = typeof DatePickerModes[number];
export interface DatePickerProps extends PickerProps, SinglePickerProps {
showTime?: TimePickerProps | boolean;
showToday?: boolean;
open?: boolean;
disabledTime?: (
current?: moment.Moment | null,
) => {
disabledHours?: () => number[];
disabledMinutes?: () => number[];
disabledSeconds?: () => number[];
};
onOpenChange?: (status: boolean) => void;
onPanelChange?: (value: moment.Moment | null, mode: DatePickerMode) => void;
onOk?: (selectedTime: moment.Moment | null) => void;
mode?: DatePickerMode;
}
export interface MonthPickerProps extends PickerProps, SinglePickerProps {
monthCellContentRender?: (date: moment.Moment, locale: any) => React.ReactNode;
}
export type RangePickerValue =
| undefined[]
| null[]
| [moment.Moment]
| [undefined, moment.Moment]
| [moment.Moment, undefined]
| [null, moment.Moment]
| [moment.Moment, null]
| [moment.Moment, moment.Moment];
export type RangePickerPresetRange = RangePickerValue | (() => RangePickerValue);
export interface RangePickerProps extends PickerProps {
className?: string;
tagPrefixCls?: string;
value?: RangePickerValue;
defaultValue?: RangePickerValue;
defaultPickerValue?: RangePickerValue;
timePicker?: React.ReactNode;
onChange?: (dates: RangePickerValue, dateStrings: [string, string]) => void;
onCalendarChange?: (dates: RangePickerValue, dateStrings: [string, string]) => void;
onOk?: (selectedTime: RangePickerPresetRange) => void;
showTime?: TimePickerProps | boolean;
showToday?: boolean;
ranges?: {
[range: string]: RangePickerPresetRange;
};
placeholder?: [string, string];
mode?: string | string[];
separator?: React.ReactNode;
disabledTime?: (
current: RangePickerValue,
type: string,
) => {
disabledHours?: () => number[];
disabledMinutes?: () => number[];
disabledSeconds?: () => number[];
};
onPanelChange?: (value?: RangePickerValue, mode?: string | string[]) => void;
renderExtraFooter?: () => React.ReactNode;
onMouseEnter?: (e: React.MouseEvent<HTMLSpanElement, MouseEvent>) => void;
onMouseLeave?: (e: React.MouseEvent<HTMLSpanElement, MouseEvent>) => void;
}
export interface WeekPickerProps extends PickerProps, SinglePickerProps {
// - currently no own props -
}
export interface DatePickerDecorator extends React.ClassicComponentClass<DatePickerProps> {
RangePicker: React.ClassicComponentClass<RangePickerProps>;
MonthPicker: React.ClassicComponentClass<MonthPickerProps>;
WeekPicker: React.ClassicComponentClass<WeekPickerProps>;
}

View File

@ -14,7 +14,7 @@ const Col: React.SFC<ColProps> = props => {
const { child, bordered, colon, type, layout } = props;
const { prefixCls, label, className, children, span = 1 } = child.props;
const labelProps: any = {
className: classNames(`${prefixCls}-item-label`, className, {
className: classNames(`${prefixCls}-item-label`, {
[`${prefixCls}-item-colon`]: colon,
[`${prefixCls}-item-no-label`]: !label,
}),

View File

@ -192,7 +192,7 @@ exports[`Descriptions Descriptions.Item support className 1`] = `
colSpan={1}
>
<span
className="ant-descriptions-item-label my-class ant-descriptions-item-colon"
className="ant-descriptions-item-label ant-descriptions-item-colon"
key="label"
>
Product

View File

@ -1,7 +1,7 @@
---
category: Components
type: Data Display
title: Description List
title: Descriptions
cols: 1
---

View File

@ -30,12 +30,12 @@ exports[`renders ./components/dropdown/demo/basic.md correctly 1`] = `
`;
exports[`renders ./components/dropdown/demo/context-menu.md correctly 1`] = `
<span
<div
class="ant-dropdown-trigger"
style="user-select:none"
style="text-align:center;background:#f7f7f7;height:200px;line-height:200px;color:#777"
>
Right Click on Me
</span>
Right Click on here
</div>
`;
exports[`renders ./components/dropdown/demo/dropdown-button.md correctly 1`] = `

View File

@ -26,7 +26,17 @@ const menu = (
ReactDOM.render(
<Dropdown overlay={menu} trigger={['contextMenu']}>
<span style={{ userSelect: 'none' }}>Right Click on Me</span>
<div
style={{
textAlign: 'center',
background: '#f7f7f7',
height: 200,
lineHeight: '200px',
color: '#777',
}}
>
Right Click on here
</div>
</Dropdown>,
mountNode,
);

View File

@ -49,7 +49,7 @@
&-menu {
position: relative;
margin: 0;
padding: 4px 0;
padding: @dropdown-edge-child-vertical-padding 0;
text-align: left;
list-style-type: none;
background-color: @dropdown-menu-bg;
@ -113,6 +113,18 @@
transition: all 0.3s;
}
&:first-child {
& when (@dropdown-edge-child-vertical-padding = 0) {
border-radius: @border-radius-base @border-radius-base 0 0;
}
}
&:last-child {
& when (@dropdown-edge-child-vertical-padding = 0) {
border-radius: 0 0 @border-radius-base @border-radius-base;
}
}
&-selected,
&-selected > a {
color: @dropdown-selected-color;

View File

@ -528,7 +528,11 @@ exports[`renders ./components/empty/demo/config-provider.md correctly 1`] = `
Name
</th>
<th
<<<<<<< HEAD
class="ant-table-cell"
=======
class="ant-table-row-cell-last"
>>>>>>> origin/master
>
Age
</th>

View File

@ -4588,6 +4588,10 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
class="ant-picker-input"
>
<input
<<<<<<< HEAD
=======
class="ant-time-picker-input"
>>>>>>> origin/master
placeholder="Select time"
readonly=""
size="10"
@ -5109,6 +5113,242 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
</div>
</div>
</div>
<div
class="ant-row ant-form-item"
>
<div
class="ant-col ant-form-item-label ant-col-xs-24 ant-col-sm-5"
>
<label
class=""
title="Success"
>
Success
</label>
</div>
<div
class="ant-col ant-form-item-control-wrapper ant-col-xs-24 ant-col-sm-12"
>
<div
class="ant-form-item-control has-feedback has-success"
>
<span
class="ant-form-item-children"
>
<span
class="ant-input-affix-wrapper"
>
<input
class="ant-input"
placeholder="with allowClear"
type="text"
value=""
/>
<span
class="ant-input-suffix"
/>
</span>
<span
class="ant-form-item-children-icon"
>
<i
aria-label="icon: check-circle"
class="anticon anticon-check-circle"
>
<svg
aria-hidden="true"
class=""
data-icon="check-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm193.5 301.7l-210.6 292a31.8 31.8 0 0 1-51.7 0L318.5 484.9c-3.8-5.3 0-12.7 6.5-12.7h46.9c10.2 0 19.9 4.9 25.9 13.3l71.2 98.8 157.2-218c6-8.3 15.6-13.3 25.9-13.3H699c6.5 0 10.3 7.4 6.5 12.7z"
/>
</svg>
</i>
</span>
</span>
</div>
</div>
</div>
<div
class="ant-row ant-form-item"
>
<div
class="ant-col ant-form-item-label ant-col-xs-24 ant-col-sm-5"
>
<label
class=""
title="Warning"
>
Warning
</label>
</div>
<div
class="ant-col ant-form-item-control-wrapper ant-col-xs-24 ant-col-sm-12"
>
<div
class="ant-form-item-control has-feedback has-warning"
>
<span
class="ant-form-item-children"
>
<span
class="ant-input-password ant-input-affix-wrapper"
>
<input
action="click"
class="ant-input"
placeholder="with input password"
type="password"
value=""
/>
<span
class="ant-input-suffix"
>
<i
aria-label="icon: eye-invisible"
class="anticon anticon-eye-invisible ant-input-password-icon"
tabindex="-1"
>
<svg
aria-hidden="true"
class=""
data-icon="eye-invisible"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M942.2 486.2Q889.47 375.11 816.7 305l-50.88 50.88C807.31 395.53 843.45 447.4 874.7 512 791.5 684.2 673.4 766 512 766q-72.67 0-133.87-22.38L323 798.75Q408 838 512 838q288.3 0 430.2-300.3a60.29 60.29 0 0 0 0-51.5zm-63.57-320.64L836 122.88a8 8 0 0 0-11.32 0L715.31 232.2Q624.86 186 512 186q-288.3 0-430.2 300.3a60.3 60.3 0 0 0 0 51.5q56.69 119.4 136.5 191.41L112.48 835a8 8 0 0 0 0 11.31L155.17 889a8 8 0 0 0 11.31 0l712.15-712.12a8 8 0 0 0 0-11.32zM149.3 512C232.6 339.8 350.7 258 512 258c54.54 0 104.13 9.36 149.12 28.39l-70.3 70.3a176 176 0 0 0-238.13 238.13l-83.42 83.42C223.1 637.49 183.3 582.28 149.3 512zm246.7 0a112.11 112.11 0 0 1 146.2-106.69L401.31 546.2A112 112 0 0 1 396 512z"
/>
<path
d="M508 624c-3.46 0-6.87-.16-10.25-.47l-52.82 52.82a176.09 176.09 0 0 0 227.42-227.42l-52.82 52.82c.31 3.38.47 6.79.47 10.25a111.94 111.94 0 0 1-112 112z"
/>
</svg>
</i>
</span>
</span>
<span
class="ant-form-item-children-icon"
>
<i
aria-label="icon: exclamation-circle"
class="anticon anticon-exclamation-circle"
>
<svg
aria-hidden="true"
class=""
data-icon="exclamation-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm-32 232c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V296zm32 440a48.01 48.01 0 0 1 0-96 48.01 48.01 0 0 1 0 96z"
/>
</svg>
</i>
</span>
</span>
</div>
</div>
</div>
<div
class="ant-row ant-form-item"
>
<div
class="ant-col ant-form-item-label ant-col-xs-24 ant-col-sm-5"
>
<label
class=""
title="Error"
>
Error
</label>
</div>
<div
class="ant-col ant-form-item-control-wrapper ant-col-xs-24 ant-col-sm-12"
>
<div
class="ant-form-item-control has-feedback has-error"
>
<span
class="ant-form-item-children"
>
<span
class="ant-input-password ant-input-affix-wrapper"
>
<input
action="click"
class="ant-input"
placeholder="with input password and allowClear"
type="password"
value=""
/>
<span
class="ant-input-suffix"
>
<i
aria-label="icon: eye-invisible"
class="anticon anticon-eye-invisible ant-input-password-icon"
tabindex="-1"
>
<svg
aria-hidden="true"
class=""
data-icon="eye-invisible"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M942.2 486.2Q889.47 375.11 816.7 305l-50.88 50.88C807.31 395.53 843.45 447.4 874.7 512 791.5 684.2 673.4 766 512 766q-72.67 0-133.87-22.38L323 798.75Q408 838 512 838q288.3 0 430.2-300.3a60.29 60.29 0 0 0 0-51.5zm-63.57-320.64L836 122.88a8 8 0 0 0-11.32 0L715.31 232.2Q624.86 186 512 186q-288.3 0-430.2 300.3a60.3 60.3 0 0 0 0 51.5q56.69 119.4 136.5 191.41L112.48 835a8 8 0 0 0 0 11.31L155.17 889a8 8 0 0 0 11.31 0l712.15-712.12a8 8 0 0 0 0-11.32zM149.3 512C232.6 339.8 350.7 258 512 258c54.54 0 104.13 9.36 149.12 28.39l-70.3 70.3a176 176 0 0 0-238.13 238.13l-83.42 83.42C223.1 637.49 183.3 582.28 149.3 512zm246.7 0a112.11 112.11 0 0 1 146.2-106.69L401.31 546.2A112 112 0 0 1 396 512z"
/>
<path
d="M508 624c-3.46 0-6.87-.16-10.25-.47l-52.82 52.82a176.09 176.09 0 0 0 227.42-227.42l-52.82 52.82c.31 3.38.47 6.79.47 10.25a111.94 111.94 0 0 1-112 112z"
/>
</svg>
</i>
</span>
</span>
<span
class="ant-form-item-children-icon"
>
<i
aria-label="icon: close-circle"
class="anticon anticon-close-circle"
>
<svg
aria-hidden="true"
class=""
data-icon="close-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 0 1-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"
/>
</svg>
</i>
</span>
</span>
</div>
</div>
</div>
</form>
`;

View File

@ -5,6 +5,7 @@ import Form from '..';
import Input from '../../input';
import Button from '../../button';
import mountTest from '../../../tests/shared/mountTest';
import './type.test';
jest.mock('scroll-into-view-if-needed');

View File

@ -0,0 +1,98 @@
/* tslint:disable */
/* eslint-disable */
import * as React from 'react';
import Form, { FormComponentProps, FormCreateOption } from '../Form';
describe('Form TypeScript test', async () => {
it('empty test case placeholder to avoid jest error', () => {
// empty
});
});
// test Form.create on component without own props
class WithoutOwnProps extends React.Component<any, any> {
state = {
foo: 'bar',
};
render() {
return <div>foo</div>;
}
}
const WithoutOwnPropsForm = Form.create()(WithoutOwnProps);
<WithoutOwnPropsForm />;
// test Form.create on component with own props
interface WithOwnPropsProps extends FormComponentProps {
name: string;
}
class WithOwnProps extends React.Component<WithOwnPropsProps, any> {
state = {
foo: 'bar',
};
render() {
return <div>foo</div>;
}
}
const WithOwnPropsForm = Form.create<WithOwnPropsProps>()(WithOwnProps);
<WithOwnPropsForm name="foo" />;
// test Form.create with options
interface WithCreateOptionsProps extends FormComponentProps {
username: string;
}
class WithCreateOptions extends React.Component<WithCreateOptionsProps, {}> {
render() {
return <div>foo</div>;
}
}
const mapPropsToFields = (props: WithCreateOptionsProps) => {
const { username } = props;
return {
username: Form.createFormField({ value: username }),
};
};
const formOptions: FormCreateOption<WithCreateOptionsProps> = { mapPropsToFields };
const WithCreateOptionsForm = Form.create(formOptions)(WithCreateOptions);
<WithCreateOptionsForm username="foo" />;
// Should work with forwardRef & wrappedComponentRef
// https://github.com/ant-design/ant-design/issues/16229
if (React.forwardRef) {
interface ForwardProps extends FormComponentProps {
str: string;
}
const ForwardDemo = React.forwardRef(({ str }: ForwardProps, ref: React.Ref<HTMLDivElement>) => {
return <div ref={ref}>{str || ''}</div>;
});
const WrappedForwardDemo = Form.create<ForwardProps>()(ForwardDemo);
<WrappedForwardDemo str="" />;
}
interface WrappedRefProps extends FormComponentProps {
str: string;
test?: () => void;
}
class WrapRefDemo extends React.Component<WrappedRefProps> {
public getForm() {
return this.props.form;
}
public render() {
return <div>{this.props.str || ''}</div>;
}
}
const WrappedWrapRefDemo = Form.create<WrappedRefProps>()(WrapRefDemo);
<WrappedWrapRefDemo str="" wrappedComponentRef={() => null} />;

View File

@ -21,7 +21,7 @@ const HorizontalLoginForm = () => {
const [form] = Form.useForm();
const [, forceUpdate] = React.useState();
// To disabled submit button at the beginning.
// To disable submit button at the beginning.
React.useEffect(() => {
forceUpdate({});
}, []);

View File

@ -119,6 +119,18 @@ ReactDOM.render(
<Form.Item label="Success" hasFeedback validateStatus="success">
<InputNumber style={{ width: '100%' }} />
</Form.Item>
<Form.Item label="Success" hasFeedback validateStatus="success">
<Input allowClear placeholder="with allowClear" />
</Form.Item>
<Form.Item label="Warning" hasFeedback validateStatus="warning">
<Input.Password placeholder="with input password" />
</Form.Item>
<Form.Item label="Error" hasFeedback validateStatus="error">
<Input.Password allowClear placeholder="with input password and allowClear" />
</Form.Item>
</Form>,
mountNode,
);

View File

View File

@ -0,0 +1,12 @@
/* eslint-disable */
import React from 'react';
import Icon from '..';
import { ReactComponent as logo } from './logo.svg';
describe('Icon TypeScript test', () => {
it('empty test case placeholder to avoid jest error', () => {
// empty
});
});
<Icon component={logo} />;

View File

@ -1,7 +1,6 @@
import * as React from 'react';
import classNames from 'classnames';
import { SearchOutlined, LoadingOutlined } from '@ant-design/icons';
import Input, { InputProps } from './Input';
import Button from '../button';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
@ -40,6 +39,12 @@ export default class Search extends React.Component<SearchProps, any> {
}
};
onMouseDown: React.MouseEventHandler<HTMLElement> = e => {
if (document.activeElement === this.input.input) {
e.preventDefault();
}
};
onSearch = (e: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLInputElement>) => {
const { onSearch, loading, disabled } = this.props;
if (loading || disabled) {
@ -48,7 +53,6 @@ export default class Search extends React.Component<SearchProps, any> {
if (onSearch) {
onSearch(this.input.input.value, e);
}
this.input.focus();
};
focus() {
@ -116,6 +120,7 @@ export default class Search extends React.Component<SearchProps, any> {
(enterButtonAsElement.type as typeof Button).__ANT_BUTTON === true;
if (isAntdButton || enterButtonAsElement.type === 'button') {
button = React.cloneElement(enterButtonAsElement, {
onMouseDown: this.onMouseDown,
onClick: this.onSearch,
key: 'enterButton',
...(isAntdButton
@ -133,6 +138,7 @@ export default class Search extends React.Component<SearchProps, any> {
size={size}
disabled={disabled}
key="enterButton"
onMouseDown={this.onMouseDown}
onClick={this.onSearch}
>
{enterButton === true ? <SearchOutlined /> : enterButton}

View File

@ -411,6 +411,92 @@ exports[`renders ./components/input/demo/align.md correctly 1`] = `
size="12"
value=""
/>
<<<<<<< HEAD
=======
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="calendar"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M880 184H712v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H384v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H144c-17.7 0-32 14.3-32 32v664c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V216c0-17.7-14.3-32-32-32zm-40 656H184V460h656v380zM184 392V256h128v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h256v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h128v136H184z"
/>
</svg>
</i>
</div>
</span>
<span
class="ant-time-picker"
style="width:100px"
>
<input
class="ant-time-picker-input"
placeholder="Select time"
type="text"
value=""
/>
<span
class="ant-time-picker-icon"
>
<i
aria-label="icon: clock-circle"
class="anticon anticon-clock-circle ant-time-picker-clock-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="clock-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"
/>
<path
d="M686.7 638.6L544.1 535.5V288c0-4.4-3.6-8-8-8H488c-4.4 0-8 3.6-8 8v275.4c0 2.6 1.2 5 3.3 6.5l165.4 120.6c3.6 2.6 8.6 1.8 11.2-1.7l28.6-39c2.6-3.7 1.8-8.7-1.8-11.2z"
/>
</svg>
</i>
</span>
</span>
<div
class="ant-select ant-select-enabled"
style="width:100px"
>
<div
aria-autocomplete="list"
aria-controls=""
aria-expanded="false"
aria-haspopup="true"
class="ant-select-selection
ant-select-selection--single"
role="combobox"
tabindex="0"
>
<div
class="ant-select-selection__rendered"
>
<div
class="ant-select-selection-selected-value"
style="display:block;opacity:1"
title="Jack"
>
Jack
</div>
</div>
>>>>>>> origin/master
<span
class="ant-picker-suffix"
>

View File

@ -15,6 +15,11 @@
&-pagination {
margin-top: 24px;
text-align: right;
// https://github.com/ant-design/ant-design/issues/20037
.@{ant-prefix}-pagination-options {
text-align: left;
}
}
&-more {

File diff suppressed because it is too large Load Diff

View File

@ -184,10 +184,11 @@
position: relative;
display: block;
min-height: 32px;
padding: 5px @control-padding-horizontal;
padding: @select-dropdown-vertical-padding @control-padding-horizontal;
color: @text-color;
font-weight: normal;
line-height: 22px;
font-size: @select-dropdown-font-size;
line-height: @select-dropdown-line-height;
}
&-item-empty {

View File

@ -15,7 +15,7 @@ When part of the page is waiting for asynchronous data or during a rendering pro
| Property | Description | Type | Default Value |
| --- | --- | --- | --- |
| delay | specifies a delay in milliseconds for loading state (prevent flush) | number (milliseconds) | - |
| indicator | React node of the spinning indicator | ReactElement | - |
| indicator | React node of the spinning indicator | ReactNode | - |
| size | size of Spin, options: `small`, `default` and `large` | string | `default` |
| spinning | whether Spin is spinning | boolean | true |
| tip | customize description content when Spin has children | string | - |
@ -23,4 +23,6 @@ When part of the page is waiting for asynchronous data or during a rendering pro
### Static Method
- `Spin.setDefaultIndicator(indicator: ReactElement)` As `indicator`, you can define the global default spin element
- `Spin.setDefaultIndicator(indicator: ReactNode)`
You can define default spin element globally.

View File

@ -16,7 +16,7 @@ subtitle: 加载中
| 参数 | 说明 | 类型 | 默认值 |
| ---------------- | -------------------------------------------- | ------------- | --------- |
| delay | 延迟显示加载效果的时间(防止闪烁) | number (毫秒) | - |
| indicator | 加载指示符 | ReactElement | - |
| indicator | 加载指示符 | ReactNode | - |
| size | 组件大小,可选值为 `small` `default` `large` | string | 'default' |
| spinning | 是否为加载中状态 | boolean | true |
| tip | 当作为包裹元素时,可以自定义描述文案 | string | - |
@ -24,4 +24,6 @@ subtitle: 加载中
### 静态方法
- `Spin.setDefaultIndicator(indicator: ReactElement)` 同上 `indicator`,你可以自定义全局默认元素
- `Spin.setDefaultIndicator(indicator: ReactNode)`
你可以自定义全局默认 Spin 的元素。

View File

@ -26,7 +26,7 @@
@steps-dot-size: 8px;
@steps-current-dot-size: 10px;
@steps-desciption-max-width: 140px;
@steps-nav-content-max-width: @steps-desciption-max-width;
@steps-nav-content-max-width: auto;
.@{steps-prefix-cls} {
.reset-component;

View File

@ -2,19 +2,18 @@
.@{steps-prefix-cls}-item {
overflow: visible;
&-tail {
margin-left: 51px;
margin-left: 58px;
padding: 3.5px 24px;
}
&-content {
display: block;
// icon左边距离+一半icon宽度是content一半的宽度垂直对齐icon
width: (@steps-icon-size / 2 + 36px) * 2;
width: (@steps-icon-size / 2 + 42px) * 2;
margin-top: 8px;
text-align: center;
}
&-icon {
display: inline-block;
margin-left: 36px;
margin-left: 42px;
}
&-title {
padding-right: 0;
@ -22,6 +21,12 @@
display: none;
}
}
&-subtitle {
display: block;
margin-bottom: 4px;
margin-left: 0;
line-height: @line-height-base;
}
}
&.@{steps-prefix-cls}-small:not(.@{steps-prefix-cls}-dot) {
.@{steps-prefix-cls}-item {

View File

@ -312,6 +312,7 @@
//Dropdown
@dropdown-menu-bg: @component-background;
@dropdown-vertical-padding: 5px;
@dropdown-edge-child-vertical-padding: 4px;
@dropdown-font-size: @font-size-base;
@dropdown-line-height: 22px;
@ -366,6 +367,9 @@
@select-dropdown-bg: @component-background;
@select-item-selected-bg: @blue-1;
@select-item-active-bg: @item-hover-bg;
@select-dropdown-vertical-padding: @dropdown-vertical-padding;
@select-dropdown-font-size: @dropdown-font-size;
@select-dropdown-line-height: @dropdown-line-height;
@select-background: @component-background;
@select-clear-background: @select-background;
@ -376,6 +380,13 @@
@cascader-menu-bg: @component-background;
@cascader-menu-border-color-split: @border-color-split;
// Cascader
// ----
@cascader-dropdown-vertical-padding: @dropdown-vertical-padding;
@cascader-dropdown-edge-child-vertical-padding: @dropdown-edge-child-vertical-padding;
@cascader-dropdown-font-size: @dropdown-font-size;
@cascader-dropdown-line-height: @dropdown-line-height;
// Anchor
// ---
@anchor-bg: @component-background;

View File

@ -3,6 +3,7 @@ import React from 'react';
import { mount } from 'enzyme';
import Table from '..';
import Input from '../../input';
import Tooltip from '../../tooltip';
import Button from '../../button';
import ConfigProvider from '../../config-provider';
@ -688,6 +689,40 @@ describe('Table.filter', () => {
expect(wrapper.find('.customize-icon').render()).toMatchSnapshot();
});
it('renders custom filter icon as string correctly', () => {
const filterIcon = () => 'string';
const wrapper = mount(
createTable({
columns: [
{
...column,
filterIcon,
},
],
}),
);
expect(wrapper.render()).toMatchSnapshot();
});
it('renders custom filter icon with right Tooltip title', () => {
const filterIcon = () => (
<Tooltip title="title" visible>
Tooltip
</Tooltip>
);
const wrapper = mount(
createTable({
columns: [
{
...column,
filterIcon,
},
],
}),
);
expect(wrapper.render()).toMatchSnapshot();
});
// https://github.com/ant-design/ant-design/issues/13028
it('reset dropdown filter correctly', () => {
class Demo extends React.Component {

View File

@ -28,7 +28,11 @@ exports[`Table.expand click to expand 1`] = `
<thead>
<tr>
<th
<<<<<<< HEAD
class="ant-table-cell"
=======
class="ant-table-row-cell-last"
>>>>>>> origin/master
>
Name
</th>

View File

@ -50,6 +50,113 @@ exports[`Table.filter renders custom content correctly 1`] = `
</div>
`;
exports[`Table.filter renders custom filter icon as string correctly 1`] = `
<div
class="ant-table-wrapper"
>
<div
class="ant-spin-nested-loading"
>
<div
class="ant-spin-container"
>
<div
class="ant-table ant-table-default ant-table-scroll-position-left"
>
<div
class="ant-table-content"
>
<div
class="ant-table-body"
>
<table
class=""
>
<colgroup>
<col />
</colgroup>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-column-has-actions ant-table-column-has-filters ant-table-row-cell-last"
>
<span
class="ant-table-header-column"
>
<div>
<span
class="ant-table-column-title"
>
Name
</span>
<span
class="ant-table-column-sorter"
/>
</div>
</span>
<span
class="ant-table-filter-icon ant-dropdown-trigger"
>
string
</span>
</th>
</tr>
</thead>
<tbody
class="ant-table-tbody"
>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="0"
>
<td
class="ant-table-column-has-actions ant-table-column-has-filters"
>
Jack
</td>
</tr>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="1"
>
<td
class="ant-table-column-has-actions ant-table-column-has-filters"
>
Lucy
</td>
</tr>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="2"
>
<td
class="ant-table-column-has-actions ant-table-column-has-filters"
>
Tom
</td>
</tr>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="3"
>
<td
class="ant-table-column-has-actions ant-table-column-has-filters"
>
Jerry
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
`;
exports[`Table.filter renders custom filter icon correctly 1`] = `
<span
class="customize-icon"
@ -66,7 +173,7 @@ exports[`Table.filter renders custom filter icon correctly 2`] = `
</span>
`;
exports[`Table.filter renders filter correctly 1`] = `
exports[`Table.filter renders custom filter icon with right Tooltip title 1`] = `
<div
class="ant-table-wrapper"
>
@ -94,10 +201,145 @@ exports[`Table.filter renders filter correctly 1`] = `
<thead>
<tr>
<th
<<<<<<< HEAD
class="ant-table-cell"
>
<div
class="ant-table-filter-column"
=======
class="ant-table-column-has-actions ant-table-column-has-filters ant-table-row-cell-last"
>
<span
class="ant-table-header-column"
>
<div>
<span
class="ant-table-column-title"
>
Name
</span>
<span
class="ant-table-column-sorter"
/>
</div>
</span>
<span
class="ant-tooltip-open ant-table-filter-icon ant-dropdown-trigger"
style=""
>
Tooltip
</span>
<div>
<div
class="ant-tooltip ant-tooltip-placement-top zoom-big-fast-appear"
style="left: -999px; top: -1003px; transform-origin: 50% 4px;"
>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-arrow"
/>
<div
class="ant-tooltip-inner"
role="tooltip"
>
title
</div>
</div>
</div>
</div>
</th>
</tr>
</thead>
<tbody
class="ant-table-tbody"
>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="0"
>
<td
class="ant-table-column-has-actions ant-table-column-has-filters"
>
Jack
</td>
</tr>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="1"
>
<td
class="ant-table-column-has-actions ant-table-column-has-filters"
>
Lucy
</td>
</tr>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="2"
>
<td
class="ant-table-column-has-actions ant-table-column-has-filters"
>
Tom
</td>
</tr>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="3"
>
<td
class="ant-table-column-has-actions ant-table-column-has-filters"
>
Jerry
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
`;
exports[`Table.filter renders filter correctly 1`] = `
<div
class="ant-table-wrapper"
>
<div
class="ant-spin-nested-loading"
>
<div
class="ant-spin-container"
>
<div
class="ant-table ant-table-default ant-table-scroll-position-left"
>
<div
class="ant-table-content"
>
<div
class="ant-table-body"
>
<table
class=""
>
<colgroup>
<col />
</colgroup>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-column-has-actions ant-table-column-has-filters ant-table-row-cell-last"
>
<span
class="ant-table-header-column"
>>>>>>> origin/master
>
<span
class="ant-table-filter-column-title"
@ -407,7 +649,11 @@ exports[`Table.filter should support getPopupContainer 1`] = `
<thead>
<tr>
<th
<<<<<<< HEAD
class="ant-table-cell"
=======
class="ant-table-column-has-actions ant-table-column-has-filters ant-table-row-cell-last"
>>>>>>> origin/master
>
<div
class="ant-table-filter-column"
@ -622,7 +868,11 @@ exports[`Table.filter should support getPopupContainer from ConfigProvider 1`] =
<thead>
<tr>
<th
<<<<<<< HEAD
class="ant-table-cell"
=======
class="ant-table-column-has-actions ant-table-column-has-filters ant-table-row-cell-last"
>>>>>>> origin/master
>
<div
class="ant-table-filter-column"

View File

@ -28,7 +28,11 @@ exports[`Table.pagination Accepts pagination as true 1`] = `
<thead>
<tr>
<th
<<<<<<< HEAD
class="ant-table-cell"
=======
class="ant-table-row-cell-last"
>>>>>>> origin/master
>
Name
</th>
@ -185,7 +189,11 @@ exports[`Table.pagination renders pagination correctly 1`] = `
<thead>
<tr>
<th
<<<<<<< HEAD
class="ant-table-cell"
=======
class="ant-table-row-cell-last"
>>>>>>> origin/master
>
Name
</th>

View File

@ -49,6 +49,7 @@ exports[`Table.rowSelection fix selection column on the left 1`] = `
<span
class="ant-checkbox-inner"
/>
<<<<<<< HEAD
</span>
</label>
</div>
@ -71,6 +72,13 @@ exports[`Table.rowSelection fix selection column on the left 1`] = `
>
<label
class="ant-checkbox-wrapper"
=======
</div>
</span>
</th>
<th
class="ant-table-row-cell-last"
>>>>>>> origin/master
>
<span
class="ant-checkbox"
@ -153,11 +161,17 @@ exports[`Table.rowSelection fix selection column on the left 1`] = `
<td
class="ant-table-cell ant-table-selection-column"
>
<<<<<<< HEAD
<label
class="ant-checkbox-wrapper"
>
<span
class="ant-checkbox"
=======
<tr>
<th
class="ant-table-selection-column ant-table-row-cell-last"
>>>>>>> origin/master
>
<input
class="ant-checkbox-input"
@ -309,6 +323,7 @@ exports[`Table.rowSelection fix selection column on the left when any other colu
<span
class="ant-checkbox-inner"
/>
<<<<<<< HEAD
</span>
</label>
</div>
@ -333,6 +348,13 @@ exports[`Table.rowSelection fix selection column on the left when any other colu
>
<label
class="ant-checkbox-wrapper"
=======
</div>
</span>
</th>
<th
class="ant-table-fixed-columns-in-body ant-table-row-cell-last"
>>>>>>> origin/master
>
<span
class="ant-checkbox"
@ -421,11 +443,53 @@ exports[`Table.rowSelection fix selection column on the left when any other colu
class="ant-table-cell ant-table-selection-column ant-table-cell-fix-left"
style="position:sticky;left:0"
>
<<<<<<< HEAD
<label
class="ant-checkbox-wrapper"
>
<span
class="ant-checkbox"
=======
<tr>
<th
class="ant-table-selection-column"
>
<span
class="ant-table-header-column"
>
<div>
<span
class="ant-table-column-title"
>
<div
class="ant-table-selection"
>
<label
class="ant-checkbox-wrapper"
>
<span
class="ant-checkbox"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
</div>
</span>
<span
class="ant-table-column-sorter"
/>
</div>
</span>
</th>
<th
class="ant-table-row-cell-last"
>>>>>>> origin/master
>
<input
class="ant-checkbox-input"
@ -586,7 +650,11 @@ exports[`Table.rowSelection use column as selection column when key is \`selecti
<thead>
<tr>
<th
<<<<<<< HEAD
class="ant-table-cell ant-table-selection-column"
=======
class="ant-table-selection-column ant-table-row-cell-last"
>>>>>>> origin/master
>
<div
class="ant-table-selection"

View File

@ -4,7 +4,11 @@ exports[`Table.sorter renders sorter icon correctly 1`] = `
<thead>
<tr>
<th
<<<<<<< HEAD
class="ant-table-cell ant-table-column-has-sorters"
=======
class="ant-table-column-has-actions ant-table-column-has-sorters ant-table-row-cell-last"
>>>>>>> origin/master
>
<div
class="ant-table-column-sorters"
@ -94,7 +98,11 @@ exports[`Table.sorter should support defaultOrder in Column 1`] = `
<thead>
<tr>
<th
<<<<<<< HEAD
class="ant-table-cell ant-table-column-has-sorters"
=======
class="ant-table-column-has-actions ant-table-column-has-sorters ant-table-column-sort ant-table-row-cell-last"
>>>>>>> origin/master
>
<div
class="ant-table-column-sorters"

View File

@ -36,7 +36,11 @@ exports[`Table renders JSX correctly 1`] = `
Name
</th>
<th
<<<<<<< HEAD
class="ant-table-cell"
=======
class="ant-table-row-cell-last"
>>>>>>> origin/master
rowspan="2"
>
Age

File diff suppressed because it is too large Load Diff

View File

@ -70,7 +70,11 @@ exports[`Table renders empty table 1`] = `
Column 7
</th>
<th
<<<<<<< HEAD
class="ant-table-cell"
=======
class="ant-table-row-cell-last"
>>>>>>> origin/master
>
Column 8
</th>
@ -214,7 +218,11 @@ exports[`Table renders empty table with custom emptyText 1`] = `
Column 7
</th>
<th
<<<<<<< HEAD
class="ant-table-cell"
=======
class="ant-table-row-cell-last"
>>>>>>> origin/master
>
Column 8
</th>
@ -310,9 +318,240 @@ exports[`Table renders empty table with fixed columns 1`] = `
<table
style="table-layout:auto"
>
<<<<<<< HEAD
<colgroup>
<col
style="width:100px;min-width:100px"
=======
<table
class=""
>
<colgroup>
<col
style="width:100px;min-width:100px"
/>
<col
style="width:100px;min-width:100px"
/>
<col />
<col />
<col />
<col />
<col />
<col />
<col />
<col />
<col
style="width:100px;min-width:100px"
/>
</colgroup>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-fixed-columns-in-body ant-table-row-cell-break-word"
>
<span
class="ant-table-header-column"
>
<div>
<span
class="ant-table-column-title"
>
Full Name
</span>
<span
class="ant-table-column-sorter"
/>
</div>
</span>
</th>
<th
class="ant-table-fixed-columns-in-body ant-table-row-cell-break-word"
>
<span
class="ant-table-header-column"
>
<div>
<span
class="ant-table-column-title"
>
Age
</span>
<span
class="ant-table-column-sorter"
/>
</div>
</span>
</th>
<th
class=""
>
<span
class="ant-table-header-column"
>
<div>
<span
class="ant-table-column-title"
>
Column 1
</span>
<span
class="ant-table-column-sorter"
/>
</div>
</span>
</th>
<th
class=""
>
<span
class="ant-table-header-column"
>
<div>
<span
class="ant-table-column-title"
>
Column 2
</span>
<span
class="ant-table-column-sorter"
/>
</div>
</span>
</th>
<th
class=""
>
<span
class="ant-table-header-column"
>
<div>
<span
class="ant-table-column-title"
>
Column 3
</span>
<span
class="ant-table-column-sorter"
/>
</div>
</span>
</th>
<th
class=""
>
<span
class="ant-table-header-column"
>
<div>
<span
class="ant-table-column-title"
>
Column 4
</span>
<span
class="ant-table-column-sorter"
/>
</div>
</span>
</th>
<th
class=""
>
<span
class="ant-table-header-column"
>
<div>
<span
class="ant-table-column-title"
>
Column 5
</span>
<span
class="ant-table-column-sorter"
/>
</div>
</span>
</th>
<th
class=""
>
<span
class="ant-table-header-column"
>
<div>
<span
class="ant-table-column-title"
>
Column 6
</span>
<span
class="ant-table-column-sorter"
/>
</div>
</span>
</th>
<th
class=""
>
<span
class="ant-table-header-column"
>
<div>
<span
class="ant-table-column-title"
>
Column 7
</span>
<span
class="ant-table-column-sorter"
/>
</div>
</span>
</th>
<th
class=""
>
<span
class="ant-table-header-column"
>
<div>
<span
class="ant-table-column-title"
>
Column 8
</span>
<span
class="ant-table-column-sorter"
/>
</div>
</span>
</th>
<th
class="ant-table-fixed-columns-in-body ant-table-row-cell-break-word ant-table-row-cell-last"
>
<span
class="ant-table-header-column"
>
<div>
<span
class="ant-table-column-title"
>
Action
</span>
<span
class="ant-table-column-sorter"
/>
</div>
</span>
</th>
</tr>
</thead>
<tbody
class="ant-table-tbody"
>>>>>>> origin/master
/>
<col
style="width:100px;min-width:100px"
@ -426,6 +665,7 @@ exports[`Table renders empty table with fixed columns 1`] = `
rx="32"
ry="7"
/>
<<<<<<< HEAD
<g
class="ant-empty-img-simple-g"
fill-rule="nonzero"
@ -443,6 +683,62 @@ exports[`Table renders empty table with fixed columns 1`] = `
</div>
<p
class="ant-empty-description"
=======
</div>
</span>
</th>
<th
class="ant-table-row-cell-break-word ant-table-row-cell-last"
>
<span
class="ant-table-header-column"
>
<div>
<span
class="ant-table-column-title"
>
Age
</span>
<span
class="ant-table-column-sorter"
/>
</div>
</span>
</th>
</tr>
</thead>
<tbody
class="ant-table-tbody"
/>
</table>
</div>
</div>
</div>
<div
class="ant-table-fixed-right"
>
<div
class="ant-table-body-outer"
style="-webkit-transform:translate3d (0, 0, 0)"
>
<div
class="ant-table-body-inner"
>
<table
class="ant-table-fixed"
>
<colgroup>
<col
style="width:100px;min-width:100px"
/>
</colgroup>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-row-cell-break-word ant-table-row-cell-last"
>>>>>>> origin/master
>
No Data
</p>
@ -551,7 +847,11 @@ exports[`Table renders empty table without emptyText when loading 1`] = `
Column 7
</th>
<th
<<<<<<< HEAD
class="ant-table-cell"
=======
class="ant-table-row-cell-last"
>>>>>>> origin/master
>
Column 8
</th>

View File

@ -19,7 +19,7 @@ title:
Use `filters` to generate filter menu in columns, `onFilter` to determine filtered result, and `filterMultiple` to indicate whether it's multiple or single selection.
Uses `defaultFilterValues` to make a column filtered by default.
Uses `defaultFilteredValue` to make a column filtered by default.
Use `sorter` to make a column sortable. `sorter` can be a function of the type `function(a, b) { ... }` for sorting data locally.
@ -60,7 +60,6 @@ const columns = [
],
},
],
defaultFilterValues: ['Jim'],
// specify the condition of filtering result
// here is that finding the name started with `value`
onFilter: (value, record) => record.name.indexOf(value) === 0,

View File

@ -0,0 +1,326 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { polyfill } from 'react-lifecycles-compat';
import Menu, { SubMenu, Item as MenuItem } from 'rc-menu';
import closest from 'dom-closest';
import classNames from 'classnames';
import shallowequal from 'shallowequal';
import Dropdown from '../dropdown';
import Icon from '../icon';
import Checkbox from '../checkbox';
import Radio from '../radio';
import FilterDropdownMenuWrapper from './FilterDropdownMenuWrapper';
import { FilterMenuProps, FilterMenuState, ColumnProps, ColumnFilterItem } from './interface';
import { generateValueMaps } from './util';
function stopPropagation(e: React.SyntheticEvent<any>) {
e.stopPropagation();
if (e.nativeEvent.stopImmediatePropagation) {
e.nativeEvent.stopImmediatePropagation();
}
}
class FilterMenu<T> extends React.Component<FilterMenuProps<T>, FilterMenuState<T>> {
static defaultProps = {
column: {},
};
static getDerivedStateFromProps<T>(nextProps: FilterMenuProps<T>, prevState: FilterMenuState<T>) {
const { column } = nextProps;
const { prevProps } = prevState;
const newState: Partial<FilterMenuState<T>> = {
prevProps: nextProps,
};
/**
* if the state is visible the component should ignore updates on selectedKeys prop to avoid
* that the user selection is lost
* this happens frequently when a table is connected on some sort of realtime data
* Fixes https://github.com/ant-design/ant-design/issues/10289 and
* https://github.com/ant-design/ant-design/issues/10209
*/
if (
'selectedKeys' in nextProps &&
!shallowequal(prevProps.selectedKeys, nextProps.selectedKeys)
) {
newState.selectedKeys = nextProps.selectedKeys;
}
if (!shallowequal((prevProps.column || {}).filters, (nextProps.column || {}).filters)) {
newState.valueKeys = generateValueMaps(nextProps.column.filters);
}
if ('filterDropdownVisible' in column) {
newState.visible = column.filterDropdownVisible as boolean;
}
return newState;
}
neverShown: boolean;
constructor(props: FilterMenuProps<T>) {
super(props);
const visible =
'filterDropdownVisible' in props.column ? props.column.filterDropdownVisible : false;
this.state = {
selectedKeys: props.selectedKeys,
valueKeys: generateValueMaps(props.column.filters),
keyPathOfSelectedItem: {}, // 记录所有有选中子菜单的祖先菜单
visible,
prevProps: props,
};
}
componentDidMount() {
const { column } = this.props;
this.setNeverShown(column);
}
componentDidUpdate() {
const { column } = this.props;
this.setNeverShown(column);
}
getDropdownVisible() {
return this.neverShown ? false : this.state.visible;
}
setNeverShown = (column: ColumnProps<T>) => {
const rootNode = ReactDOM.findDOMNode(this);
const filterBelongToScrollBody = !!closest(rootNode, `.ant-table-scroll`);
if (filterBelongToScrollBody) {
// When fixed column have filters, there will be two dropdown menus
// Filter dropdown menu inside scroll body should never be shown
// To fix https://github.com/ant-design/ant-design/issues/5010 and
// https://github.com/ant-design/ant-design/issues/7909
this.neverShown = !!column.fixed;
}
};
setSelectedKeys = ({ selectedKeys }: { selectedKeys?: React.Key[] }) => {
this.setState({ selectedKeys: selectedKeys! });
};
setVisible(visible: boolean) {
const { column } = this.props;
if (!('filterDropdownVisible' in column)) {
this.setState({ visible });
}
if (column.onFilterDropdownVisibleChange) {
column.onFilterDropdownVisibleChange(visible);
}
}
handleClearFilters = () => {
this.setState(
{
selectedKeys: [],
},
this.handleConfirm,
);
};
handleConfirm = () => {
this.setVisible(false);
// Call `setSelectedKeys` & `confirm` in the same time will make filter data not up to date
// https://github.com/ant-design/ant-design/issues/12284
this.setState({}, this.confirmFilter);
};
onVisibleChange = (visible: boolean) => {
this.setVisible(visible);
const { column } = this.props;
// https://github.com/ant-design/ant-design/issues/17833
if (!visible && !(column.filterDropdown instanceof Function)) {
this.confirmFilter();
}
};
handleMenuItemClick = (info: { keyPath: React.Key[]; key: React.Key }) => {
const { selectedKeys } = this.state;
if (!info.keyPath || info.keyPath.length <= 1) {
return;
}
const { keyPathOfSelectedItem } = this.state;
if (selectedKeys && selectedKeys.indexOf(info.key) >= 0) {
// deselect SubMenu child
delete keyPathOfSelectedItem[info.key];
} else {
// select SubMenu child
keyPathOfSelectedItem[info.key] = info.keyPath;
}
this.setState({ keyPathOfSelectedItem });
};
hasSubMenu() {
const {
column: { filters = [] },
} = this.props;
return filters.some(item => !!(item.children && item.children.length > 0));
}
confirmFilter() {
const { column, selectedKeys: propSelectedKeys, confirmFilter } = this.props;
const { selectedKeys, valueKeys } = this.state;
const { filterDropdown } = column;
if (!shallowequal(selectedKeys, propSelectedKeys)) {
confirmFilter(
column,
filterDropdown
? selectedKeys
: selectedKeys.map(key => valueKeys[key]).filter(key => key !== undefined),
);
}
}
renderMenus(items: ColumnFilterItem[]): React.ReactElement<any>[] {
const { dropdownPrefixCls, prefixCls } = this.props;
return items.map(item => {
if (item.children && item.children.length > 0) {
const { keyPathOfSelectedItem } = this.state;
const containSelected = Object.keys(keyPathOfSelectedItem).some(
key => keyPathOfSelectedItem[key].indexOf(item.value) >= 0,
);
const subMenuCls = classNames(`${prefixCls}-dropdown-submenu`, {
[`${dropdownPrefixCls}-submenu-contain-selected`]: containSelected,
});
return (
<SubMenu title={item.text} popupClassName={subMenuCls} key={item.value.toString()}>
{this.renderMenus(item.children)}
</SubMenu>
);
}
return this.renderMenuItem(item);
});
}
renderFilterIcon = () => {
const { column, locale, prefixCls, selectedKeys } = this.props;
const filtered = selectedKeys && selectedKeys.length > 0;
let filterIcon = column.filterIcon;
if (typeof filterIcon === 'function') {
filterIcon = filterIcon(filtered);
}
const dropdownIconClass = classNames({
[`${prefixCls}-selected`]: filtered,
[`${prefixCls}-open`]: this.getDropdownVisible(),
});
if (!filterIcon) {
return (
<Icon
title={locale.filterTitle}
type="filter"
theme="filled"
className={dropdownIconClass}
onClick={stopPropagation}
/>
);
}
if (React.isValidElement(filterIcon)) {
return React.cloneElement(filterIcon, {
title: filterIcon.props.title || locale.filterTitle,
className: classNames(`${prefixCls}-icon`, dropdownIconClass, filterIcon.props.className),
onClick: stopPropagation,
});
}
return <span className={classNames(`${prefixCls}-icon`, dropdownIconClass)}>{filterIcon}</span>;
};
renderMenuItem(item: ColumnFilterItem) {
const { column } = this.props;
const { selectedKeys } = this.state;
const multiple = 'filterMultiple' in column ? column.filterMultiple : true;
// We still need trade key as string since Menu render need string
const internalSelectedKeys = (selectedKeys || []).map(key => key.toString());
const input = multiple ? (
<Checkbox checked={internalSelectedKeys.indexOf(item.value.toString()) >= 0} />
) : (
<Radio checked={internalSelectedKeys.indexOf(item.value.toString()) >= 0} />
);
return (
<MenuItem key={item.value}>
{input}
<span>{item.text}</span>
</MenuItem>
);
}
render() {
const { selectedKeys: originSelectedKeys } = this.state;
const { column, locale, prefixCls, dropdownPrefixCls, getPopupContainer } = this.props;
// default multiple selection in filter dropdown
const multiple = 'filterMultiple' in column ? column.filterMultiple : true;
const dropdownMenuClass = classNames({
[`${dropdownPrefixCls}-menu-without-submenu`]: !this.hasSubMenu(),
});
let { filterDropdown } = column;
if (filterDropdown instanceof Function) {
filterDropdown = filterDropdown({
prefixCls: `${dropdownPrefixCls}-custom`,
setSelectedKeys: (selectedKeys: Array<any>) => this.setSelectedKeys({ selectedKeys }),
selectedKeys: originSelectedKeys,
confirm: this.handleConfirm,
clearFilters: this.handleClearFilters,
filters: column.filters,
visible: this.getDropdownVisible(),
});
}
const menus = filterDropdown ? (
<FilterDropdownMenuWrapper className={`${prefixCls}-dropdown`}>
{filterDropdown}
</FilterDropdownMenuWrapper>
) : (
<FilterDropdownMenuWrapper className={`${prefixCls}-dropdown`}>
<Menu
multiple={multiple}
onClick={this.handleMenuItemClick}
prefixCls={`${dropdownPrefixCls}-menu`}
className={dropdownMenuClass}
onSelect={this.setSelectedKeys}
onDeselect={this.setSelectedKeys}
selectedKeys={originSelectedKeys && originSelectedKeys.map(val => val.toString())}
getPopupContainer={getPopupContainer}
>
{this.renderMenus(column.filters!)}
</Menu>
<div className={`${prefixCls}-dropdown-btns`}>
<a className={`${prefixCls}-dropdown-link confirm`} onClick={this.handleConfirm}>
{locale.filterConfirm}
</a>
<a className={`${prefixCls}-dropdown-link clear`} onClick={this.handleClearFilters}>
{locale.filterReset}
</a>
</div>
</FilterDropdownMenuWrapper>
);
return (
<Dropdown
trigger={['click']}
placement="bottomRight"
overlay={menus}
visible={this.getDropdownVisible()}
onVisibleChange={this.onVisibleChange}
getPopupContainer={getPopupContainer}
forceRender
>
{this.renderFilterIcon()}
</Dropdown>
);
}
}
polyfill(FilterMenu);
export default FilterMenu;

View File

@ -96,7 +96,8 @@ export interface ColumnGroupType<RecordType> extends ColumnType<RecordType> {
export type ColumnsType<RecordType = unknown> = (
| ColumnGroupType<RecordType>
| ColumnType<RecordType>)[];
| ColumnType<RecordType>
)[];
export interface SelectionItem {
key: string;

View File

@ -29,6 +29,7 @@
left: 0;
z-index: 1;
box-sizing: border-box;
width: 0;
height: 2px;
background-color: @tabs-ink-bar-color;
transform-origin: 0 0;
@ -330,7 +331,7 @@
bottom: auto;
left: auto;
width: 2px;
height: auto;
height: 0;
}
.@{tab-prefix-cls}-tab-next {
@ -403,12 +404,12 @@
.@{tab-prefix-cls}-top .@{tab-prefix-cls}-ink-bar-animated,
.@{tab-prefix-cls}-bottom .@{tab-prefix-cls}-ink-bar-animated {
transition: transform 0.3s @ease-in-out, width 0.3s @ease-in-out, left 0.3s @ease-in-out;
transition: transform 0.3s @ease-in-out, width 0.2s @ease-in-out, left 0.3s @ease-in-out;
}
.@{tab-prefix-cls}-left .@{tab-prefix-cls}-ink-bar-animated,
.@{tab-prefix-cls}-right .@{tab-prefix-cls}-ink-bar-animated {
transition: transform 0.3s @ease-in-out, height 0.3s @ease-in-out, top 0.3s @ease-in-out;
transition: transform 0.3s @ease-in-out, height 0.2s @ease-in-out, top 0.3s @ease-in-out;
}
// No animation

View File

@ -39,6 +39,16 @@ describe('Tag', () => {
expect(wrapper.find('.ant-tag:not(.ant-tag-hidden)').length).toBe(1);
});
// https://github.com/ant-design/ant-design/issues/20344
it('should not trigger onClick when click close icon', () => {
const onClose = jest.fn();
const onClick = jest.fn();
const wrapper = mount(<Tag closable onClose={onClose} onClick={onClick} />);
wrapper.find('.anticon-close').simulate('click');
expect(onClose).toHaveBeenCalled();
expect(onClick).not.toHaveBeenCalled();
});
describe('visibility', () => {
it('can be controlled by visible with visible as initial value', () => {
const wrapper = mount(<Tag visible />);

View File

@ -87,6 +87,7 @@ class Tag extends React.Component<TagProps, TagState> {
}
handleIconClick = (e: React.MouseEvent<HTMLElement>) => {
e.stopPropagation();
this.setVisible(false, e);
};

View File

@ -137,6 +137,10 @@ exports[`renders ./components/time-picker/demo/addon.md correctly 1`] = `
class="ant-picker-input"
>
<input
<<<<<<< HEAD
=======
class="ant-time-picker-input"
>>>>>>> origin/master
placeholder="Select time"
readonly=""
size="10"
@ -181,6 +185,10 @@ exports[`renders ./components/time-picker/demo/basic.md correctly 1`] = `
class="ant-picker-input"
>
<input
<<<<<<< HEAD
=======
class="ant-time-picker-input"
>>>>>>> origin/master
placeholder="Select time"
readonly=""
size="10"
@ -225,7 +233,11 @@ exports[`renders ./components/time-picker/demo/disabled.md correctly 1`] = `
class="ant-picker-input"
>
<input
<<<<<<< HEAD
disabled=""
=======
class="ant-time-picker-input"
>>>>>>> origin/master
placeholder="Select time"
readonly=""
size="10"
@ -262,14 +274,239 @@ exports[`renders ./components/time-picker/demo/disabled.md correctly 1`] = `
</div>
`;
<<<<<<< HEAD
=======
exports[`renders ./components/time-picker/demo/addon.md correctly 1`] = `
<span
class="ant-time-picker"
>
<input
class="ant-time-picker-input"
placeholder="Select time"
type="text"
value=""
/>
<span
class="ant-time-picker-icon"
>
<i
aria-label="icon: clock-circle"
class="anticon anticon-clock-circle ant-time-picker-clock-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="clock-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"
/>
<path
d="M686.7 638.6L544.1 535.5V288c0-4.4-3.6-8-8-8H488c-4.4 0-8 3.6-8 8v275.4c0 2.6 1.2 5 3.3 6.5l165.4 120.6c3.6 2.6 8.6 1.8 11.2-1.7l28.6-39c2.6-3.7 1.8-8.7-1.8-11.2z"
/>
</svg>
</i>
</span>
</span>
`;
exports[`renders ./components/time-picker/demo/basic.md correctly 1`] = `
<span
class="ant-time-picker"
>
<input
class="ant-time-picker-input"
placeholder="Select time"
type="text"
value=""
/>
<span
class="ant-time-picker-icon"
>
<i
aria-label="icon: clock-circle"
class="anticon anticon-clock-circle ant-time-picker-clock-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="clock-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"
/>
<path
d="M686.7 638.6L544.1 535.5V288c0-4.4-3.6-8-8-8H488c-4.4 0-8 3.6-8 8v275.4c0 2.6 1.2 5 3.3 6.5l165.4 120.6c3.6 2.6 8.6 1.8 11.2-1.7l28.6-39c2.6-3.7 1.8-8.7-1.8-11.2z"
/>
</svg>
</i>
</span>
</span>
`;
exports[`renders ./components/time-picker/demo/disabled.md correctly 1`] = `
<span
class="ant-time-picker"
>
<input
class="ant-time-picker-input"
disabled=""
placeholder="Select time"
type="text"
value="12:08:23"
/>
<span
class="ant-time-picker-icon"
>
<i
aria-label="icon: clock-circle"
class="anticon anticon-clock-circle ant-time-picker-clock-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="clock-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"
/>
<path
d="M686.7 638.6L544.1 535.5V288c0-4.4-3.6-8-8-8H488c-4.4 0-8 3.6-8 8v275.4c0 2.6 1.2 5 3.3 6.5l165.4 120.6c3.6 2.6 8.6 1.8 11.2-1.7l28.6-39c2.6-3.7 1.8-8.7-1.8-11.2z"
/>
</svg>
</i>
</span>
</span>
`;
>>>>>>> origin/master
exports[`renders ./components/time-picker/demo/hide-column.md correctly 1`] = `
<div
class="ant-picker"
>
<<<<<<< HEAD
<div
class="ant-picker-input"
>
<input
=======
<input
class="ant-time-picker-input"
placeholder="Select time"
type="text"
value="12:08"
/>
<span
class="ant-time-picker-icon"
>
<i
aria-label="icon: clock-circle"
class="anticon anticon-clock-circle ant-time-picker-clock-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="clock-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"
/>
<path
d="M686.7 638.6L544.1 535.5V288c0-4.4-3.6-8-8-8H488c-4.4 0-8 3.6-8 8v275.4c0 2.6 1.2 5 3.3 6.5l165.4 120.6c3.6 2.6 8.6 1.8 11.2-1.7l28.6-39c2.6-3.7 1.8-8.7-1.8-11.2z"
/>
</svg>
</i>
</span>
<i
aria-label="icon: close-circle"
class="anticon anticon-close-circle ant-time-picker-clear"
tabindex="-1"
>
<svg
aria-hidden="true"
class=""
data-icon="close-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 0 1-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"
/>
</svg>
</i>
</span>
`;
exports[`renders ./components/time-picker/demo/interval-options.md correctly 1`] = `
<span
class="ant-time-picker"
>
<input
class="ant-time-picker-input"
placeholder="Select time"
type="text"
value=""
/>
<span
class="ant-time-picker-icon"
>
<i
aria-label="icon: clock-circle"
class="anticon anticon-clock-circle ant-time-picker-clock-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="clock-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"
/>
<path
d="M686.7 638.6L544.1 535.5V288c0-4.4-3.6-8-8-8H488c-4.4 0-8 3.6-8 8v275.4c0 2.6 1.2 5 3.3 6.5l165.4 120.6c3.6 2.6 8.6 1.8 11.2-1.7l28.6-39c2.6-3.7 1.8-8.7-1.8-11.2z"
/>
</svg>
</i>
</span>
</span>
`;
exports[`renders ./components/time-picker/demo/size.md correctly 1`] = `
<div>
<span
class="ant-time-picker ant-time-picker-large"
>
<input
class="ant-time-picker-input"
>>>>>>> origin/master
placeholder="Select time"
readonly=""
size="10"
@ -338,6 +575,10 @@ exports[`renders ./components/time-picker/demo/interval-options.md correctly 1`]
class="ant-picker-input"
>
<input
<<<<<<< HEAD
=======
class="ant-time-picker-input"
>>>>>>> origin/master
placeholder="Select time"
readonly=""
size="10"
@ -395,6 +636,7 @@ exports[`renders ./components/time-picker/demo/range-picker.md correctly 1`] = `
<span
class="ant-picker-separator"
>
<<<<<<< HEAD
</span>
</div>
@ -411,6 +653,22 @@ exports[`renders ./components/time-picker/demo/range-picker.md correctly 1`] = `
<div
class="ant-picker-active-bar"
style="left:0;width:0;position:absolute"
=======
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 0 1-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"
/>
</svg>
</i>
</span>
<span
class="ant-time-picker ant-time-picker-small"
>
<input
class="ant-time-picker-input"
placeholder="Select time"
type="text"
value="12:08:23"
>>>>>>> origin/master
/>
<span
class="ant-picker-suffix"
@ -647,8 +905,19 @@ exports[`renders ./components/time-picker/demo/suffix.md correctly 1`] = `
<div
class="ant-picker"
>
<<<<<<< HEAD
<div
class="ant-picker-input"
=======
<input
class="ant-time-picker-input"
placeholder="Select time"
type="text"
value=""
/>
<span
class="ant-time-picker-icon"
>>>>>>> origin/master
>
<input
placeholder="Select time"
@ -688,8 +957,19 @@ exports[`renders ./components/time-picker/demo/value.md correctly 1`] = `
<div
class="ant-picker"
>
<<<<<<< HEAD
<div
class="ant-picker-input"
=======
<input
class="ant-time-picker-input"
placeholder="Select time"
type="text"
value=""
/>
<span
class="ant-time-picker-icon"
>>>>>>> origin/master
>
<input
placeholder="Select time"

View File

@ -4,6 +4,7 @@ exports[`TimePicker not render clean icon when allowClear is false 1`] = `
<div
class="ant-picker"
>
<<<<<<< HEAD
<div
class="ant-picker-input"
>
@ -11,6 +12,53 @@ exports[`TimePicker not render clean icon when allowClear is false 1`] = `
placeholder="Select time"
readonly=""
size="10"
=======
<input
class="ant-time-picker-input"
placeholder="Select time"
type="text"
value="00:00:00"
/>
<span
class="ant-time-picker-icon"
>
<i
aria-label="icon: clock-circle"
class="anticon anticon-clock-circle ant-time-picker-clock-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="clock-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"
/>
<path
d="M686.7 638.6L544.1 535.5V288c0-4.4-3.6-8-8-8H488c-4.4 0-8 3.6-8 8v275.4c0 2.6 1.2 5 3.3 6.5l165.4 120.6c3.6 2.6 8.6 1.8 11.2-1.7l28.6-39c2.6-3.7 1.8-8.7-1.8-11.2z"
/>
</svg>
</i>
</span>
</span>
`;
exports[`TimePicker prop locale should works 1`] = `
Array [
<span
class="ant-time-picker"
style=""
>
<input
class="ant-time-picker-input"
placeholder="Избери дата"
type="text"
>>>>>>> origin/master
value="00:00:00"
/>
<span

View File

@ -1892,7 +1892,11 @@ exports[`renders ./components/transfer/demo/table-transfer.md correctly 1`] = `
Tag
</th>
<th
<<<<<<< HEAD
class="ant-table-cell"
=======
class="ant-table-row-cell-last"
>>>>>>> origin/master
>
Description
</th>
@ -2551,7 +2555,11 @@ exports[`renders ./components/transfer/demo/table-transfer.md correctly 1`] = `
</div>
</th>
<th
<<<<<<< HEAD
class="ant-table-cell"
=======
class="ant-table-row-cell-last"
>>>>>>> origin/master
>
Name
</th>

View File

@ -25,7 +25,7 @@ type TransferRender = (item: TransferItem) => RenderResult;
export interface TransferItem {
key: string;
title: string;
title?: string;
description?: string;
disabled?: boolean;
[name: string]: any;

View File

@ -40,7 +40,7 @@ Tree selection control.
| suffixIcon | The custom suffix icon | ReactNode | - | |
| treeCheckable | Whether to show checkbox on the treeNodes | boolean | false | |
| treeCheckStrictly | Whether to check nodes precisely (in the `checkable` mode), means parent and child nodes are not associated, and it will make `labelInValue` be true | boolean | false | |
| treeData | Data of the treeNodes, manual construction work is no longer needed if this property has been set(ensure the Uniqueness of each value) | array\<{ value, title, children, \[disabled, disableCheckbox, selectable] }> | \[] | |
| treeData | Data of the treeNodes, manual construction work is no longer needed if this property has been set(ensure the Uniqueness of each value) | array\<{ value, title, children, \[disabled, disableCheckbox, selectable, checkable] }> | \[] | |
| treeDataSimpleMode | Enable simple mode of treeData. Changes the `treeData` schema to: \[{id:1, pId:0, value:'1', title:"test1",...},...] where pId is parent node's id). It is possible to replace the default `id` and `pId` keys by providing object to `treeDataSimpleMode` | false\|object\<{ id: string, pId: string, rootPId: string }> | false | |
| treeDefaultExpandAll | Whether to expand all treeNodes by default | boolean | false | |
| treeDefaultExpandedKeys | Default expanded treeNodes | string\[] | - | |
@ -67,6 +67,7 @@ Tree selection control.
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| selectable | can be selected | boolean | true | |
| checkable | When Tree is checkable, set TreeNode display Checkbox or not | boolean | - | |
| disableCheckbox | Disables the checkbox of the treeNode | boolean | false | |
| disabled | Disabled or not | boolean | false | |
| isLeaf | Leaf node or not | boolean | false | |

View File

@ -41,7 +41,7 @@ title: TreeSelect
| suffixIcon | 自定义的选择框后缀图标 | ReactNode | - | |
| treeCheckable | 显示 checkbox | boolean | false | |
| treeCheckStrictly | checkable 状态下节点选择完全受控(父子节点选中状态不再关联),会使得 `labelInValue` 强制为 true | boolean | false | |
| treeData | treeNodes 数据,如果设置则不需要手动构造 TreeNode 节点value 在整个树范围内唯一) | array\<{value, title, children, \[disabled, disableCheckbox, selectable]}> | \[] | |
| treeData | treeNodes 数据,如果设置则不需要手动构造 TreeNode 节点value 在整个树范围内唯一) | array\<{value, title, children, \[disabled, disableCheckbox, selectable, checkable]}> | \[] | |
| treeDataSimpleMode | 使用简单格式的 treeData具体设置参考可设置的类型 (此时 treeData 应变为这样的数据结构: \[{id:1, pId:0, value:'1', title:"test1",...},...], `pId` 是父节点的 id) | false\|object\<{ id: string, pId: string, rootPId: string }> | false | |
| treeDefaultExpandAll | 默认展开所有树节点 | boolean | false | |
| treeDefaultExpandedKeys | 默认展开的树节点 | string\[] | - | |
@ -68,6 +68,7 @@ title: TreeSelect
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| selectable | 是否可选 | boolean | true | |
| checkable | 当树为 checkable 时,设置独立节点是否展示 Checkbox | boolean | - | |
| disableCheckbox | 禁掉 checkbox | boolean | false | |
| disabled | 是否禁用 | boolean | false | |
| isLeaf | 是否是叶子节点 | boolean | false | |

View File

@ -308,8 +308,37 @@ exports[`renders ./components/tree/demo/basic-controlled.md correctly 1`] = `
class="ant-tree-list-holder-inner"
style="display:flex;flex-direction:column"
>
<<<<<<< HEAD
<div
class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-indeterminate"
=======
<span
class="ant-tree-switcher ant-tree-switcher-noop"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-tree-switcher-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
/>
</svg>
</i>
</span>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal ant-tree-node-selected"
title="leaf"
>>>>>>> origin/master
>
<span
class="ant-tree-switcher ant-tree-switcher_open"
@ -342,6 +371,7 @@ exports[`renders ./components/tree/demo/basic-controlled.md correctly 1`] = `
class="ant-tree-checkbox-inner"
/>
</span>
<<<<<<< HEAD
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"
title="0-0"
@ -355,6 +385,40 @@ exports[`renders ./components/tree/demo/basic-controlled.md correctly 1`] = `
</div>
<div
class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked"
=======
</span>
</li>
<li
class="ant-tree-treenode-switcher-open"
role="treeitem"
>
<span
class="ant-tree-switcher ant-tree-switcher-noop"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-tree-switcher-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
/>
</svg>
</i>
</span>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
title="leaf"
>>>>>>> origin/master
>
<span
aria-hidden="true"
@ -975,6 +1039,7 @@ exports[`renders ./components/tree/demo/directory.md correctly 1`] = `
tabindex="0"
value=""
/>
<<<<<<< HEAD
</div>
<div
class="ant-tree-list"
@ -986,19 +1051,129 @@ exports[`renders ./components/tree/demo/directory.md correctly 1`] = `
>
<div
class="ant-tree-treenode ant-tree-treenode-switcher-open"
=======
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
title="Tree Node"
>
<span
class="ant-tree-title"
>
Tree Node
</span>
</span>
</li>
</ul>
`;
exports[`renders ./components/tree/demo/line.md correctly 1`] = `
<div>
<div
style="margin-bottom:16px"
>
showLine:
<button
aria-checked="true"
checked=""
class="ant-switch ant-switch-checked"
role="switch"
type="button"
>
<span
class="ant-switch-inner"
/>
</button>
<br />
<br />
showIcon:
<button
aria-checked="false"
class="ant-switch"
role="switch"
type="button"
>
<span
class="ant-switch-inner"
/>
</button>
</div>
<ul
class="ant-tree ant-tree-icon-hide ant-tree-show-line"
role="tree"
unselectable="on"
>
<li
class="ant-tree-treenode-switcher-open"
role="treeitem"
>
<span
class="ant-tree-switcher ant-tree-switcher_open"
>
<i
aria-label="icon: minus-square"
class="anticon anticon-minus-square ant-tree-switcher-line-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="minus-square"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M328 544h368c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H328c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8z"
/>
<path
d="M880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32zm-40 728H184V184h656v656z"
/>
</svg>
</i>
</span>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"
title="parent 1"
>
<span
class="ant-tree-title"
>
parent 1
</span>
</span>
<ul
class="ant-tree-child-tree ant-tree-child-tree-open"
data-expanded="true"
role="group"
>
<li
class="ant-tree-treenode-switcher-open"
role="treeitem"
>>>>>>> origin/master
>
<span
class="ant-tree-switcher ant-tree-switcher_open"
>
<<<<<<< HEAD
<span
aria-label="caret-down"
class="anticon anticon-caret-down ant-tree-switcher-icon"
role="img"
=======
<i
aria-label="icon: minus-square"
class="anticon anticon-minus-square ant-tree-switcher-line-icon"
>>>>>>> origin/master
>
<svg
aria-hidden="true"
class=""
<<<<<<< HEAD
data-icon="caret-down"
=======
data-icon="minus-square"
>>>>>>> origin/master
fill="currentColor"
focusable="false"
height="1em"
@ -1006,6 +1181,7 @@ exports[`renders ./components/tree/demo/directory.md correctly 1`] = `
width="1em"
>
<path
<<<<<<< HEAD
d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"
/>
</svg>
@ -1071,17 +1247,66 @@ exports[`renders ./components/tree/demo/directory.md correctly 1`] = `
aria-label="file"
class="anticon anticon-file"
role="img"
=======
d="M328 544h368c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H328c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8z"
/>
<path
d="M880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32zm-40 728H184V184h656v656z"
/>
</svg>
</i>
</span>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"
title="parent 1-0"
>
<span
class="ant-tree-title"
>
parent 1-0
</span>
</span>
<ul
class="ant-tree-child-tree ant-tree-child-tree-open"
data-expanded="true"
role="group"
>
<li
class="ant-tree-treenode-switcher-close"
role="treeitem"
>
<span
class="ant-tree-switcher ant-tree-switcher-noop"
>
<svg
aria-hidden="true"
class=""
data-icon="file"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
<i
aria-label="icon: file"
class="anticon anticon-file ant-tree-switcher-line-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="file"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0 0 42 42h216v494z"
/>
</svg>
</i>
</span>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
title="leaf"
>>>>>>> origin/master
>
<span
class="ant-tree-title"
>
<<<<<<< HEAD
<path
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"
/>
@ -1120,17 +1345,47 @@ exports[`renders ./components/tree/demo/directory.md correctly 1`] = `
aria-label="file"
class="anticon anticon-file"
role="img"
=======
leaf
</span>
</span>
</li>
<li
class="ant-tree-treenode-switcher-close"
role="treeitem"
>
<span
class="ant-tree-switcher ant-tree-switcher-noop"
>
<svg
aria-hidden="true"
class=""
data-icon="file"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
<i
aria-label="icon: file"
class="anticon anticon-file ant-tree-switcher-line-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="file"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0 0 42 42h216v494z"
/>
</svg>
</i>
</span>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
title="leaf"
>>>>>>> origin/master
>
<span
class="ant-tree-title"
>
<<<<<<< HEAD
<path
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"
/>
@ -1316,6 +1571,274 @@ exports[`renders ./components/tree/demo/draggable.md correctly 1`] = `
>
<div
role="tree"
=======
leaf
</span>
</span>
</li>
<li
class="ant-tree-treenode-switcher-close"
role="treeitem"
>
<span
class="ant-tree-switcher ant-tree-switcher-noop"
>
<i
aria-label="icon: file"
class="anticon anticon-file ant-tree-switcher-line-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="file"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0 0 42 42h216v494z"
/>
</svg>
</i>
</span>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
title="leaf"
>
<span
class="ant-tree-title"
>
leaf
</span>
</span>
</li>
</ul>
</li>
<li
class="ant-tree-treenode-switcher-open"
role="treeitem"
>
<span
class="ant-tree-switcher ant-tree-switcher_open"
>
<i
aria-label="icon: minus-square"
class="anticon anticon-minus-square ant-tree-switcher-line-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="minus-square"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M328 544h368c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H328c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8z"
/>
<path
d="M880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32zm-40 728H184V184h656v656z"
/>
</svg>
</i>
</span>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"
title="parent 1-1"
>
<span
class="ant-tree-title"
>
parent 1-1
</span>
</span>
<ul
class="ant-tree-child-tree ant-tree-child-tree-open"
data-expanded="true"
role="group"
>
<li
class="ant-tree-treenode-switcher-close"
role="treeitem"
>
<span
class="ant-tree-switcher ant-tree-switcher-noop"
>
<i
aria-label="icon: file"
class="anticon anticon-file ant-tree-switcher-line-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="file"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0 0 42 42h216v494z"
/>
</svg>
</i>
</span>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
title="leaf"
>
<span
class="ant-tree-title"
>
leaf
</span>
</span>
</li>
</ul>
</li>
<li
class="ant-tree-treenode-switcher-open"
role="treeitem"
>
<span
class="ant-tree-switcher ant-tree-switcher_open"
>
<i
aria-label="icon: minus-square"
class="anticon anticon-minus-square ant-tree-switcher-line-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="minus-square"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M328 544h368c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H328c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8z"
/>
<path
d="M880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32zm-40 728H184V184h656v656z"
/>
</svg>
</i>
</span>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"
title="parent 1-2"
>
<span
class="ant-tree-title"
>
parent 1-2
</span>
</span>
<ul
class="ant-tree-child-tree ant-tree-child-tree-open"
data-expanded="true"
role="group"
>
<li
class="ant-tree-treenode-switcher-close"
role="treeitem"
>
<span
class="ant-tree-switcher ant-tree-switcher-noop"
>
<i
aria-label="icon: file"
class="anticon anticon-file ant-tree-switcher-line-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="file"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0 0 42 42h216v494z"
/>
</svg>
</i>
</span>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
title="leaf"
>
<span
class="ant-tree-title"
>
leaf
</span>
</span>
</li>
<li
class="ant-tree-treenode-switcher-close"
role="treeitem"
>
<span
class="ant-tree-switcher ant-tree-switcher-noop"
>
<i
aria-label="icon: form"
class="anticon anticon-form"
>
<svg
aria-hidden="true"
class=""
data-icon="form"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M904 512h-56c-4.4 0-8 3.6-8 8v320H184V184h320c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V520c0-4.4-3.6-8-8-8z"
/>
<path
d="M355.9 534.9L354 653.8c-.1 8.9 7.1 16.2 16 16.2h.4l118-2.9c2-.1 4-.9 5.4-2.3l415.9-415c3.1-3.1 3.1-8.2 0-11.3L785.4 114.3c-1.6-1.6-3.6-2.3-5.7-2.3s-4.1.8-5.7 2.3l-415.8 415a8.3 8.3 0 0 0-2.3 5.6zm63.5 23.6L779.7 199l45.2 45.1-360.5 359.7-45.7 1.1.7-46.4z"
/>
</svg>
</i>
</span>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
title="leaf"
>
<span
class="ant-tree-title"
>
leaf
</span>
</span>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
`;
exports[`renders ./components/tree/demo/search.md correctly 1`] = `
<div>
<span
class="ant-input-search ant-input-affix-wrapper"
style="margin-bottom:8px"
>>>>>>> origin/master
>
<input
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
@ -2175,6 +2698,7 @@ exports[`renders ./components/tree/demo/search.md correctly 1`] = `
<div
role="tree"
>
<<<<<<< HEAD
<input
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
tabindex="0"
@ -2191,19 +2715,64 @@ exports[`renders ./components/tree/demo/search.md correctly 1`] = `
>
<div
class="ant-tree-treenode ant-tree-treenode-switcher-close"
=======
<li
class="ant-tree-treenode-switcher-open"
role="treeitem"
>
<span
class="ant-tree-switcher ant-tree-switcher_open"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-tree-switcher-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
/>
</svg>
</i>
</span>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"
title="parent 1-0"
>
<span
class="ant-tree-title"
>
parent 1-0
</span>
</span>
<ul
class="ant-tree-child-tree ant-tree-child-tree-open"
data-expanded="true"
role="group"
>
<li
class="ant-tree-treenode-switcher-close"
role="treeitem"
>
<span
class="ant-tree-switcher ant-tree-switcher_close"
class="ant-tree-switcher ant-tree-switcher-noop"
>
<span
aria-label="caret-down"
class="anticon anticon-caret-down ant-tree-switcher-icon"
role="img"
<i
aria-label="icon: down"
class="anticon anticon-down ant-tree-switcher-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="caret-down"
data-icon="down"
fill="currentColor"
focusable="false"
height="1em"
@ -2211,7 +2780,61 @@ exports[`renders ./components/tree/demo/search.md correctly 1`] = `
width="1em"
>
<path
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
/>
</svg>
</i>
</span>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
title="leaf"
>
<span
class="ant-tree-title"
>
leaf
</span>
</span>
</li>
<li
class="ant-tree-treenode-switcher-close"
role="treeitem"
>>>>>>> origin/master
>
<span
class="ant-tree-switcher ant-tree-switcher_close"
>
<<<<<<< HEAD
<span
aria-label="caret-down"
class="anticon anticon-caret-down ant-tree-switcher-icon"
role="img"
=======
<i
aria-label="icon: down"
class="anticon anticon-down ant-tree-switcher-icon"
>>>>>>> origin/master
>
<svg
aria-hidden="true"
class=""
<<<<<<< HEAD
data-icon="caret-down"
=======
data-icon="down"
>>>>>>> origin/master
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
<<<<<<< HEAD
d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"
=======
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
>>>>>>> origin/master
/>
</svg>
</span>
@ -2238,15 +2861,25 @@ exports[`renders ./components/tree/demo/search.md correctly 1`] = `
<span
class="ant-tree-switcher ant-tree-switcher_close"
>
<<<<<<< HEAD
<span
aria-label="caret-down"
class="anticon anticon-caret-down ant-tree-switcher-icon"
role="img"
=======
<i
aria-label="icon: down"
class="anticon anticon-down ant-tree-switcher-icon"
>>>>>>> origin/master
>
<svg
aria-hidden="true"
class=""
<<<<<<< HEAD
data-icon="caret-down"
=======
data-icon="down"
>>>>>>> origin/master
fill="currentColor"
focusable="false"
height="1em"
@ -2254,7 +2887,11 @@ exports[`renders ./components/tree/demo/search.md correctly 1`] = `
width="1em"
>
<path
<<<<<<< HEAD
d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"
=======
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
>>>>>>> origin/master
/>
</svg>
</span>

View File

@ -0,0 +1,102 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Tree icon and switcherIcon of Tree with showLine should render correctly 1`] = `
<ul
class="ant-tree ant-tree-show-line"
role="tree"
unselectable="on"
>
<li
class="ant-tree-treenode-switcher-close"
role="treeitem"
>
<span
class="ant-tree-switcher ant-tree-switcher_close"
>
switcherIcon
</span>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-close"
title="---"
>
<span
class="ant-tree-iconEle ant-tree-icon__customize"
>
icon
</span>
<span
class="ant-tree-title"
>
---
</span>
</span>
</li>
<li
class="ant-tree-treenode-switcher-close"
role="treeitem"
>
<span
class="ant-tree-switcher ant-tree-switcher_close"
>
switcherIcon
</span>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-close"
title="---"
>
<span
class="ant-tree-iconEle ant-tree-icon__close"
/>
<span
class="ant-tree-title"
>
---
</span>
</span>
</li>
<li
class="ant-tree-treenode-switcher-close"
role="treeitem"
>
<span
class="ant-tree-switcher ant-tree-switcher_close"
>
<i
aria-label="icon: plus-square"
class="anticon anticon-plus-square ant-tree-switcher-line-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="plus-square"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M328 544h152v152c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V544h152c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H544V328c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v152H328c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8z"
/>
<path
d="M880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32zm-40 728H184V184h656v656z"
/>
</svg>
</i>
</span>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-close"
title="---"
>
<span
class="ant-tree-iconEle ant-tree-icon__close"
/>
<span
class="ant-tree-title"
>
---
</span>
</span>
</li>
</ul>
`;

View File

@ -0,0 +1,33 @@
import React from 'react';
import { mount } from 'enzyme';
import Tree from '../index';
const { TreeNode } = Tree;
describe('Tree', () => {
it('icon and switcherIcon of Tree with showLine should render correctly', () => {
const wrapper = mount(
<Tree showLine showIcon>
<TreeNode icon="icon" switcherIcon="switcherIcon" key="0-0">
<TreeNode icon="icon" switcherIcon="switcherIcon" key="0-0-0" />
<TreeNode switcherIcon="switcherIcon" key="0-0-1" />
<TreeNode icon="icon" key="0-0-2" />
<TreeNode key="0-0-3" />
</TreeNode>
<TreeNode switcherIcon="switcherIcon" key="0-1">
<TreeNode icon="icon" switcherIcon="switcherIcon" key="0-0-0" />
<TreeNode switcherIcon="switcherIcon" key="0-0-1" />
<TreeNode icon="icon" key="0-0-2" />
<TreeNode key="0-0-3" />
</TreeNode>
<TreeNode key="0-2">
<TreeNode icon="icon" switcherIcon="switcherIcon" key="0-0-0" />
<TreeNode switcherIcon="switcherIcon" key="0-0-1" />
<TreeNode icon="icon" key="0-0-2" />
<TreeNode key="0-0-3" />
</TreeNode>
</Tree>,
);
expect(wrapper.render()).toMatchSnapshot();
});
});

View File

@ -2,54 +2,86 @@
order: 5
title:
zh-CN: 连接线
en-US: Tree With Line
en-US: Tree with line
---
## zh-CN
带连接线的树。
节点之间带连接线的树,常用于文件目录结构展示。使用 `showLine` 开启,可以用 `switcherIcon` 修改默认图标
## en-US
Tree With Line
Tree with connected line between nodes, turn on by `showLine`, customize the preseted icon by `switcherIcon`.
```tsx
import { Tree } from 'antd';
import { Tree, Switch } from 'antd';
import { CarryOutOutlined, FormOutlined } from '@ant-design/icons';
const treeData = [
{
title: 'parent 1',
key: '0-0',
icon: <CarryOutOutlined />,
children: [
{
title: 'parent 1-0',
key: '0-0-0',
icon: <CarryOutOutlined />,
children: [
{ title: 'leaf', key: '0-0-0-0' },
{ title: 'leaf', key: '0-0-0-1' },
{ title: 'leaf', key: '0-0-0-2' },
{ title: 'leaf', key: '0-0-0-0', icon: <CarryOutOutlined /> },
{ title: 'leaf', key: '0-0-0-1', icon: <CarryOutOutlined /> },
{ title: 'leaf', key: '0-0-0-2', icon: <CarryOutOutlined /> },
],
},
{
title: 'parent 1-1',
key: '0-0-1',
children: [{ title: 'leaf', key: '0-0-1-0' }],
icon: <CarryOutOutlined />,
children: [{ title: 'leaf', key: '0-0-1-0', icon: <CarryOutOutlined /> }],
},
{
title: 'parent 1-2',
key: '0-0-2',
children: [{ title: 'leaf', key: '0-0-2-0' }, { title: 'leaf', key: '0-0-2-1' }],
icon: <CarryOutOutlined />,
children: [
{ title: 'leaf', key: '0-0-2-0', icon: <CarryOutOutlined /> },
{
title: 'leaf',
key: '0-0-2-1',
icon: <CarryOutOutlined />,
switcherIcon: <FormOutlined />,
},
],
},
],
},
];
const Demo: React.FC<{}> = () => {
const [showLine, setShowLine] = React.useState(true);
const [showIcon, setShowIcon] = React.useState(false);
const onSelect = (selectedKeys, info) => {
console.log('selected', selectedKeys, info);
};
return <Tree showLine defaultExpandedKeys={['0-0-0']} onSelect={onSelect} treeData={treeData} />;
return (
<div>
<div style={{ marginBottom: 16 }}>
showLine: <Switch checked={showLine} onChange={setShowLine} />
<br />
<br />
showIcon: <Switch checked={showIcon} onChange={setShowIcon} />
</div>
<Tree
showLine={showLine}
showIcon={showIcon}
defaultExpandedKeys={['0-0-0']}
onSelect={onSelect}
treeData={treeData}
/>
</div>
);
};
ReactDOM.render(<Demo />, mountNode);

View File

@ -38,7 +38,7 @@ Almost anything can be represented in a tree structure. Examples include directo
| showIcon | Shows the icon before a TreeNode's title. There is no default style; you must set a custom style for it if set to `true` | boolean | false |
| switcherIcon | customize collapse/expand icon of tree node | React.ReactElement | - |
| showLine | Shows a connecting line | boolean | false |
| onCheck | Callback function for when the onCheck event occurs | function(checkedKeys, e:{checked: bool, checkedNodes, node, event}) | - |
| onCheck | Callback function for when the onCheck event occurs | function(checkedKeys, e:{checked: bool, checkedNodes, node, event, halfCheckedKeys}) | - |
| onDragEnd | Callback function for when the onDragEnd event occurs | function({event, node}) | - |
| onDragEnter | Callback function for when the onDragEnter event occurs | function({event, node, expandedKeys}) | - |
| onDragLeave | Callback function for when the onDragLeave event occurs | function({event, node}) | - |

View File

@ -39,7 +39,7 @@ subtitle: 树形控件
| showIcon | 是否展示 TreeNode title 前的图标,没有默认样式,如设置为 true需要自行定义图标相关样式 | boolean | false |
| switcherIcon | 自定义树节点的展开/折叠图标 | React.ReactElement | - |
| showLine | 是否展示连接线 | boolean | false |
| onCheck | 点击复选框触发 | function(checkedKeys, e:{checked: bool, checkedNodes, node, event}) | - |
| onCheck | 点击复选框触发 | function(checkedKeys, e:{checked: bool, checkedNodes, node, event, halfCheckedKeys}) | - |
| onDragEnd | dragend 触发时调用 | function({event, node}) | - |
| onDragEnter | dragenter 触发时调用 | function({event, node, expandedKeys}) | - |
| onDragLeave | dragleave 触发时调用 | function({event, node}) | - |

View File

@ -1,7 +1,7 @@
import * as React from 'react';
import KeyCode from 'rc-util/lib/KeyCode';
import classNames from 'classnames';
import { EnterOutlined } from '@ant-design/icons';
import TextArea from '../input/TextArea';
interface EditableProps {
@ -114,7 +114,7 @@ class Editable extends React.Component<EditableProps, EditableState> {
const { prefixCls, 'aria-label': ariaLabel, className, style } = this.props;
return (
<div className={`${prefixCls} ${prefixCls}-edit-content ${className}`} style={style}>
<div className={classNames(prefixCls, `${prefixCls}-edit-content`, className)} style={style}>
<TextArea
ref={this.setTextarea}
value={current}

View File

@ -7,11 +7,11 @@ title:
## zh-CN
提供额外的交互能力。
提供可编辑和可复制等额外的交互能力。
## en-US
Provide additional interactive capacity.
Provide additional interactive capacity of editable and copyable.
```jsx
import { Typography } from 'antd';

View File

@ -25,6 +25,7 @@ cols: 1
| editable | 是否可编辑,为对象时可对编辑进行控制 | boolean \| { editing: boolean, onStart: Function, onChange: Function(string) } | false | |
| ellipsis | 设置自动溢出省略 | boolean | false | |
| mark | 添加标记样式 | boolean | false | |
| code | 添加代码样式 | boolean | false | |
| underline | 添加下划线样式 | boolean | false | |
| strong | 是否加粗 | boolean | false | |
| type | 文本类型 | `secondary`, `warning`, `danger` | - | |

View File

@ -156,6 +156,11 @@
color: @text-color-secondary;
pointer-events: none;
}
// Fix Editable Textarea flash in Firefox
textarea {
-moz-transition: none;
}
}
// list

View File

@ -188,7 +188,7 @@ describe('Upload', () => {
});
});
it('should increase percent automaticly when call autoUpdateProgress in IE', done => {
it('should increase percent automatically when call autoUpdateProgress in IE', done => {
let uploadInstance;
let lastPercent = -1;
const props = {

View File

@ -73,7 +73,10 @@ export const isImageUrl = (file: UploadFile): boolean => {
}
const url: string = (file.thumbUrl || file.url) as string;
const extension = extname(url);
if (/^data:image\//.test(url) || /(webp|svg|png|gif|jpg|jpeg|jfif|bmp|dpg)$/i.test(extension)) {
if (
/^data:image\//.test(url) ||
/(webp|svg|png|gif|jpg|jpeg|jfif|bmp|dpg|ico)$/i.test(extension)
) {
return true;
}
if (/^data:/.test(url)) {

View File

@ -3,7 +3,7 @@ order: 6
title: Customize Theme
---
Ant Design allows you to customize our design tokens in order to meet the needs of UI diversity from business and brand, including primary color, border radius, border color, etc.
Ant Design allows you to customize our design tokens to satisfy UI diversity from business or brand requirements, including primary color, border radius, border color, etc.
![customized themes](https://zos.alipayobjects.com/rmsportal/zTFoszBtDODhXfLAazfSpYbSLSEeytoG.png)

View File

@ -9,7 +9,7 @@ Here are the frequently asked questions about Ant Design and antd that you shoul
### Are you going to provide Sass/Stylus(etc.) style file?
No, but you can convert Less to Sass/Stylus(etc.) with tools that you can find on Google.
No plan, but you can convert Less to Sass/Stylus(etc.) with tools that you can find on Google.
### `Select Dropdown DatePicker TimePicker Popover Popconfirm` disappears when I click another popup component inside it. How do I resolve this?

View File

@ -9,7 +9,7 @@ title: FAQ
### 你们会提供 Sass/Stylus 等格式的样式文件吗?
。事实上你可以使用工具(请自行 Google将 Less 转换成 Sass/Stylus 等。
暂无计划。事实上你可以使用工具(请自行 Google将 Less 转换成 Sass/Stylus 等。
### 当我点击 `Select Dropdown DatePicker TimePicker Popover Popconfirm` 内的另一个 popup 组件时它会消失,如何解决?

View File

@ -5,15 +5,23 @@ title: Getting Started
Ant Design React is dedicated to providing a **good development experience** for programmers. Make sure that you have installed [Node.js](https://nodejs.org/)(> 8.0.0) correctly.
If you try in local environment, Please refer to [Install and Initialization](https://ant.design/docs/react/use-with-create-react-app#Install-and-Initialization) section of "Use in create-react-app".
> Before delving into Ant Design React, a good knowledge base of [React](https://reactjs.org) and [JavaScript ES2015](http://babeljs.io/docs/learn-es2015/) is needed.
---
## First Example
Here is a simple example to show usage of Ant Design React.
Here is a simple codesandbox example to show the usage of Ant Design React.
<iframe src="https://codesandbox.io/embed/wk04r016q8?fontsize=14" style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;" sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"></iframe>
<iframe
src="https://codesandbox.io/embed/antd-reproduction-template-6e93z?autoresize=1&fontsize=14&hidenavigation=1&theme=dark"
style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;"
title="antd reproduction template"
allow="geolocation; microphone; camera; midi; vr; accelerometer; gyroscope; payment; ambient-light-sensor; encrypted-media; usb"
sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"
/>
### 1. Create one codesandbox
@ -23,6 +31,8 @@ Visit http://u.ant.design/codesandbox-repro to create a codesandbox. Don't forge
Replace the content of `index.js` with the following code. As you can see, there is no difference between antd's components and typical React components.
If you already set up by [Install and Initialization](https://ant.design/docs/react/use-with-create-react-app#Install-and-Initialization) section of "Use in create-react-app", Please replace the content of /src/index.js
```jsx
import React from 'react';
import ReactDOM from 'react-dom';

View File

@ -11,9 +11,15 @@ Ant Design React 致力于提供给程序员**愉悦**的开发体验。
## 第一个例子
这是一个最简单的 Ant Design 组件的在线演示。
这是一个最简单的 Ant Design 组件的在线 codesandbox 演示。
<iframe src="https://codesandbox.io/embed/wk04r016q8?fontsize=14" style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;" sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"></iframe>
<iframe
src="https://codesandbox.io/embed/antd-reproduction-template-6e93z?autoresize=1&fontsize=14&hidenavigation=1&theme=dark"
style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;"
title="antd reproduction template"
allow="geolocation; microphone; camera; midi; vr; accelerometer; gyroscope; payment; ambient-light-sensor; encrypted-media; usb"
sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"
/>
### 1. 创建一个 codesandbox

View File

@ -7,7 +7,7 @@ The default language of `antd@2.x` is English as of yet. If you want to use othe
## ConfigProvider
antd provides a React Component [ConfigProvider](/components/config-provider) for configuring antd locale text globally.
`antd` provides a React Component [ConfigProvider](/components/config-provider) for configuring antd locale text globally.
```jsx
import { ConfigProvider } from 'antd';
@ -29,7 +29,6 @@ Supported languages:
| Language | Filename |
| --------------------- | -------- |
| Arabic | ar_EG |
| Armenian | hy_AM |
| Bulgarian | bg_BG |
| Catalan | ca_ES |
| Czech | cs_CZ |
@ -47,12 +46,14 @@ Supported languages:
| Croatian | hr_HR |
| Hindi | hi_IN |
| Hungarian | hu_HU |
| Armenian | hy_AM |
| Indonesian | id_ID |
| Italian | it_IT |
| Icelandic | is_IS |
| Japanese | ja_JP |
| Kannada | kn_IN |
| Korean | ko_KR |
| Latvian | lv_LV |
| Macedonian | mk_MK |
| Norwegian | nb_NO |
| Nepal | ne_NP |
@ -61,6 +62,8 @@ Supported languages:
| Polish | pl_PL |
| Portuguese (Brazil) | pt_BR |
| Portuguese | pt_PT |
| Romanian | ro_RO |
| Russian | ru_RU |
| Slovak | sk_SK |
| Serbian | sr_RS |
| Slovenian | sl_SI |
@ -68,8 +71,6 @@ Supported languages:
| Tamil | ta_IN |
| Thai | th_TH |
| Turkish | tr_TR |
| Romanian | ro_RO |
| Russian | ru_RU |
| Ukrainian | uk_UA |
| Vietnamese | vi_VN |
| Chinese (Simplified) | zh_CN |

View File

@ -28,7 +28,6 @@ return (
| 语言 | 文件名 |
| ---------------- | ------ |
| 阿拉伯语 | ar_EG |
| 亚美尼亚 | hy_AM |
| 保加利亚语 | bg_BG |
| 加泰罗尼亚语 | ca_ES |
| 捷克语 | cs_CZ |
@ -46,12 +45,14 @@ return (
| 印地语 | hi_IN |
| 克罗地亚语 | hr_HR |
| 匈牙利语 | hu_HU |
| 亚美尼亚 | hy_AM |
| 冰岛语 | is_IS |
| 印度尼西亚语 | id_ID |
| 意大利语 | it_IT |
| 日语 | ja_JP |
| 卡纳达语 | kn_IN |
| 韩语/朝鲜语 | ko_KR |
| 拉脱维亚语 | lv_LV |
| 马其顿语 | mk_MK |
| 挪威语 | nb_NO |
| 尼泊尔语 | ne_NP |
@ -60,6 +61,8 @@ return (
| 波兰语 | pl_PL |
| 葡萄牙语(巴西) | pt_BR |
| 葡萄牙语 | pt_PT |
| 罗马尼亚语 | ro_RO |
| 俄罗斯语 | ru_RU |
| 斯洛伐克语 | sk_SK |
| 塞尔维亚语 | sr_RS |
| 斯洛文尼亚语 | sl_SI |
@ -67,8 +70,6 @@ return (
| 泰米尔语 | ta_IN |
| 泰语 | th_TH |
| 土耳其语 | tr_TR |
| 罗马尼亚语 | ro_RO |
| 俄罗斯语 | ru_RU |
| 乌克兰语 | uk_UA |
| 越南语 | vi_VN |
| 简体中文 | zh_CN |

View File

@ -25,12 +25,14 @@ Following the Ant Design specification, we developed a React UI library `antd` t
---
## Features
## Features
- An enterprise-class UI design language for web applications.
- A set of high-quality React components out of the box.
- Written in TypeScript with complete defined types.
- The whole package of development and design resources and tools.
- 🌈 Enterprise-class UI designed for web applications.
- 📦 A set of high-quality React components out of the box.
- 🛡 Written in TypeScript with predictable static types.
- ⚙️ Whole package of design resources and development tools.
- 🌍 Internationalization support for dozens of languages.
- 🎨 Powerful theme customization in every detail.
## Environment Support

View File

@ -25,12 +25,14 @@ title: Ant Design of React
---
## 特性
## 特性
- 提炼自企业级中后台产品的交互语言和视觉风格。
- 开箱即用的高质量 React 组件。
- 使用 TypeScript 构建,提供完整的类型定义文件。
- 全链路开发和设计工具体系。
- 🌈 提炼自企业级中后台产品的交互语言和视觉风格。
- 📦 开箱即用的高质量 React 组件。
- 🛡 使用 TypeScript 开发,提供完整的类型定义文件。
- ⚙️ 全链路开发和设计工具体系。
- 🌍 数十个国际化语言支持。
- 🎨 深入每个细节的主题定制能力。
## 支持环境

View File

@ -11,10 +11,14 @@ Let's create a TypeScript project by using `create-react-app`, then import `antd
Ensure your system has installed latest version of [yarn](https://yarnpkg.com) or [npm](https://www.npmjs.com/).
Create a new project named `antd-demo-ts` using yarn.
Create a new [cra-template-typescript](https://github.com/facebook/create-react-app/tree/master/packages/cra-template-typescript) project named `antd-demo-ts` using yarn.
```bash
$ yarn create react-app antd-demo-ts --typescript
$ yarn create react-app antd-demo-ts --template typescript
# or
npx create-react-app my-app --template typescript
```
If you are using npm (we will use yarn in the following instructions, it's ok to replace yarn with npm)

View File

@ -11,10 +11,14 @@ title: 在 TypeScript 中使用
请确保电脑上已经安装了最新版的 [yarn](https://yarnpkg.com) 或者 [npm](https://www.npmjs.com/)。
使用 yarn 创建项目。
使用 yarn 创建 [cra-template-typescript](https://github.com/facebook/create-react-app/tree/master/packages/cra-template-typescript) 项目。
```bash
$ yarn create react-app antd-demo-ts --typescript
$ yarn create react-app antd-demo-ts --template typescript
# or
npx create-react-app my-app --template typescript
```
如果你使用的是 npm接下来我们都会用 yarn 作为例子,如果你习惯用 npm 也没问题)。

View File

@ -13,6 +13,10 @@ Before all start, you may need install [yarn](https://github.com/yarnpkg/yarn/).
```bash
$ yarn create react-app antd-demo
# or
$ npx create-react-app antd-demo
```
The tool will create and initialize environment and dependencies automatically, please try config your proxy setting or use another npm registry if any network errors happen during it.
@ -55,19 +59,15 @@ $ yarn add antd
Modify `src/App.js`, import Button component from `antd`.
```jsx
import React, { Component } from 'react';
import Button from 'antd/es/button';
import React from 'react';
import { Button } from 'antd';
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
<Button type="primary">Button</Button>
</div>
);
}
}
const App = () => (
<div className="App">
<Button type="primary">Button</Button>
</div>
);
export default App;
```
@ -86,9 +86,11 @@ Add `antd/dist/antd.css` at the top of `src/App.css`.
Ok, you should now see a blue primary button displayed on the page. Next you can choose any components of `antd` to develop your application. Visit other workflows of `create-react-app` at its [User Guide ](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md).
We are successfully running antd components now, go build your own application!
## Advanced Guides
We are successfully running antd components now but in the real world, there are still lots of problems about antd-demo. For instance, we actually import styles of all components in the project which may be a css bundle size issue (It is OK then if you don't care the gzipped 60kb css file size).
In the real world, there are still lots of problems about antd-demo. For instance, we actually import styles of all components in the project which may be a css bundle size issue (It is OK then if you don't care the gzipped 60kb css file size).
Now we need to customize the default webpack config. We can achieve that by using [react-app-rewired](https://github.com/timarney/react-app-rewired) which is one of create-react-app's custom config solutions.

View File

@ -13,6 +13,10 @@ title: 在 create-react-app 中使用
```bash
$ yarn create react-app antd-demo
# or
$ npx create-react-app antd-demo
```
工具会自动初始化一个脚手架并安装 React 项目的各种必要依赖,如果在过程中出现网络问题,请尝试配置代理或使用其他 npm registry。
@ -55,19 +59,15 @@ $ yarn add antd
修改 `src/App.js`,引入 antd 的按钮组件。
```jsx
import React, { Component } from 'react';
import Button from 'antd/es/button';
import React from 'react';
import { Button } from 'antd';
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
<Button type="primary">Button</Button>
</div>
);
}
}
const App = () => (
<div className="App">
<Button type="primary">Button</Button>
</div>
);
export default App;
```
@ -86,9 +86,11 @@ export default App;
好了,现在你应该能看到页面上已经有了 antd 的蓝色按钮组件,接下来就可以继续选用其他组件开发应用了。其他开发流程你可以参考 create-react-app 的[官方文档](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md)。
我们现在已经把 antd 组件成功运行起来了,开始开发你的应用吧!
## 高级配置
我们现在已经把组件成功运行起来了,但是在实际开发过程中还有很多问题,例如上面的例子实际上加载了全部的 antd 组件的样式gzipped 后一共大约 60kb
这个例子在实际开发中还有一些优化的空间,比如无法进行主题配置,而且上面的例子加载了全部的 antd 组件的样式gzipped 后一共大约 60kb
此时我们需要对 create-react-app 的默认配置进行自定义,这里我们使用 [react-app-rewired](https://github.com/timarney/react-app-rewired) (一个对 create-react-app 进行自定义配置的社区解决方案)。

View File

@ -54,6 +54,11 @@ const LinksList = () => (
<li>
<a href="http://vue.ant.design" target="_blank">Ant Design of Vue<LinkIcon /></a>
</li>
<li>
<a href="https://ecomfe.github.io/santd" target="_blank">
San UI Toolkit for Ant Design<LinkIcon />
</a>
</li>
<li>
<a href="https://github.com/FE-Driver/vue-beauty" target="_blank">
vue-beauty (vue)<LinkIcon />

View File

@ -55,6 +55,11 @@ const LinksList = () => (
<li>
<a href="http://vue.ant.design" target="_blank">Ant Design of Vue<LinkIcon /></a>
</li>
<li>
<a href="https://ecomfe.github.io/santd" target="_blank">
San UI Toolkit for Ant Design<LinkIcon />
</a>
</li>
<li>
<a href="https://github.com/FE-Driver/vue-beauty" target="_blank">
vue-beauty (vue)<LinkIcon />

View File

@ -38,6 +38,7 @@
],
"main": "lib/index.js",
"module": "es/index.js",
"unpkg": "dist/antd.min.js",
"typings": "lib/index.d.ts",
"scripts": {
"api-collection": "antd-tools run api-collection",
@ -103,8 +104,8 @@
"rc-cascader": "~1.0.0-alpha.0",
"rc-checkbox": "~2.1.6",
"rc-collapse": "~1.11.3",
"rc-dialog": "~7.5.2",
"rc-drawer": "~3.0.0",
"rc-dialog": "~7.6.0",
"rc-drawer": "~3.1.1",
"rc-dropdown": "~3.0.0-alpha.0",
"rc-field-form": "^0.0.0-alpha.26",
"rc-input-number": "~4.5.0",
@ -122,13 +123,12 @@
"rc-switch": "~1.9.0",
"rc-table": "~7.0.0-alpha.20",
"rc-tabs": "~10.0.0-alpha.0",
"rc-time-picker": "~4.0.0-alpha.2",
"rc-tooltip": "~4.0.0-alpha.3",
"rc-tree": "~3.0.0-alpha.37",
"rc-tree-select": "~3.0.0-alpha.5",
"rc-trigger": "~4.0.0-alpha.7",
"rc-upload": "~3.0.0-alpha.0",
"rc-util": "~4.16.1",
"rc-util": "^4.16.1",
"rc-virtual-list": "^0.0.0-alpha.25",
"@ant-design/react-slick": "~0.25.5",
"resize-observer-polyfill": "^1.5.1",
@ -141,6 +141,7 @@
"@ant-design/colors": "^3.2.2",
"@ant-design/tools": "^8.0.4",
"@packtracker/webpack-plugin": "^2.0.1",
"@qixian.cs/github-contributors-list": "^1.0.3",
"@sentry/browser": "^5.4.0",
"@stackblitz/sdk": "^1.3.0",
"@types/classnames": "^2.2.8",
@ -154,7 +155,7 @@
"@types/shallowequal": "^1.1.1",
"@types/warning": "^3.0.0",
"@typescript-eslint/eslint-plugin": "^2.0.0",
"@typescript-eslint/parser": "~2.9.0",
"@typescript-eslint/parser": "^2.10.0",
"antd-theme-generator": "^1.1.6",
"babel-eslint": "^10.0.1",
"babel-plugin-add-react-displayname": "^0.0.5",
@ -177,7 +178,7 @@
"eslint-config-airbnb": "^18.0.0",
"eslint-config-prettier": "^6.0.0",
"eslint-plugin-babel": "^5.3.0",
"eslint-plugin-import": "^2.17.3",
"eslint-plugin-import": "~2.19.1",
"eslint-plugin-jest": "^23.0.2",
"eslint-plugin-jsx-a11y": "^6.2.1",
"eslint-plugin-markdown": "^1.0.0",
@ -212,8 +213,8 @@
"react": "^16.9.0",
"react-color": "^2.17.3",
"react-copy-to-clipboard": "^5.0.1",
"react-dnd": "^9.0.0",
"react-dnd-html5-backend": "^9.0.0",
"react-dnd": "^10.0.2",
"react-dnd-html5-backend": "^10.0.2",
"react-dom": "^16.9.0",
"react-github-button": "^0.1.11",
"react-helmet-async": "^1.0.4",
@ -232,7 +233,7 @@
"scrollama": "^2.0.0",
"simple-git": "^1.113.0",
"stylelint": "^12.0.0",
"stylelint-config-prettier": "^7.0.0",
"stylelint-config-prettier": "^8.0.0",
"stylelint-config-rational-order": "^0.1.2",
"stylelint-config-standard": "^19.0.0",
"stylelint-declaration-block-no-ignored-properties": "^2.1.0",

View File

@ -1,3 +0,0 @@
{
"extends": ["config:base", ":preserveSemverRanges"]
}

View File

@ -34,14 +34,10 @@ describe('site test', () => {
});
return resp;
};
const handleComponentName = name => {
const componentMap = {
descriptions: 'description list',
};
// eslint-disable-next-line no-unused-vars
const [_, componentName] = name.split('/');
const compName = componentName.toLowerCase().replace('-', '');
return componentMap[compName] || compName;
const componentName = name.split('/')[1];
return componentName.toLowerCase().replace('-', '');
};
const expectComponent = async component => {

View File

@ -13,9 +13,12 @@ module.exports = {
'app.header.lang': '中文',
'app.content.edit-page': 'Edit this page on GitHub!',
'app.content.edit-demo': 'Edit this demo on GitHub!',
'app.content.contributors': 'contributors',
'app.component.examples': 'Examples',
'app.component.examples.expand': 'Expand all code',
'app.component.examples.collapse': 'Collapse all code',
'app.component.examples.visible': 'Expand debug examples',
'app.component.examples.hide': 'Collapse debug examples',
'app.demo.debug': "Debug only, won't display at online",
'app.demo.copy': 'Copy code',
'app.demo.copied': 'Copied!',
@ -49,7 +52,7 @@ module.exports = {
'app.home.getting-started': 'Getting Started',
'app.home.recommend': 'Recommend',
'app.home.recommend.yuque': 'Yuque, our favorite documentation tool',
'app.home.recommend.antv': 'G2Plot, the new charting library',
'app.home.recommend.antv.g2plot': 'G2Plot, the new charting library',
'app.home.more': 'Learn more',
'app.home.more-mobile-react': 'Ant Design Mobile of React',
'app.home.more-mobile-angular': 'Ant Design Mobile of Angular',

View File

@ -1,12 +1,3 @@
html,
body {
height: 100%;
}
html {
overflow-x: hidden;
}
body {
color: @site-text-color;
font-size: 14px;
@ -29,7 +20,7 @@ a {
.main-container {
position: relative;
min-height: 500px;
padding: 0 170px 144px 64px;
padding: 0 170px 32px 64px;
overflow: hidden;
background: #fff;
}
@ -40,8 +31,7 @@ a {
&-inner {
height: 100%;
max-height: 100vh;
overflow-x: hidden;
overflow-y: hidden;
overflow: hidden;
}
&:hover &-inner {

View File

@ -0,0 +1,8 @@
.contributors-list {
margin-top: 120px !important;
a + a,
.ant-avatar + .ant-avatar {
margin-left: 8px;
}
}

View File

@ -22,12 +22,15 @@
&-expand-trigger {
position: relative;
margin-left: 8px;
margin-left: 12px;
color: #3b4357;
font-size: 18px;
font-size: 20px;
cursor: pointer;
opacity: 0.8;
opacity: 0.75;
transition: all 0.3s;
&:hover {
opacity: 1;
}
}
&-title {

View File

@ -464,3 +464,9 @@ svg {
}
}
}
@supports (-moz-appearance: meterbar) {
.en-us .banner-btn {
line-height: 38px !important;
}
}

View File

@ -22,4 +22,4 @@
@import './theme';
@import './docsearch';
@import './nprogress';
@import './santa';
@import './contributors';

Some files were not shown because too many files have changed in this diff Show More