mirror of
https://github.com/ant-design/ant-design.git
synced 2026-02-09 10:59:19 +08:00
Compare commits
193 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20ef1f199c | ||
|
|
62839eb426 | ||
|
|
2f7998cc0c | ||
|
|
fee211e3c4 | ||
|
|
8188956193 | ||
|
|
57cb4a460b | ||
|
|
fd6d1796ed | ||
|
|
e01e545dcd | ||
|
|
13fb839032 | ||
|
|
85fcf0fe6e | ||
|
|
0b1a5409bd | ||
|
|
ea1f00d19f | ||
|
|
bef81beba6 | ||
|
|
b875f2ac83 | ||
|
|
408fbb41e5 | ||
|
|
850a5b4567 | ||
|
|
ab36853cb7 | ||
|
|
9b65863512 | ||
|
|
adf5288524 | ||
|
|
4300c046a0 | ||
|
|
fb68fcdc05 | ||
|
|
4146efa810 | ||
|
|
8fda3972fe | ||
|
|
89a6593c44 | ||
|
|
14619bc1d8 | ||
|
|
5fabb45d9d | ||
|
|
62d7a2bbb0 | ||
|
|
bca69b6e8c | ||
|
|
fac56ee952 | ||
|
|
3fed6f02a5 | ||
|
|
43bf7965de | ||
|
|
407dfda998 | ||
|
|
811d562527 | ||
|
|
16ac3b31df | ||
|
|
85b6744bf6 | ||
|
|
f2cae4361e | ||
|
|
0ab55ce884 | ||
|
|
ecce1e4aba | ||
|
|
6096f6e281 | ||
|
|
cba968f9dc | ||
|
|
be06f53e23 | ||
|
|
400ca638b3 | ||
|
|
73db45471f | ||
|
|
ca6260c75a | ||
|
|
a713a6ae5d | ||
|
|
1d516d7f7f | ||
|
|
6e69bcc9ca | ||
|
|
d7e81027d6 | ||
|
|
0ec7fa84d0 | ||
|
|
329edc1ed0 | ||
|
|
74e0587d5b | ||
|
|
815d52558b | ||
|
|
b022eaf9c2 | ||
|
|
53eee985f0 | ||
|
|
c824569ea0 | ||
|
|
f7d211fcea | ||
|
|
d6430ad3f2 | ||
|
|
2d82b59abf | ||
|
|
965bc58ed1 | ||
|
|
6030431121 | ||
|
|
69e3b87a9d | ||
|
|
bed1f7775b | ||
|
|
c7810823bf | ||
|
|
3fa135023f | ||
|
|
ae44aae0d3 | ||
|
|
d8eb8ece4b | ||
|
|
a210784294 | ||
|
|
c8a2acbb78 | ||
|
|
19a8118a81 | ||
|
|
34ff6db099 | ||
|
|
f2ac4f380b | ||
|
|
fb4ed9a638 | ||
|
|
46026c3aaf | ||
|
|
5d26cb0cc8 | ||
|
|
958bc51629 | ||
|
|
fb66bce007 | ||
|
|
041b7fa9e2 | ||
|
|
be30d4bfa4 | ||
|
|
fecdfd9c77 | ||
|
|
040fe5696a | ||
|
|
102efd529a | ||
|
|
3906f4fc00 | ||
|
|
5ff3a77dce | ||
|
|
c57d7f3a6c | ||
|
|
3072787839 | ||
|
|
69549a8648 | ||
|
|
26648cc0b1 | ||
|
|
eb8dc9f715 | ||
|
|
4d09b26f82 | ||
|
|
bb92b01ae0 | ||
|
|
e4c72cf6f5 | ||
|
|
d2e98b1bb9 | ||
|
|
4cae32842f | ||
|
|
ce59719a55 | ||
|
|
62b2ba38ee | ||
|
|
c34f9ea4b4 | ||
|
|
eefa24b6fa | ||
|
|
5ff193cf60 | ||
|
|
103920e4f5 | ||
|
|
91faa7e4cb | ||
|
|
5ecd32a83f | ||
|
|
26b9e1f887 | ||
|
|
d744df5974 | ||
|
|
0cb5601527 | ||
|
|
2f30c806a3 | ||
|
|
4079f36340 | ||
|
|
8b705e3224 | ||
|
|
68603366eb | ||
|
|
dfe7fd3231 | ||
|
|
326484465f | ||
|
|
cedc956512 | ||
|
|
807fea0447 | ||
|
|
af2dd379c2 | ||
|
|
41d1661627 | ||
|
|
f1a582581f | ||
|
|
f4051d8efc | ||
|
|
f6af1c6adf | ||
|
|
a1acc7942a | ||
|
|
d402582598 | ||
|
|
b74d1bdd54 | ||
|
|
8f52b8028b | ||
|
|
9dcaad0f88 | ||
|
|
c2ff79470f | ||
|
|
e116eea56f | ||
|
|
c6a7c44066 | ||
|
|
91fcf98741 | ||
|
|
3afc432062 | ||
|
|
e42caa5869 | ||
|
|
52ab454715 | ||
|
|
451d01b082 | ||
|
|
0cf62f696d | ||
|
|
499494caa4 | ||
|
|
c9682fcd6e | ||
|
|
4e669d465e | ||
|
|
5916582518 | ||
|
|
1d4f240276 | ||
|
|
94c3978208 | ||
|
|
8c23d8b9a2 | ||
|
|
be0fd703f7 | ||
|
|
a35b6241eb | ||
|
|
9e27697e93 | ||
|
|
948a69c75e | ||
|
|
dd8f57247f | ||
|
|
f38c7bb239 | ||
|
|
4ded5e6777 | ||
|
|
98a3de1eb7 | ||
|
|
42592bafcf | ||
|
|
48763bfa7c | ||
|
|
e150cfc371 | ||
|
|
8cff912aec | ||
|
|
c083d13fc4 | ||
|
|
725f2fb731 | ||
|
|
fd573acdec | ||
|
|
b697ef1213 | ||
|
|
0bdf682a80 | ||
|
|
715814291b | ||
|
|
39d452ca77 | ||
|
|
e88f0214dd | ||
|
|
c1d55addf1 | ||
|
|
764960875d | ||
|
|
187b10320b | ||
|
|
3402f656ad | ||
|
|
15d8494cf2 | ||
|
|
696f5600ec | ||
|
|
5bf96bbb51 | ||
|
|
214458931d | ||
|
|
0189244ebc | ||
|
|
dc2ba553e7 | ||
|
|
53efaa89a5 | ||
|
|
3d8b9df423 | ||
|
|
767d2d0638 | ||
|
|
92caa2d02c | ||
|
|
82aa3cdc13 | ||
|
|
593cfe8950 | ||
|
|
d99d90b1fa | ||
|
|
2ee2cc3303 | ||
|
|
13995bff02 | ||
|
|
654a675532 | ||
|
|
fdf38f41d7 | ||
|
|
c0edbd3362 | ||
|
|
ff382abc51 | ||
|
|
f8a3da5f4a | ||
|
|
1d1e197527 | ||
|
|
2b46a232db | ||
|
|
d5c3d578af | ||
|
|
f4d114f0c3 | ||
|
|
06ec0391f8 | ||
|
|
c9c2d5a256 | ||
|
|
4fd5dda8d5 | ||
|
|
cef820f7a6 | ||
|
|
bde17425a0 | ||
|
|
10bbf1fe0f | ||
|
|
cbdbb6dd30 |
3
.codesandbox/ci.json
Normal file
3
.codesandbox/ci.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"sandboxes": ["wk04r016q8"]
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
components/**/*.js
|
||||
components/**/*.jsx
|
||||
components/*/__tests__/type.tsx
|
||||
!components/*/__tests__/**/*.js
|
||||
!components/*/demo/*
|
||||
!.*.js
|
||||
|
||||
@@ -55,6 +55,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,
|
||||
@@ -84,6 +85,8 @@ const eslintrc = {
|
||||
'no-restricted-globals': 0,
|
||||
'max-classes-per-file': 0,
|
||||
'react/static-property-placement': 0,
|
||||
'jest/no-test-callback': 0,
|
||||
'jest/expect-expect': 0,
|
||||
},
|
||||
globals: {
|
||||
gtag: true,
|
||||
|
||||
21
.github/workflows/deploy-site.yml
vendored
21
.github/workflows/deploy-site.yml
vendored
@@ -9,13 +9,20 @@ jobs:
|
||||
build-and-deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
- name: checkout
|
||||
uses: actions/checkout@master
|
||||
|
||||
- name: Deploy website
|
||||
uses: JamesIves/github-pages-deploy-action@master
|
||||
- name: install
|
||||
run: npm install
|
||||
|
||||
- name: build
|
||||
run: npm run predeploy
|
||||
|
||||
- name: deploy
|
||||
uses: peaceiris/actions-gh-pages@v2.5.0
|
||||
env:
|
||||
ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
|
||||
BRANCH: gh-pages
|
||||
FOLDER: _site
|
||||
BUILD_SCRIPT: npm install && npm run predeploy
|
||||
ACTIONS_DEPLOY_KEY: ${{ secrets.ACCESS_TOKEN }}
|
||||
PUBLISH_BRANCH: gh-pages
|
||||
PUBLISH_DIR: ./_site
|
||||
with:
|
||||
emptyCommits: false
|
||||
|
||||
19
.github/workflows/lighthouse-ci.yml
vendored
Normal file
19
.github/workflows/lighthouse-ci.yml
vendored
Normal 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
|
||||
200
.github/workflows/test.yml
vendored
200
.github/workflows/test.yml
vendored
@@ -3,16 +3,206 @@ name: test
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
setup:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@master
|
||||
|
||||
- name: cache package-lock.json
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: package-temp-dir
|
||||
key: lock-${{ github.sha }}
|
||||
|
||||
- name: create package-lock.json
|
||||
run: npm i --package-lock-only
|
||||
|
||||
- name: hack for singe file
|
||||
run: |
|
||||
if [ ! -d "package-temp-dir" ]; then
|
||||
mkdir package-temp-dir
|
||||
fi
|
||||
cp package-lock.json package-temp-dir
|
||||
|
||||
- name: cache node_modules
|
||||
id: node_modules_cache_id
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: node_modules
|
||||
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
||||
|
||||
- name: install
|
||||
run: npm install
|
||||
if: steps.node_modules_cache_id.outputs.cache-hit != 'true'
|
||||
run: npm ci
|
||||
|
||||
compile:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@master
|
||||
|
||||
- name: restore cache from package-lock.json
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: package-temp-dir
|
||||
key: lock-${{ github.sha }}
|
||||
|
||||
- name: restore cache from node_modules
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: node_modules
|
||||
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
||||
|
||||
- name: cache lib
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: lib
|
||||
key: lib-${{ github.sha }}
|
||||
|
||||
- name: cache es
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: es
|
||||
key: es-${{ github.sha }}
|
||||
|
||||
- name: compile
|
||||
run: npm run compile
|
||||
|
||||
- name: check
|
||||
run: node ./tests/dekko/lib.test.js
|
||||
needs: setup
|
||||
|
||||
dist:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@master
|
||||
|
||||
- name: restore cache from package-lock.json
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: package-temp-dir
|
||||
key: lock-${{ github.sha }}
|
||||
|
||||
- name: restore cache from node_modules
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: node_modules
|
||||
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
||||
|
||||
- name: dist
|
||||
run: npm run dist
|
||||
|
||||
- name: check
|
||||
run: node ./tests/dekko/dist.test.js
|
||||
|
||||
- name: test
|
||||
run: npm run test-all
|
||||
run: npm test
|
||||
env:
|
||||
LIB_DIR: dist
|
||||
needs: setup
|
||||
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@master
|
||||
|
||||
- name: restore cache from package-lock.json
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: package-temp-dir
|
||||
key: lock-${{ github.sha }}
|
||||
|
||||
- name: restore cache from node_modules
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: node_modules
|
||||
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
||||
|
||||
- name: lint
|
||||
run: npm run lint
|
||||
needs: setup
|
||||
|
||||
node:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@master
|
||||
|
||||
- name: restore cache from package-lock.json
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: package-temp-dir
|
||||
key: lock-${{ github.sha }}
|
||||
|
||||
- name: restore cache from node_modules
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: node_modules
|
||||
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
||||
|
||||
- name: test
|
||||
run: npm test
|
||||
needs: setup
|
||||
|
||||
lib:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@master
|
||||
|
||||
- name: restore cache from package-lock.json
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: package-temp-dir
|
||||
key: lock-${{ github.sha }}
|
||||
|
||||
- name: restore cache from node_modules
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: node_modules
|
||||
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
||||
|
||||
- name: restore cache from lib
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: lib
|
||||
key: lib-${{ github.sha }}
|
||||
|
||||
- name: test
|
||||
run: npm test
|
||||
env:
|
||||
LIB_DIR: lib
|
||||
needs: compile
|
||||
|
||||
es:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@master
|
||||
|
||||
- name: restore cache from package-lock.json
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: package-temp-dir
|
||||
key: lock-${{ github.sha }}
|
||||
|
||||
- name: restore cache from node_modules
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: node_modules
|
||||
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
||||
|
||||
- name: restore cache from es
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: es
|
||||
key: es-${{ github.sha }}
|
||||
|
||||
- name: test
|
||||
run: npm test
|
||||
env:
|
||||
LIB_DIR: es
|
||||
needs: compile
|
||||
|
||||
2
.jest.js
2
.jest.js
@@ -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,
|
||||
|
||||
@@ -15,6 +15,114 @@ timeline: true
|
||||
|
||||
---
|
||||
|
||||
## 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`
|
||||
|
||||
- 🏆 `3.26.0` will be the last minor version of antd v3. And v4 beta is coming!
|
||||
- 🌟 Notification support `closeIcon` props. [#19618](https://github.com/ant-design/ant-design/pull/19618) [@liuchao233](https://github.com/liuchao233)
|
||||
- 🌟 Typography support `pt_BR` locale. [#19651](https://github.com/ant-design/ant-design/pull/19651) [@liuchao233](https://github.com/liuchao233)
|
||||
- 🌟 Table support `defaultFilteredValues` props. [#18925](https://github.com/ant-design/ant-design/pull/18925) [@mgcrea](https://github.com/mgcrea)
|
||||
- 🇲🇰 Locale add Macedonian support. [#19647](https://github.com/ant-design/ant-design/pull/19647) [@sradevski](https://github.com/sradevski)
|
||||
- 🐞 Fix Input.Group compat mode has wrong border radius for Input Addon. [#19926](https://github.com/ant-design/ant-design/pull/19926)
|
||||
- 🐞 Fix Spin render default indicator when `indicator` is `null`. [#19943](https://github.com/ant-design/ant-design/pull/19943)
|
||||
- 🐞 Fix Button component `disabled` with `loading` not prevent pointer-events. [#19958](https://github.com/ant-design/ant-design/pull/19958)
|
||||
- 🐞 Fix message can not cancel when `key` is provided. [#19967](https://github.com/ant-design/ant-design/pull/19967)
|
||||
- 🐞 Fix image in Upload with `picture-card` mode exceeds the border. [#20008](https://github.com/ant-design/ant-design/pull/20008) [@qq645381995](https://github.com/qq645381995)
|
||||
- 🐞 Fix Input clear icon overlap with feedback icon. [#20017](https://github.com/ant-design/ant-design/pull/20017)
|
||||
- 🐞 Fix Slider tooltip text not align center. [#20016](https://github.com/ant-design/ant-design/pull/20016)
|
||||
- 🐞 Fix Descriptions items not working with React.Fragment. [#20019](https://github.com/ant-design/ant-design/pull/20019)
|
||||
- 🛠 Upload under drag mode moves `className` and `style` to the real effect dom.[#19987](https://github.com/ant-design/ant-design/pull/19987)
|
||||
- 💄Add less variable `@table-header-bg-sm` and fix small Table footer style. [#19939](https://github.com/ant-design/ant-design/pull/19939)
|
||||
|
||||
## 3.25.3
|
||||
|
||||
`2019-11-24`
|
||||
|
||||
- 🐞 Fix TimePicker disabled item style when focussed. [#19812](https://github.com/ant-design/ant-design/pull/19812) [@yoyo837](https://github.com/yoyo837)
|
||||
- 🐞 Fix Menu.Item link style inside Badge. [#19810](https://github.com/ant-design/ant-design/pull/19810)
|
||||
- 🐞 Fix Upload `picture-card` type, for crashed style when list item is removing. [#19783](https://github.com/ant-design/ant-design/pull/19783) [@qq645381995](https://github.com/qq645381995)
|
||||
- 🇳🇱 Update `sk-SK` locales. [#19787](https://github.com/ant-design/ant-design/pull/19787) [@Kamahl19](https://github.com/Kamahl19)
|
||||
- TypeScript
|
||||
- ⚡️ Export interface types in Tooltip. [19846](https://github.com/ant-design/ant-design/pull/19846) [@kachkaev](https://github.com/kachkaev)
|
||||
|
||||
## 3.25.2
|
||||
|
||||
`2019-11-17`
|
||||
|
||||
- 🐞 Fix Upload List do not have tooltip when upload failed. [#19689](https://github.com/ant-design/ant-design/pull/19689) [@qq645381995](https://github.com/qq645381995)
|
||||
- 💄 Fix Transfer search style to avoid text overlap with clear icon. [#19693](https://github.com/ant-design/ant-design/pull/19693) [@Abdullah700](https://github.com/Abdullah700)
|
||||
- 🇳🇱 Update `NL-nl` locales. [#19734](https://github.com/ant-design/ant-design/pull/19734) [@hoest](https://github.com/hoest)
|
||||
- TypeScript
|
||||
- 🐞 Fix Table FilterDropdownProps definition. [#19701](https://github.com/ant-design/ant-design/pull/19701) [@DeanVanNiekerk](https://github.com/DeanVanNiekerk)
|
||||
- 🛠 Slider add `reverse` definition. [#19713](https://github.com/ant-design/ant-design/pull/19713) [@jacklee814](https://github.com/jacklee814)
|
||||
- 🐞 Update Table `filteredValue` definition. [#19722](https://github.com/ant-design/ant-design/pull/19722) [@andelf](https://github.com/andelf)
|
||||
|
||||
## 3.25.1
|
||||
|
||||
`2019-11-10`
|
||||
|
||||
- 🐞 Fix less variables of `@menu-icon-size` and `@menu-icon-size-lg` not working. [#19553](https://github.com/ant-design/ant-design/pull/19553) [@yoyo837](https://github.com/yoyo837)
|
||||
- 🐞 Fix DirectoryTree `defaultExpandedAll` not working with `treeData`. [#19646](https://github.com/ant-design/ant-design/pull/19646)
|
||||
- 🐞 Fix Drawer content overflow when `placement` prop is top or bottom. [#19506](https://github.com/ant-design/ant-design/pull/19506) [@shaodahong](https://github.com/shaodahong)
|
||||
- 🐞 Fix broken Menu.ItemGroup style inside Dropdown again. [#19578](https://github.com/ant-design/ant-design/pull/19578)
|
||||
- 🐞 Fix Dropdown that menu icon `margin-right` style is missing. [#19635](https://github.com/ant-design/ant-design/pull/19635)
|
||||
- 🐞 Fix Form.Item custom props not working. [#19599](https://github.com/ant-design/ant-design/pull/19599) [@yoyo837](https://github.com/yoyo837)
|
||||
- 🐞 Fix Icon `extraCommonProps` not working properly. [#19572](https://github.com/ant-design/ant-design/pull/19572) [@yoyo837](https://github.com/yoyo837)
|
||||
- 🐞 Fix Modal.method() scrollbar not disabled. [#19233](https://github.com/ant-design/ant-design/pull/19233) [@emersonlaurentino](https://github.com/emersonlaurentino)
|
||||
- Table
|
||||
- 🐞 Fix border missing in fixed columns. [#19559](https://github.com/ant-design/ant-design/pull/19559)
|
||||
- 🐞 Fix Column with `sortOrder` throw error of inifinite loop. [#19558](https://github.com/ant-design/ant-design/pull/19558)
|
||||
- 🐞 Fix Column `defaultSortOrder` not working. [#19558](https://github.com/ant-design/ant-design/pull/19558)
|
||||
- TypeScript
|
||||
- 🐞 Fix type definition of `ListStyle` for Transfer. [#19568](https://github.com/ant-design/ant-design/pull/19568) [@lxnxbnq](https://github.com/lxnxbnq)
|
||||
- 🐞 Fix type definition of multiple props for RangePicker. [#19421](https://github.com/ant-design/ant-design/pull/19421) [@JennieJi](https://github.com/JennieJi)
|
||||
|
||||
## 3.25.0
|
||||
|
||||
`2019-11-04`
|
||||
|
||||
- 🌟 Transfer `listStyle` support function callback. [#19330](https://github.com/ant-design/ant-design/pull/19330) [@lxnxbnq](https://github.com/lxnxbnq)
|
||||
- 🌟 `icon` of Avatar support ReactNode. [#19368](https://github.com/ant-design/ant-design/pull/19368)
|
||||
- 🌟 TextArea support `allowClear`. [#19310](https://github.com/ant-design/ant-design/pull/19310) [@Rustin-Liu](https://github.com/Rustin-Liu)
|
||||
- 🌟 Upload support to custom `method` for request. [#19533](https://github.com/ant-design/ant-design/pull/19533)
|
||||
- 🌟 Upload `onChange` add `XMLHttpRequest` as additional param. [#19539](https://github.com/ant-design/ant-design/pull/19539) [@hahmadia](https://github.com/hahmadia)
|
||||
- 🐞 Fix WeekPicker `defaultPickerValue` not works. [#19141](https://github.com/ant-design/ant-design/pull/19141) [@NightFox7](https://github.com/NightFox7)
|
||||
- 🐞 Fix DatePicker `onEsc is not a function` TypeError. [#19474](https://github.com/ant-design/ant-design/pull/19474)
|
||||
- 🐞 Fix table does not automatically scroll to the top when change page size. [#19474](https://github.com/ant-design/ant-design/pull/19474) [@MrHeer](https://github.com/MrHeer)
|
||||
- 💄 Fix Icon Button not aligned well in Button.Group. [#19453](https://github.com/ant-design/ant-design/pull/19453)
|
||||
- 💄 Fix Checkbox not aligned center of some cases in Chrome. [#19452](https://github.com/ant-design/ant-design/pull/19452)
|
||||
- 💄 Fix Menu `margin` collapsed issue. [#19476](https://github.com/ant-design/ant-design/pull/19476) [@wangweijun0418](https://github.com/wangweijun0418)
|
||||
- 💄 Remove useless style in Select. [#19510](https://github.com/ant-design/ant-design/pull/19510) [@jacklee814](https://github.com/jacklee814)
|
||||
- 💄 Added less variables `@input-number-hover-border-color`, `@select-background`. [#19546](https://github.com/ant-design/ant-design/pull/19546)
|
||||
- 🌍 Add `downloadFile` in all locale files. [#19361](https://github.com/ant-design/ant-design/pull/19361) [@DemetriusHR](https://github.com/DemetriusHR)
|
||||
- 🇹🇭 Add missing translations in Thai (th_TH) locale. [#19378](https://github.com/ant-design/ant-design/pull/19378) [@anawinwz](https://github.com/anawinwz)
|
||||
- Typescript
|
||||
- 🐞 Add Upload missing `preview` type. [#19496](https://github.com/ant-design/ant-design/pull/19496) [@chnliquan](https://github.com/chnliquan)
|
||||
|
||||
## 3.24.3
|
||||
|
||||
`2019-10-26`
|
||||
|
||||
@@ -15,6 +15,114 @@ timeline: true
|
||||
|
||||
---
|
||||
|
||||
## 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`
|
||||
|
||||
- 🏆 `3.26.0` 将为 antd v3 最后一个 minor 版本,v4 beta 版即将发布!
|
||||
- 🌟 Notification 支持 `closeIcon` 属性。[#19618](https://github.com/ant-design/ant-design/pull/19618) [@liuchao233](https://github.com/liuchao233)
|
||||
- 🌟 Typography 添加 `pt_BR` 国际化支持。[#19651](https://github.com/ant-design/ant-design/pull/19651) [@liuchao233](https://github.com/liuchao233)
|
||||
- 🌟 Table 支持 `defaultFilteredValues` 属性。[#18925](https://github.com/ant-design/ant-design/pull/18925) [@mgcrea](https://github.com/mgcrea)
|
||||
- 🇲🇰 国际化添加北马其顿支持。[#19647](https://github.com/ant-design/ant-design/pull/19647) [@sradevski](https://github.com/sradevski)
|
||||
- 🐞 修复 Input.Group 紧凑模式下使用 Input Addon 圆角不对的问题。[#19926](https://github.com/ant-design/ant-design/pull/19926)
|
||||
- 🐞 修复 Spin 在 `indicator` 属性为 `null` 时,渲染默认的旋转图标。[#19943](https://github.com/ant-design/ant-design/pull/19943)
|
||||
- 🐞 修复 Button 组件 `disabled` 和 `loading` 状态下没有阻止鼠标事件。[#19958](https://github.com/ant-design/ant-design/pull/19958)
|
||||
- 🐞 修复 message 组件使用 `key` 时无法手动取消的问题。[#19967](https://github.com/ant-design/ant-design/pull/19967)
|
||||
- 🐞 修复 Upload 在 `picture-card` 模式下,图片过长会超出边界的问题。[#20008](https://github.com/ant-design/ant-design/pull/20008) [@qq645381995](https://github.com/qq645381995)
|
||||
- 🐞 修复 Input 清除图标和反馈图标重合的问题。[#20017](https://github.com/ant-design/ant-design/pull/20017)
|
||||
- 🐞 修复 Slider 的 tooltip 内容没有居中的问题。[#20016](https://github.com/ant-design/ant-design/pull/20016)
|
||||
- 🐞 修复 Descriptions 内使用 React.Fragment 的渲染问题。[#20019](https://github.com/ant-design/ant-design/pull/20019)
|
||||
- 🛠 Upload 拖拽模式下的 `className` 和 `style` 将会作用到真正的 dom 上。[#19987](https://github.com/ant-design/ant-design/pull/19987)
|
||||
- 💄 新增 less 变量 `@table-header-bg-sm` 并修复小号 Table 的 footer 样式。[#19939](https://github.com/ant-design/ant-design/pull/19939)
|
||||
|
||||
## 3.25.3
|
||||
|
||||
`2019-11-24`
|
||||
|
||||
- 🐞 修复 TimePicker 禁用项 focus 时的样式问题。[#19812](https://github.com/ant-design/ant-design/pull/19812) [@yoyo837](https://github.com/yoyo837)
|
||||
- 🐞 修复 Menu.Item 链接在 Badge 内时,始终处于 active 状态的问题。[#19810](https://github.com/ant-design/ant-design/pull/19810)
|
||||
- 🐞 修复 Upload 类型为 `picture-card` 时,列表删除时的样式问题。[#19783](https://github.com/ant-design/ant-design/pull/19783) [@qq645381995](https://github.com/qq645381995)
|
||||
- 🇳🇱 更新 `sk-SK` 国际化。[#19787](https://github.com/ant-design/ant-design/pull/19787) [@Kamahl19](https://github.com/Kamahl19)
|
||||
- TypeScript
|
||||
- ⚡️ 导出 Tooltip 类型定义。[19846](https://github.com/ant-design/ant-design/pull/19846) [@kachkaev](https://github.com/kachkaev)
|
||||
|
||||
## 3.25.2
|
||||
|
||||
`2019-11-17`
|
||||
|
||||
- 🐞 修复 Upload List 上传错误时没有鼠标悬浮提示的问题。[#19689](https://github.com/ant-design/ant-design/pull/19689) [@qq645381995](https://github.com/qq645381995)
|
||||
- 💄 修复 Transfer 输入框内容会与清除按钮重叠的问题。[#19693](https://github.com/ant-design/ant-design/pull/19693) [@Abdullah700](https://github.com/Abdullah700)
|
||||
- 🇳🇱 更新 `NL-nl` 国际化。[#19734](https://github.com/ant-design/ant-design/pull/19734) [@hoest](https://github.com/hoest)
|
||||
- TypeScript
|
||||
- 🐞 修复 Table FilterDropdownProps 定义。[#19701](https://github.com/ant-design/ant-design/pull/19701) [@DeanVanNiekerk](https://github.com/DeanVanNiekerk)
|
||||
- 🛠 Slider 添加 `reverse` 定义。[#19713](https://github.com/ant-design/ant-design/pull/19713) [@jacklee814](https://github.com/jacklee814)
|
||||
- 🐞 更新 Table `filteredValue` 定义。[#19722](https://github.com/ant-design/ant-design/pull/19722) [@andelf](https://github.com/andelf)
|
||||
|
||||
## 3.25.1
|
||||
|
||||
`2019-11-10`
|
||||
|
||||
- 🐞 修复定制 `@menu-icon-size` 和 `@menu-icon-size-lg` less 变量不生效的问题。[#19553](https://github.com/ant-design/ant-design/pull/19553) [@yoyo837](https://github.com/yoyo837)
|
||||
- 🐞 修复 DirectoryTree 中 `defaultExpandedAll` 在使用 `treeData` 时不生效的问题。[#19646](https://github.com/ant-design/ant-design/pull/19646)
|
||||
- 🐞 修复 Drawer 中 `placement` 属性为 top 或 bottom 时内容溢出的问题。[#19506](https://github.com/ant-design/ant-design/pull/19506) [@shaodahong](https://github.com/shaodahong)
|
||||
- 🐞 修复 Dropdown 下 Menu.ItemGroup 样式错乱的问题。 [#19578](https://github.com/ant-design/ant-design/pull/19578)
|
||||
- 🐞 修复 Dropdown 中菜单图标丢失右边距的问题。[#19635](https://github.com/ant-design/ant-design/pull/19635)
|
||||
- 🐞 修复 Form.Item 中自定义属性无法生效的问题。[#19599](https://github.com/ant-design/ant-design/pull/19599) [@yoyo837](https://github.com/yoyo837)
|
||||
- 🐞 修复 Icon 中 `extraCommonProps` 属性不生效的问题。 [#19572](https://github.com/ant-design/ant-design/pull/19572) [@yoyo837](https://github.com/yoyo837)
|
||||
- 🐞 修复 Modal.method() 中浏览器滚动条没有禁用的问题。[#19233](https://github.com/ant-design/ant-design/pull/19233) [@emersonlaurentino](https://github.com/emersonlaurentino)
|
||||
- Table
|
||||
- 🐞 修复合并单元格和固定列同时使用时边框丢失的问题。[#19559](https://github.com/ant-design/ant-design/pull/19559)
|
||||
- 🐞 修复 Column 设置了 `sortOrder` 属性导致死循环的问题。[#19558](https://github.com/ant-design/ant-design/pull/19558)
|
||||
- 🐞 修复 Column 的 `defaultSortOrder` 属性不生效的问题。[#19558](https://github.com/ant-design/ant-design/pull/19558)
|
||||
- TypeScript
|
||||
- 🐞 修复 Transfer 中 `ListStyle` 的类型定义。[#19568](https://github.com/ant-design/ant-design/pull/19568) [@lxnxbnq](https://github.com/lxnxbnq)
|
||||
- 🐞 修复 RangePicker 中多个属性的类型定义缺失的问题。[#19421](https://github.com/ant-design/ant-design/pull/19421) [@JennieJi](https://github.com/JennieJi)
|
||||
|
||||
## 3.25.0
|
||||
|
||||
`2019-11-04`
|
||||
|
||||
- 🌟 Transfer `listStyle` 支持回调函数。[#19330](https://github.com/ant-design/ant-design/pull/19330) [@lxnxbnq](https://github.com/lxnxbnq)
|
||||
- 🌟 Avatar 的 `icon` 属性支持传递 ReactNode。[#19368](https://github.com/ant-design/ant-design/pull/19368)
|
||||
- 🌟 TextArea 支持 `allowClear`。[#19310](https://github.com/ant-design/ant-design/pull/19310) [@Rustin-Liu](https://github.com/Rustin-Liu)
|
||||
- 🌟 Upload 新增 `method` 属性用于修改请求方式。[#19533](https://github.com/ant-design/ant-design/pull/19533)
|
||||
- 🌟 Upload `onChange` 新增 `XMLHttpRequest` 作为额外参数。[#19539](https://github.com/ant-design/ant-design/pull/19539) [@hahmadia](https://github.com/hahmadia)
|
||||
- 🐞 修复 WeekPicker 中 `defaultPickerValue` 不生效的问题。[#19141](https://github.com/ant-design/ant-design/pull/19141) [@NightFox7](https://github.com/NightFox7)
|
||||
- 🐞 修复 DatePicker 抛出 `onEsc is not a function` 错误。[#19474](https://github.com/ant-design/ant-design/pull/19474)
|
||||
- 🐞 修复 Table 改变每页大小时不滚动到第一行的问题。[#19474](https://github.com/ant-design/ant-design/pull/19474) [@MrHeer](https://github.com/MrHeer)
|
||||
- 💄 修复 Button.Group 下图标按钮没有对齐的问题。[#19453](https://github.com/ant-design/ant-design/pull/19453)
|
||||
- 💄 修复 Checkbox 对勾在 Chrome 下有时没有居中的问题。[#19452](https://github.com/ant-design/ant-design/pull/19452)
|
||||
- 💄 修复 Menu `margin` 样式重合的问题。[#19476](https://github.com/ant-design/ant-design/pull/19476) [@wangweijun0418](https://github.com/wangweijun0418)
|
||||
- 💄 移除 Select 中没有必要的样式。[#19510](https://github.com/ant-design/ant-design/pull/19510) [@jacklee814](https://github.com/jacklee814)
|
||||
- 💄 新增 less 变量 `@input-number-hover-border-color`, `@select-background`。[#19546](https://github.com/ant-design/ant-design/pull/19546)
|
||||
- 🌍 国际化添加缺失的 `downloadFile` 支持。[#19361](https://github.com/ant-design/ant-design/pull/19361) [@DemetriusHR](https://github.com/DemetriusHR)
|
||||
- 🇹🇭 添加丢失的泰文国际化 (th_TH)。[#19378](https://github.com/ant-design/ant-design/pull/19378) [@anawinwz](https://github.com/anawinwz)
|
||||
- Typescript
|
||||
- 🐞 修复 Upload 丢失的 `preview` 定义。[#19496](https://github.com/ant-design/ant-design/pull/19496) [@chnliquan](https://github.com/chnliquan)
|
||||
|
||||
## 3.24.3
|
||||
|
||||
`2019-10-26`
|
||||
|
||||
10
README.md
10
README.md
@@ -10,7 +10,7 @@
|
||||
|
||||
An enterprise-class UI design language and React UI library.
|
||||
|
||||
[](https://circleci.com/gh/ant-design/ant-design)  [](https://codecov.io/gh/ant-design/ant-design/branch/master) [](https://www.npmjs.com/package/antd) [](https://www.npmjs.com/package/antd) [](http://npmjs.com/antd)
|
||||
[](https://circleci.com/gh/ant-design/ant-design)  [](https://codecov.io/gh/ant-design/ant-design/branch/master) [](https://www.npmjs.com/package/antd) [](https://www.npmjs.com/package/antd) [](http://npmjs.com/antd)
|
||||
|
||||
[](https://david-dm.org/ant-design/ant-design) [](https://david-dm.org/ant-design/ant-design?type=dev) [](https://lgtm.com/projects/g/ant-design/ant-design/alerts/) [](https://app.fossa.io/projects/git%2Bgithub.com%2Fant-design%2Fant-design?ref=badge_shield) [](https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22)
|
||||
|
||||
@@ -36,8 +36,8 @@ English | [简体中文](./README-zh_CN.md)
|
||||
- [Electron](http://electron.atom.io/)
|
||||
|
||||
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png" alt="Opera" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Opera | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/electron/electron_48x48.png" alt="Electron" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Electron |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| IE9, IE10, IE11, Edge | last 2 versions | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
|
||||
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| IE9, IE10, IE11, Edge | last 2 versions | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
|
||||
|
||||
## 📦 Install
|
||||
|
||||
@@ -52,14 +52,14 @@ yarn add antd
|
||||
## 🔨 Usage
|
||||
|
||||
```jsx
|
||||
import { DatePicker } from 'antd';
|
||||
import { DatePicker } from "antd";
|
||||
ReactDOM.render(<DatePicker />, mountNode);
|
||||
```
|
||||
|
||||
And import style manually:
|
||||
|
||||
```jsx
|
||||
import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
|
||||
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).
|
||||
|
||||
@@ -4,11 +4,11 @@ type: Navigation
|
||||
title: Affix
|
||||
---
|
||||
|
||||
Make an element stick to viewport.
|
||||
Wrap Affix around another component to make it stick the viewport.
|
||||
|
||||
## When To Use
|
||||
|
||||
When user browses a long web page, some content need to stick to the viewport. This is common for menus and actions.
|
||||
On longer web pages, its helpful for some content to stick to the viewport. This is common for menus and actions.
|
||||
|
||||
Please note that Affix should not cover other content on the page, especially when the size of the viewport is small.
|
||||
|
||||
@@ -16,12 +16,12 @@ Please note that Affix should not cover other content on the page, especially wh
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| offsetBottom | Pixels to offset from bottom when calculating position of scroll | number | - | |
|
||||
| offsetTop | Pixels to offset from top when calculating position of scroll | number | 0 | |
|
||||
| target | specifies the scrollable area dom node | () => HTMLElement | () => window | |
|
||||
| onChange | Callback for when affix state is changed | Function(affixed) | - | |
|
||||
| offsetBottom | Offset from the bottom of the viewport (in pixels) | number | - | |
|
||||
| offsetTop | Offset from the top of the viewport (in pixels) | number | 0 | |
|
||||
| target | Specifies the scrollable area DOM node | () => HTMLElement | () => window | |
|
||||
| onChange | Callback for when Affix state is changed | Function(affixed) | - | |
|
||||
|
||||
**Note:** Children of `Affix` can not be `position: absolute`, but you can set `Affix` as `position: absolute`:
|
||||
**Note:** Children of `Affix` must not have the property `position: absolute`, but you can set `position: absolute` on `Affix` itself:
|
||||
|
||||
```jsx
|
||||
<Affix style={{ position: 'absolute', top: y, left: x }}>...</Affix>
|
||||
@@ -33,4 +33,4 @@ Please note that Affix should not cover other content on the page, especially wh
|
||||
|
||||
We don't listen window scroll for performance consideration. You can add listener if you still want: <https://codesandbox.io/s/2xyj5zr85p>
|
||||
|
||||
Related issue:[#3938](https://github.com/ant-design/ant-design/issues/3938) [#5642](https://github.com/ant-design/ant-design/issues/5642) [#16120](https://github.com/ant-design/ant-design/issues/16120)
|
||||
Related issues:[#3938](https://github.com/ant-design/ant-design/issues/3938) [#5642](https://github.com/ant-design/ant-design/issues/5642) [#16120](https://github.com/ant-design/ant-design/issues/16120)
|
||||
|
||||
@@ -52,7 +52,7 @@ export default class Alert extends React.Component<AlertProps, AlertState> {
|
||||
);
|
||||
|
||||
this.state = {
|
||||
closing: true,
|
||||
closing: false,
|
||||
closed: false,
|
||||
};
|
||||
}
|
||||
@@ -66,15 +66,15 @@ export default class Alert extends React.Component<AlertProps, AlertState> {
|
||||
dom.style.height = `${dom.offsetHeight}px`;
|
||||
|
||||
this.setState({
|
||||
closing: false,
|
||||
closing: true,
|
||||
});
|
||||
(this.props.onClose || noop)(e);
|
||||
};
|
||||
|
||||
animationEnd = () => {
|
||||
this.setState({
|
||||
closing: false,
|
||||
closed: true,
|
||||
closing: true,
|
||||
});
|
||||
(this.props.afterClose || noop)();
|
||||
};
|
||||
@@ -91,6 +91,7 @@ export default class Alert extends React.Component<AlertProps, AlertState> {
|
||||
icon,
|
||||
} = this.props;
|
||||
let { closable, type, showIcon, iconType } = this.props;
|
||||
const { closing, closed } = this.state;
|
||||
|
||||
const prefixCls = getPrefixCls('alert', customizePrefixCls);
|
||||
|
||||
@@ -133,7 +134,7 @@ export default class Alert extends React.Component<AlertProps, AlertState> {
|
||||
prefixCls,
|
||||
`${prefixCls}-${type}`,
|
||||
{
|
||||
[`${prefixCls}-close`]: !this.state.closing,
|
||||
[`${prefixCls}-closing`]: closing,
|
||||
[`${prefixCls}-with-description`]: !!description,
|
||||
[`${prefixCls}-no-icon`]: !showIcon,
|
||||
[`${prefixCls}-banner`]: !!banner,
|
||||
@@ -162,23 +163,22 @@ export default class Alert extends React.Component<AlertProps, AlertState> {
|
||||
const iconNode = (icon &&
|
||||
(React.isValidElement<{ className?: string }>(icon) ? (
|
||||
React.cloneElement(icon, {
|
||||
className: classNames({
|
||||
className: classNames(`${prefixCls}-icon`, {
|
||||
[icon.props.className as string]: icon.props.className,
|
||||
[`${prefixCls}-icon`]: true,
|
||||
}),
|
||||
})
|
||||
) : (
|
||||
<span className={`${prefixCls}-icon`}>{icon}</span>
|
||||
))) || <Icon className={`${prefixCls}-icon`} type={iconType} theme={iconTheme} />;
|
||||
|
||||
return this.state.closed ? null : (
|
||||
return closed ? null : (
|
||||
<Animate
|
||||
component=""
|
||||
showProp="data-show"
|
||||
transitionName={`${prefixCls}-slide-up`}
|
||||
onEnd={this.animationEnd}
|
||||
>
|
||||
<div data-show={this.state.closing} className={alertCls} style={style} {...dataOrAriaProps}>
|
||||
<div data-show={!closing} className={alertCls} style={style} {...dataOrAriaProps}>
|
||||
{showIcon ? iconNode : null}
|
||||
<span className={`${prefixCls}-message`}>{message}</span>
|
||||
<span className={`${prefixCls}-description`}>{description}</span>
|
||||
|
||||
@@ -77,6 +77,7 @@
|
||||
line-height: 22px;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
|
||||
.@{iconfont-css-prefix}-close {
|
||||
@@ -138,7 +139,7 @@
|
||||
display: block;
|
||||
}
|
||||
|
||||
&&-close {
|
||||
&&-closing {
|
||||
height: 0 !important;
|
||||
margin: 0;
|
||||
padding-top: 0;
|
||||
|
||||
@@ -52,8 +52,8 @@ const dataSource = ['12345', '23456', '34567'];
|
||||
|
||||
## FAQ
|
||||
|
||||
### Why text composition system not works well with onSearch in controlled mode?
|
||||
### Why doesn't the text composition system work well with onSearch in controlled mode?
|
||||
|
||||
Please use `onChange` to manage control state. `onSearch` is used for searching input which is not same as `onChange`. Besides, click on the option also not trigger the `onSearch` event.
|
||||
Please use `onChange` to manage control state. `onSearch` is used for searching input which is not same as `onChange`. Besides, clicking on the option will not trigger the `onSearch` event.
|
||||
|
||||
Related issue: [#18230](https://github.com/ant-design/ant-design/issues/18230) [#17916](https://github.com/ant-design/ant-design/issues/17916)
|
||||
|
||||
@@ -529,6 +529,29 @@ exports[`renders ./components/avatar/demo/toggle-debug.md correctly 1`] = `
|
||||
|
||||
exports[`renders ./components/avatar/demo/type.md correctly 1`] = `
|
||||
<div>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-circle ant-avatar-icon"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: user"
|
||||
class="anticon anticon-user"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="user"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M858.5 763.6a374 374 0 0 0-80.6-119.5 375.63 375.63 0 0 0-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 0 0-80.6 119.5A371.7 371.7 0 0 0 136 901.8a8 8 0 0 0 8 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 0 0 8-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</span>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-circle ant-avatar-icon"
|
||||
>
|
||||
|
||||
@@ -14,11 +14,12 @@ title:
|
||||
Image, Icon and letter are supported, and the latter two kinds of avatar can have custom colors and background colors.
|
||||
|
||||
```jsx
|
||||
import { Avatar } from 'antd';
|
||||
import { Avatar, Icon } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<div>
|
||||
<Avatar icon="user" />
|
||||
<Avatar icon={<Icon type="user" />} />
|
||||
<Avatar>U</Avatar>
|
||||
<Avatar>USER</Avatar>
|
||||
<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
|
||||
|
||||
@@ -10,7 +10,7 @@ Avatars can be used to represent people or objects. It supports images, `Icon`s,
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| icon | the `Icon` type for an icon avatar, see `Icon` Component | string | - | |
|
||||
| icon | the `Icon` type for an icon avatar, see `Icon` Component or use ReactNode | string \| ReactNode | - | |
|
||||
| shape | the shape of avatar | `circle` \| `square` | `circle` | |
|
||||
| size | the size of the avatar | number \| string: `large` `small` `default` | `default` | |
|
||||
| src | the address of the image for an image avatar | string | - | |
|
||||
|
||||
@@ -16,7 +16,7 @@ export interface AvatarProps {
|
||||
/** Srcset of image avatar */
|
||||
srcSet?: string;
|
||||
/** Type of the Icon to be used in avatar */
|
||||
icon?: string;
|
||||
icon?: string | React.ReactNode;
|
||||
style?: React.CSSProperties;
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
@@ -137,7 +137,11 @@ export default class Avatar extends React.Component<AvatarProps, AvatarState> {
|
||||
if (src && isImgExist) {
|
||||
children = <img src={src} srcSet={srcSet} onError={this.handleImgLoadError} alt={alt} />;
|
||||
} else if (icon) {
|
||||
children = <Icon type={icon} />;
|
||||
if (typeof icon === 'string') {
|
||||
children = <Icon type={icon} />;
|
||||
} else {
|
||||
children = icon;
|
||||
}
|
||||
} else {
|
||||
const childrenNode = this.avatarChildren;
|
||||
if (childrenNode || scale !== 1) {
|
||||
|
||||
@@ -15,7 +15,7 @@ title: Avatar
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| icon | 设置头像的图标类型,参考 `Icon` 组件 | string | - | |
|
||||
| icon | 设置头像的图标类型,可设为 Icon 的 `type` 或 ReactNode | string \| ReactNode | - | |
|
||||
| shape | 指定头像的形状 | Enum{ 'circle', 'square' } | `circle` | |
|
||||
| size | 设置头像的大小 | number \| Enum{ 'large', 'small', 'default' } | `default` | |
|
||||
| src | 图片类头像的资源地址 | string | - | |
|
||||
|
||||
@@ -30,8 +30,12 @@ describe('react router', () => {
|
||||
afterAll(() => {
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
// https://github.com/airbnb/enzyme/issues/875
|
||||
(process.env.REACT === '15' ? it.skip : it)('react router 4', () => {
|
||||
it('react router 4', () => {
|
||||
if (process.env.REACT === '15') {
|
||||
return;
|
||||
}
|
||||
const Home = withRouter(props => {
|
||||
const { location, history } = props;
|
||||
const pathSnippets = location.pathname.split('/').filter(i => i);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -73,6 +81,10 @@
|
||||
|
||||
&-icon-only {
|
||||
.btn-square(@btn-prefix-cls);
|
||||
|
||||
> i {
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
&-round {
|
||||
@@ -118,7 +130,9 @@
|
||||
|
||||
&&-loading {
|
||||
position: relative;
|
||||
pointer-events: none;
|
||||
&:not([disabled]) {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
&&-loading::before {
|
||||
|
||||
@@ -124,6 +124,9 @@
|
||||
z-index: 0;
|
||||
}
|
||||
}
|
||||
> .@{btnClassName}-icon-only {
|
||||
font-size: @font-size-base;
|
||||
}
|
||||
// size
|
||||
&-lg > .@{btnClassName},
|
||||
&-lg > span > .@{btnClassName} {
|
||||
|
||||
@@ -316,7 +316,7 @@ describe('Calendar', () => {
|
||||
|
||||
for (let index = start; index < end; index += 1) {
|
||||
monthOptions.push(
|
||||
<Select.Option className="month-item" key={`${index}`}>
|
||||
<Select.Option className="month-item" key={`${index}`} value={index}>
|
||||
{months[index]}
|
||||
</Select.Option>,
|
||||
);
|
||||
|
||||
3
components/calendar/locale/mk_MK.tsx
Normal file
3
components/calendar/locale/mk_MK.tsx
Normal file
@@ -0,0 +1,3 @@
|
||||
import mk_MK from '../../date-picker/locale/mk_MK';
|
||||
|
||||
export default mk_MK;
|
||||
@@ -72,9 +72,3 @@ interface Option {
|
||||
| ------- | ------------ | ------- |
|
||||
| blur() | remove focus | |
|
||||
| focus() | get focus | |
|
||||
|
||||
<style>
|
||||
.ant-cascader-picker {
|
||||
width: 300px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -74,10 +74,4 @@ interface Option {
|
||||
| blur() | 移除焦点 | |
|
||||
| focus() | 获取焦点 | |
|
||||
|
||||
<style>
|
||||
.ant-cascader-picker {
|
||||
width: 300px;
|
||||
}
|
||||
</style>
|
||||
|
||||
> 注意,如果需要获得中国省市区数据,可以参考 [china-division](https://gist.github.com/afc163/7582f35654fd03d5be7009444345ea17)。
|
||||
|
||||
@@ -34,10 +34,20 @@ title: Checkbox
|
||||
| defaultValue | 默认选中的选项 | string\[] | \[] | 3.6.2 |
|
||||
| disabled | 整组失效 | boolean | false | 3.6.2 |
|
||||
| name | CheckboxGroup 下所有 `input[type="checkbox"]` 的 `name` 属性 | string | - | 3.16.0 |
|
||||
| options | 指定可选项 | string\[] | \[] | 3.6.2 |
|
||||
| options | 指定可选项 | string\[] \| Option\[] | \[] | 3.6.2 |
|
||||
| value | 指定选中的选项 | string\[] | \[] | 3.6.2 |
|
||||
| onChange | 变化时回调函数 | Function(checkedValue) | - | 3.6.2 |
|
||||
|
||||
##### Option
|
||||
|
||||
```typescript
|
||||
interface Option {
|
||||
label: string;
|
||||
value: string;
|
||||
disabled?: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
### 方法
|
||||
|
||||
#### Checkbox
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 21%;
|
||||
left: 22%;
|
||||
display: table;
|
||||
width: @check-width;
|
||||
height: @check-height;
|
||||
|
||||
@@ -6791,7 +6791,6 @@ exports[`ConfigProvider components Drawer configProvider 1`] = `
|
||||
>
|
||||
<div
|
||||
class="config-drawer-wrapper-body"
|
||||
style="overflow:auto;height:100%"
|
||||
>
|
||||
<div
|
||||
class="config-drawer-header-no-title"
|
||||
@@ -6851,7 +6850,6 @@ exports[`ConfigProvider components Drawer normal 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-wrapper-body"
|
||||
style="overflow:auto;height:100%"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-header-no-title"
|
||||
@@ -6911,7 +6909,6 @@ exports[`ConfigProvider components Drawer prefixCls 1`] = `
|
||||
>
|
||||
<div
|
||||
class="prefix-Drawer-wrapper-body"
|
||||
style="overflow:auto;height:100%"
|
||||
>
|
||||
<div
|
||||
class="prefix-Drawer-header-no-title"
|
||||
@@ -8156,7 +8153,9 @@ exports[`ConfigProvider components Menu prefixCls 1`] = `
|
||||
|
||||
exports[`ConfigProvider components Modal configProvider 1`] = `
|
||||
<div>
|
||||
<div>
|
||||
<div
|
||||
class="config-modal-root"
|
||||
>
|
||||
<div
|
||||
class="config-modal-mask"
|
||||
/>
|
||||
@@ -8248,7 +8247,9 @@ exports[`ConfigProvider components Modal configProvider 1`] = `
|
||||
|
||||
exports[`ConfigProvider components Modal normal 1`] = `
|
||||
<div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-modal-root"
|
||||
>
|
||||
<div
|
||||
class="ant-modal-mask"
|
||||
/>
|
||||
@@ -8340,7 +8341,9 @@ exports[`ConfigProvider components Modal normal 1`] = `
|
||||
|
||||
exports[`ConfigProvider components Modal prefixCls 1`] = `
|
||||
<div>
|
||||
<div>
|
||||
<div
|
||||
class="prefix-Modal-root"
|
||||
>
|
||||
<div
|
||||
class="prefix-Modal-mask"
|
||||
/>
|
||||
@@ -11159,7 +11162,7 @@ exports[`ConfigProvider components Slider configProvider 1`] = `
|
||||
/>
|
||||
<div>
|
||||
<div
|
||||
class="config-tooltip config-tooltip-placement-top "
|
||||
class="config-tooltip config-slider-tooltip config-tooltip-placement-top "
|
||||
>
|
||||
<div
|
||||
class="config-tooltip-content"
|
||||
@@ -11208,7 +11211,7 @@ exports[`ConfigProvider components Slider normal 1`] = `
|
||||
/>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip ant-tooltip-placement-top "
|
||||
class="ant-tooltip ant-slider-tooltip ant-tooltip-placement-top "
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
@@ -11257,7 +11260,7 @@ exports[`ConfigProvider components Slider prefixCls 1`] = `
|
||||
/>
|
||||
<div>
|
||||
<div
|
||||
class="prefix-Slider-tooltip prefix-Slider-tooltip-placement-top "
|
||||
class="prefix-Slider-tooltip prefix-Slider-tooltip prefix-Slider-tooltip-placement-top "
|
||||
>
|
||||
<div
|
||||
class="prefix-Slider-tooltip-content"
|
||||
@@ -11601,7 +11604,7 @@ exports[`ConfigProvider components Table configProvider 1`] = `
|
||||
>
|
||||
<tr>
|
||||
<th
|
||||
class="config-table-column-has-actions config-table-column-has-filters config-table-column-has-sorters"
|
||||
class="config-table-column-has-actions config-table-column-has-filters config-table-column-has-sorters config-table-row-cell-last"
|
||||
>
|
||||
<span
|
||||
class="config-table-header-column"
|
||||
@@ -11847,7 +11850,7 @@ exports[`ConfigProvider components Table normal 1`] = `
|
||||
>
|
||||
<tr>
|
||||
<th
|
||||
class="ant-table-column-has-actions ant-table-column-has-filters ant-table-column-has-sorters"
|
||||
class="ant-table-column-has-actions ant-table-column-has-filters ant-table-column-has-sorters ant-table-row-cell-last"
|
||||
>
|
||||
<span
|
||||
class="ant-table-header-column"
|
||||
@@ -12093,7 +12096,7 @@ exports[`ConfigProvider components Table prefixCls 1`] = `
|
||||
>
|
||||
<tr>
|
||||
<th
|
||||
class="prefix-Table-column-has-actions prefix-Table-column-has-filters prefix-Table-column-has-sorters"
|
||||
class="prefix-Table-column-has-actions prefix-Table-column-has-filters prefix-Table-column-has-sorters prefix-Table-row-cell-last"
|
||||
>
|
||||
<span
|
||||
class="prefix-Table-header-column"
|
||||
@@ -17366,53 +17369,24 @@ exports[`ConfigProvider components Upload configProvider 1`] = `
|
||||
class="config-upload-list config-upload-list-text"
|
||||
>
|
||||
<div
|
||||
class="config-upload-list-item config-upload-list-item-done config-upload-list-item-list-type-text"
|
||||
class=""
|
||||
>
|
||||
<div
|
||||
class="config-upload-list-item-info"
|
||||
>
|
||||
<span>
|
||||
<i
|
||||
aria-label="icon: paper-clip"
|
||||
class="anticon anticon-paper-clip"
|
||||
<span>
|
||||
<div
|
||||
class="config-upload-list-item config-upload-list-item-done config-upload-list-item-list-type-text"
|
||||
>
|
||||
<div
|
||||
class="config-upload-list-item-info"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="paper-clip"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M779.3 196.6c-94.2-94.2-247.6-94.2-341.7 0l-261 260.8c-1.7 1.7-2.6 4-2.6 6.4s.9 4.7 2.6 6.4l36.9 36.9a9 9 0 0 0 12.7 0l261-260.8c32.4-32.4 75.5-50.2 121.3-50.2s88.9 17.8 121.2 50.2c32.4 32.4 50.2 75.5 50.2 121.2 0 45.8-17.8 88.8-50.2 121.2l-266 265.9-43.1 43.1c-40.3 40.3-105.8 40.3-146.1 0-19.5-19.5-30.2-45.4-30.2-73s10.7-53.5 30.2-73l263.9-263.8c6.7-6.6 15.5-10.3 24.9-10.3h.1c9.4 0 18.1 3.7 24.7 10.3 6.7 6.7 10.3 15.5 10.3 24.9 0 9.3-3.7 18.1-10.3 24.7L372.4 653c-1.7 1.7-2.6 4-2.6 6.4s.9 4.7 2.6 6.4l36.9 36.9a9 9 0 0 0 12.7 0l215.6-215.6c19.9-19.9 30.8-46.3 30.8-74.4s-11-54.6-30.8-74.4c-41.1-41.1-107.9-41-149 0L463 364 224.8 602.1A172.22 172.22 0 0 0 174 724.8c0 46.3 18.1 89.8 50.8 122.5 33.9 33.8 78.3 50.7 122.7 50.7 44.4 0 88.8-16.9 122.6-50.7l309.2-309C824.8 492.7 850 432 850 367.5c.1-64.6-25.1-125.3-70.7-170.9z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
<span
|
||||
class="config-upload-list-item-name config-upload-list-item-name-icon-count-2"
|
||||
title="xxx.png"
|
||||
>
|
||||
xxx.png
|
||||
</span>
|
||||
<span
|
||||
class="config-upload-list-item-card-actions "
|
||||
>
|
||||
<a
|
||||
title="Download file"
|
||||
>
|
||||
<span>
|
||||
<i
|
||||
aria-label="icon: download"
|
||||
class="anticon anticon-download"
|
||||
tabindex="-1"
|
||||
title="Download file"
|
||||
aria-label="icon: paper-clip"
|
||||
class="anticon anticon-paper-clip"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="download"
|
||||
data-icon="paper-clip"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
@@ -17420,39 +17394,74 @@ exports[`ConfigProvider components Upload configProvider 1`] = `
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M505.7 661a8 8 0 0 0 12.6 0l112-141.7c4.1-5.2.4-12.9-6.3-12.9h-74.1V168c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v338.3H400c-6.7 0-10.4 7.7-6.3 12.9l112 141.8zM878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8z"
|
||||
d="M779.3 196.6c-94.2-94.2-247.6-94.2-341.7 0l-261 260.8c-1.7 1.7-2.6 4-2.6 6.4s.9 4.7 2.6 6.4l36.9 36.9a9 9 0 0 0 12.7 0l261-260.8c32.4-32.4 75.5-50.2 121.3-50.2s88.9 17.8 121.2 50.2c32.4 32.4 50.2 75.5 50.2 121.2 0 45.8-17.8 88.8-50.2 121.2l-266 265.9-43.1 43.1c-40.3 40.3-105.8 40.3-146.1 0-19.5-19.5-30.2-45.4-30.2-73s10.7-53.5 30.2-73l263.9-263.8c6.7-6.6 15.5-10.3 24.9-10.3h.1c9.4 0 18.1 3.7 24.7 10.3 6.7 6.7 10.3 15.5 10.3 24.9 0 9.3-3.7 18.1-10.3 24.7L372.4 653c-1.7 1.7-2.6 4-2.6 6.4s.9 4.7 2.6 6.4l36.9 36.9a9 9 0 0 0 12.7 0l215.6-215.6c19.9-19.9 30.8-46.3 30.8-74.4s-11-54.6-30.8-74.4c-41.1-41.1-107.9-41-149 0L463 364 224.8 602.1A172.22 172.22 0 0 0 174 724.8c0 46.3 18.1 89.8 50.8 122.5 33.9 33.8 78.3 50.7 122.7 50.7 44.4 0 88.8-16.9 122.6-50.7l309.2-309C824.8 492.7 850 432 850 367.5c.1-64.6-25.1-125.3-70.7-170.9z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</a>
|
||||
<a
|
||||
title="Remove file"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: delete"
|
||||
class="anticon anticon-delete"
|
||||
tabindex="-1"
|
||||
title="Remove file"
|
||||
<span
|
||||
class="config-upload-list-item-name config-upload-list-item-name-icon-count-2"
|
||||
title="xxx.png"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="delete"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
xxx.png
|
||||
</span>
|
||||
<span
|
||||
class="config-upload-list-item-card-actions "
|
||||
>
|
||||
<a
|
||||
title="Download file"
|
||||
>
|
||||
<path
|
||||
d="M360 184h-8c4.4 0 8-3.6 8-8v8h304v-8c0 4.4 3.6 8 8 8h-8v72h72v-80c0-35.3-28.7-64-64-64H352c-35.3 0-64 28.7-64 64v80h72v-72zm504 72H160c-17.7 0-32 14.3-32 32v32c0 4.4 3.6 8 8 8h60.4l24.7 523c1.6 34.1 29.8 61 63.9 61h454c34.2 0 62.3-26.8 63.9-61l24.7-523H888c4.4 0 8-3.6 8-8v-32c0-17.7-14.3-32-32-32zM731.3 840H292.7l-24.2-512h487l-24.2 512z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</a>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<i
|
||||
aria-label="icon: download"
|
||||
class="anticon anticon-download"
|
||||
tabindex="-1"
|
||||
title="Download file"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="download"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M505.7 661a8 8 0 0 0 12.6 0l112-141.7c4.1-5.2.4-12.9-6.3-12.9h-74.1V168c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v338.3H400c-6.7 0-10.4 7.7-6.3 12.9l112 141.8zM878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</a>
|
||||
<a
|
||||
title="Remove file"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: delete"
|
||||
class="anticon anticon-delete"
|
||||
tabindex="-1"
|
||||
title="Remove file"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="delete"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M360 184h-8c4.4 0 8-3.6 8-8v8h304v-8c0 4.4 3.6 8 8 8h-8v72h72v-80c0-35.3-28.7-64-64-64H352c-35.3 0-64 28.7-64 64v80h72v-72zm504 72H160c-17.7 0-32 14.3-32 32v32c0 4.4 3.6 8 8 8h60.4l24.7 523c1.6 34.1 29.8 61 63.9 61h454c34.2 0 62.3-26.8 63.9-61l24.7-523H888c4.4 0 8-3.6 8-8v-32c0-17.7-14.3-32-32-32zM731.3 840H292.7l-24.2-512h487l-24.2 512z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</a>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
@@ -17469,53 +17478,24 @@ exports[`ConfigProvider components Upload normal 1`] = `
|
||||
class="ant-upload-list ant-upload-list-text"
|
||||
>
|
||||
<div
|
||||
class="ant-upload-list-item ant-upload-list-item-done ant-upload-list-item-list-type-text"
|
||||
class=""
|
||||
>
|
||||
<div
|
||||
class="ant-upload-list-item-info"
|
||||
>
|
||||
<span>
|
||||
<i
|
||||
aria-label="icon: paper-clip"
|
||||
class="anticon anticon-paper-clip"
|
||||
<span>
|
||||
<div
|
||||
class="ant-upload-list-item ant-upload-list-item-done ant-upload-list-item-list-type-text"
|
||||
>
|
||||
<div
|
||||
class="ant-upload-list-item-info"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="paper-clip"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M779.3 196.6c-94.2-94.2-247.6-94.2-341.7 0l-261 260.8c-1.7 1.7-2.6 4-2.6 6.4s.9 4.7 2.6 6.4l36.9 36.9a9 9 0 0 0 12.7 0l261-260.8c32.4-32.4 75.5-50.2 121.3-50.2s88.9 17.8 121.2 50.2c32.4 32.4 50.2 75.5 50.2 121.2 0 45.8-17.8 88.8-50.2 121.2l-266 265.9-43.1 43.1c-40.3 40.3-105.8 40.3-146.1 0-19.5-19.5-30.2-45.4-30.2-73s10.7-53.5 30.2-73l263.9-263.8c6.7-6.6 15.5-10.3 24.9-10.3h.1c9.4 0 18.1 3.7 24.7 10.3 6.7 6.7 10.3 15.5 10.3 24.9 0 9.3-3.7 18.1-10.3 24.7L372.4 653c-1.7 1.7-2.6 4-2.6 6.4s.9 4.7 2.6 6.4l36.9 36.9a9 9 0 0 0 12.7 0l215.6-215.6c19.9-19.9 30.8-46.3 30.8-74.4s-11-54.6-30.8-74.4c-41.1-41.1-107.9-41-149 0L463 364 224.8 602.1A172.22 172.22 0 0 0 174 724.8c0 46.3 18.1 89.8 50.8 122.5 33.9 33.8 78.3 50.7 122.7 50.7 44.4 0 88.8-16.9 122.6-50.7l309.2-309C824.8 492.7 850 432 850 367.5c.1-64.6-25.1-125.3-70.7-170.9z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
<span
|
||||
class="ant-upload-list-item-name ant-upload-list-item-name-icon-count-2"
|
||||
title="xxx.png"
|
||||
>
|
||||
xxx.png
|
||||
</span>
|
||||
<span
|
||||
class="ant-upload-list-item-card-actions "
|
||||
>
|
||||
<a
|
||||
title="Download file"
|
||||
>
|
||||
<span>
|
||||
<i
|
||||
aria-label="icon: download"
|
||||
class="anticon anticon-download"
|
||||
tabindex="-1"
|
||||
title="Download file"
|
||||
aria-label="icon: paper-clip"
|
||||
class="anticon anticon-paper-clip"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="download"
|
||||
data-icon="paper-clip"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
@@ -17523,39 +17503,74 @@ exports[`ConfigProvider components Upload normal 1`] = `
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M505.7 661a8 8 0 0 0 12.6 0l112-141.7c4.1-5.2.4-12.9-6.3-12.9h-74.1V168c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v338.3H400c-6.7 0-10.4 7.7-6.3 12.9l112 141.8zM878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8z"
|
||||
d="M779.3 196.6c-94.2-94.2-247.6-94.2-341.7 0l-261 260.8c-1.7 1.7-2.6 4-2.6 6.4s.9 4.7 2.6 6.4l36.9 36.9a9 9 0 0 0 12.7 0l261-260.8c32.4-32.4 75.5-50.2 121.3-50.2s88.9 17.8 121.2 50.2c32.4 32.4 50.2 75.5 50.2 121.2 0 45.8-17.8 88.8-50.2 121.2l-266 265.9-43.1 43.1c-40.3 40.3-105.8 40.3-146.1 0-19.5-19.5-30.2-45.4-30.2-73s10.7-53.5 30.2-73l263.9-263.8c6.7-6.6 15.5-10.3 24.9-10.3h.1c9.4 0 18.1 3.7 24.7 10.3 6.7 6.7 10.3 15.5 10.3 24.9 0 9.3-3.7 18.1-10.3 24.7L372.4 653c-1.7 1.7-2.6 4-2.6 6.4s.9 4.7 2.6 6.4l36.9 36.9a9 9 0 0 0 12.7 0l215.6-215.6c19.9-19.9 30.8-46.3 30.8-74.4s-11-54.6-30.8-74.4c-41.1-41.1-107.9-41-149 0L463 364 224.8 602.1A172.22 172.22 0 0 0 174 724.8c0 46.3 18.1 89.8 50.8 122.5 33.9 33.8 78.3 50.7 122.7 50.7 44.4 0 88.8-16.9 122.6-50.7l309.2-309C824.8 492.7 850 432 850 367.5c.1-64.6-25.1-125.3-70.7-170.9z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</a>
|
||||
<a
|
||||
title="Remove file"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: delete"
|
||||
class="anticon anticon-delete"
|
||||
tabindex="-1"
|
||||
title="Remove file"
|
||||
<span
|
||||
class="ant-upload-list-item-name ant-upload-list-item-name-icon-count-2"
|
||||
title="xxx.png"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="delete"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
xxx.png
|
||||
</span>
|
||||
<span
|
||||
class="ant-upload-list-item-card-actions "
|
||||
>
|
||||
<a
|
||||
title="Download file"
|
||||
>
|
||||
<path
|
||||
d="M360 184h-8c4.4 0 8-3.6 8-8v8h304v-8c0 4.4 3.6 8 8 8h-8v72h72v-80c0-35.3-28.7-64-64-64H352c-35.3 0-64 28.7-64 64v80h72v-72zm504 72H160c-17.7 0-32 14.3-32 32v32c0 4.4 3.6 8 8 8h60.4l24.7 523c1.6 34.1 29.8 61 63.9 61h454c34.2 0 62.3-26.8 63.9-61l24.7-523H888c4.4 0 8-3.6 8-8v-32c0-17.7-14.3-32-32-32zM731.3 840H292.7l-24.2-512h487l-24.2 512z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</a>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<i
|
||||
aria-label="icon: download"
|
||||
class="anticon anticon-download"
|
||||
tabindex="-1"
|
||||
title="Download file"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="download"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M505.7 661a8 8 0 0 0 12.6 0l112-141.7c4.1-5.2.4-12.9-6.3-12.9h-74.1V168c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v338.3H400c-6.7 0-10.4 7.7-6.3 12.9l112 141.8zM878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</a>
|
||||
<a
|
||||
title="Remove file"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: delete"
|
||||
class="anticon anticon-delete"
|
||||
tabindex="-1"
|
||||
title="Remove file"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="delete"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M360 184h-8c4.4 0 8-3.6 8-8v8h304v-8c0 4.4 3.6 8 8 8h-8v72h72v-80c0-35.3-28.7-64-64-64H352c-35.3 0-64 28.7-64 64v80h72v-72zm504 72H160c-17.7 0-32 14.3-32 32v32c0 4.4 3.6 8 8 8h60.4l24.7 523c1.6 34.1 29.8 61 63.9 61h454c34.2 0 62.3-26.8 63.9-61l24.7-523H888c4.4 0 8-3.6 8-8v-32c0-17.7-14.3-32-32-32zM731.3 840H292.7l-24.2-512h487l-24.2 512z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</a>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
@@ -17572,53 +17587,24 @@ exports[`ConfigProvider components Upload prefixCls 1`] = `
|
||||
class="ant-upload-list ant-upload-list-text"
|
||||
>
|
||||
<div
|
||||
class="ant-upload-list-item ant-upload-list-item-done ant-upload-list-item-list-type-text"
|
||||
class=""
|
||||
>
|
||||
<div
|
||||
class="ant-upload-list-item-info"
|
||||
>
|
||||
<span>
|
||||
<i
|
||||
aria-label="icon: paper-clip"
|
||||
class="anticon anticon-paper-clip"
|
||||
<span>
|
||||
<div
|
||||
class="ant-upload-list-item ant-upload-list-item-done ant-upload-list-item-list-type-text"
|
||||
>
|
||||
<div
|
||||
class="ant-upload-list-item-info"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="paper-clip"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M779.3 196.6c-94.2-94.2-247.6-94.2-341.7 0l-261 260.8c-1.7 1.7-2.6 4-2.6 6.4s.9 4.7 2.6 6.4l36.9 36.9a9 9 0 0 0 12.7 0l261-260.8c32.4-32.4 75.5-50.2 121.3-50.2s88.9 17.8 121.2 50.2c32.4 32.4 50.2 75.5 50.2 121.2 0 45.8-17.8 88.8-50.2 121.2l-266 265.9-43.1 43.1c-40.3 40.3-105.8 40.3-146.1 0-19.5-19.5-30.2-45.4-30.2-73s10.7-53.5 30.2-73l263.9-263.8c6.7-6.6 15.5-10.3 24.9-10.3h.1c9.4 0 18.1 3.7 24.7 10.3 6.7 6.7 10.3 15.5 10.3 24.9 0 9.3-3.7 18.1-10.3 24.7L372.4 653c-1.7 1.7-2.6 4-2.6 6.4s.9 4.7 2.6 6.4l36.9 36.9a9 9 0 0 0 12.7 0l215.6-215.6c19.9-19.9 30.8-46.3 30.8-74.4s-11-54.6-30.8-74.4c-41.1-41.1-107.9-41-149 0L463 364 224.8 602.1A172.22 172.22 0 0 0 174 724.8c0 46.3 18.1 89.8 50.8 122.5 33.9 33.8 78.3 50.7 122.7 50.7 44.4 0 88.8-16.9 122.6-50.7l309.2-309C824.8 492.7 850 432 850 367.5c.1-64.6-25.1-125.3-70.7-170.9z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
<span
|
||||
class="ant-upload-list-item-name ant-upload-list-item-name-icon-count-2"
|
||||
title="xxx.png"
|
||||
>
|
||||
xxx.png
|
||||
</span>
|
||||
<span
|
||||
class="ant-upload-list-item-card-actions "
|
||||
>
|
||||
<a
|
||||
title="Download file"
|
||||
>
|
||||
<span>
|
||||
<i
|
||||
aria-label="icon: download"
|
||||
class="anticon anticon-download"
|
||||
tabindex="-1"
|
||||
title="Download file"
|
||||
aria-label="icon: paper-clip"
|
||||
class="anticon anticon-paper-clip"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="download"
|
||||
data-icon="paper-clip"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
@@ -17626,39 +17612,74 @@ exports[`ConfigProvider components Upload prefixCls 1`] = `
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M505.7 661a8 8 0 0 0 12.6 0l112-141.7c4.1-5.2.4-12.9-6.3-12.9h-74.1V168c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v338.3H400c-6.7 0-10.4 7.7-6.3 12.9l112 141.8zM878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8z"
|
||||
d="M779.3 196.6c-94.2-94.2-247.6-94.2-341.7 0l-261 260.8c-1.7 1.7-2.6 4-2.6 6.4s.9 4.7 2.6 6.4l36.9 36.9a9 9 0 0 0 12.7 0l261-260.8c32.4-32.4 75.5-50.2 121.3-50.2s88.9 17.8 121.2 50.2c32.4 32.4 50.2 75.5 50.2 121.2 0 45.8-17.8 88.8-50.2 121.2l-266 265.9-43.1 43.1c-40.3 40.3-105.8 40.3-146.1 0-19.5-19.5-30.2-45.4-30.2-73s10.7-53.5 30.2-73l263.9-263.8c6.7-6.6 15.5-10.3 24.9-10.3h.1c9.4 0 18.1 3.7 24.7 10.3 6.7 6.7 10.3 15.5 10.3 24.9 0 9.3-3.7 18.1-10.3 24.7L372.4 653c-1.7 1.7-2.6 4-2.6 6.4s.9 4.7 2.6 6.4l36.9 36.9a9 9 0 0 0 12.7 0l215.6-215.6c19.9-19.9 30.8-46.3 30.8-74.4s-11-54.6-30.8-74.4c-41.1-41.1-107.9-41-149 0L463 364 224.8 602.1A172.22 172.22 0 0 0 174 724.8c0 46.3 18.1 89.8 50.8 122.5 33.9 33.8 78.3 50.7 122.7 50.7 44.4 0 88.8-16.9 122.6-50.7l309.2-309C824.8 492.7 850 432 850 367.5c.1-64.6-25.1-125.3-70.7-170.9z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</a>
|
||||
<a
|
||||
title="Remove file"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: delete"
|
||||
class="anticon anticon-delete"
|
||||
tabindex="-1"
|
||||
title="Remove file"
|
||||
<span
|
||||
class="ant-upload-list-item-name ant-upload-list-item-name-icon-count-2"
|
||||
title="xxx.png"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="delete"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
xxx.png
|
||||
</span>
|
||||
<span
|
||||
class="ant-upload-list-item-card-actions "
|
||||
>
|
||||
<a
|
||||
title="Download file"
|
||||
>
|
||||
<path
|
||||
d="M360 184h-8c4.4 0 8-3.6 8-8v8h304v-8c0 4.4 3.6 8 8 8h-8v72h72v-80c0-35.3-28.7-64-64-64H352c-35.3 0-64 28.7-64 64v80h72v-72zm504 72H160c-17.7 0-32 14.3-32 32v32c0 4.4 3.6 8 8 8h60.4l24.7 523c1.6 34.1 29.8 61 63.9 61h454c34.2 0 62.3-26.8 63.9-61l24.7-523H888c4.4 0 8-3.6 8-8v-32c0-17.7-14.3-32-32-32zM731.3 840H292.7l-24.2-512h487l-24.2 512z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</a>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<i
|
||||
aria-label="icon: download"
|
||||
class="anticon anticon-download"
|
||||
tabindex="-1"
|
||||
title="Download file"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="download"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M505.7 661a8 8 0 0 0 12.6 0l112-141.7c4.1-5.2.4-12.9-6.3-12.9h-74.1V168c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v338.3H400c-6.7 0-10.4 7.7-6.3 12.9l112 141.8zM878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</a>
|
||||
<a
|
||||
title="Remove file"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: delete"
|
||||
class="anticon anticon-delete"
|
||||
tabindex="-1"
|
||||
title="Remove file"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="delete"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M360 184h-8c4.4 0 8-3.6 8-8v8h304v-8c0 4.4 3.6 8 8 8h-8v72h72v-80c0-35.3-28.7-64-64-64H352c-35.3 0-64 28.7-64 64v80h72v-72zm504 72H160c-17.7 0-32 14.3-32 32v32c0 4.4 3.6 8 8 8h60.4l24.7 523c1.6 34.1 29.8 61 63.9 61h454c34.2 0 62.3-26.8 63.9-61l24.7-523H888c4.4 0 8-3.6 8-8v-32c0-17.7-14.3-32-32-32zM731.3 840H292.7l-24.2-512h487l-24.2 512z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</a>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
|
||||
@@ -9,7 +9,7 @@ title: ConfigProvider
|
||||
|
||||
## Usage
|
||||
|
||||
This component provides a configuration to all React components underneath itself via the [context API](https://facebook.github.io/react/docs/context.html), In the render tree all components will have access to the provided config.
|
||||
This component provides a configuration to all React components underneath itself via the [context API](https://facebook.github.io/react/docs/context.html). In the render tree all components will have access to the provided config.
|
||||
|
||||
```jsx
|
||||
import { ConfigProvider } from 'antd';
|
||||
@@ -25,7 +25,7 @@ return (
|
||||
|
||||
### Content Security Policy
|
||||
|
||||
Some component use dynamic style to support wave effect. You can config `csp` prop if Content Security Policy (CSP) is enabled:
|
||||
Some components use dynamic style to support wave effect. You can config `csp` prop if Content Security Policy (CSP) is enabled:
|
||||
|
||||
```jsx
|
||||
<ConfigProvider csp={{ nonce: 'YourNonceCode' }}>
|
||||
@@ -44,3 +44,29 @@ Some component use dynamic style to support wave effect. You can config `csp` pr
|
||||
| locale | language package setting, you can find the packages in [antd/es/locale](http://unpkg.com/antd/es/locale/) | object | 3.21.0 |
|
||||
| prefixCls | set prefix class | string | ant | 3.12.0 |
|
||||
| pageHeader | Unify the ghost of pageHeader ,Ref [pageHeader](<(/components/page-header)> | { ghost:boolean } | 'true' | 3.24.0 |
|
||||
|
||||
## FAQ
|
||||
|
||||
#### 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>
|
||||
```
|
||||
|
||||
@@ -45,3 +45,29 @@ return (
|
||||
| locale | 语言包配置,语言包可到 [antd/es/locale](http://unpkg.com/antd/es/locale/) 目录下寻找 | object | - | 3.21.0 |
|
||||
| prefixCls | 设置统一样式前缀 | string | ant | 3.12.0 |
|
||||
| pageHeader | 统一设置 pageHeader 的 ghost,参考 [pageHeader](<(/components/page-header)>) | { ghost: boolean } | 'true' | 3.24.0 |
|
||||
|
||||
## FAQ
|
||||
|
||||
#### 为什么我使用了 ConfigProvider `locale`,时间类组件的国际化还有问题?
|
||||
|
||||
请检查是否设置了 `moment.locale('zh-cn')`,或者是否有两个版本的 moment 共存。
|
||||
|
||||
#### 配置 `getPopupContainer` 导致 Modal 报错?
|
||||
|
||||
相关 issue:https://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>
|
||||
```
|
||||
|
||||
@@ -11,7 +11,7 @@ import Tag from '../tag';
|
||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||
import warning from '../_util/warning';
|
||||
import interopDefault from '../_util/interopDefault';
|
||||
import { RangePickerValue, RangePickerPresetRange } from './interface';
|
||||
import { RangePickerValue, RangePickerPresetRange, RangePickerProps } from './interface';
|
||||
import { formatDate } from './utils';
|
||||
import InputIcon from './InputIcon';
|
||||
|
||||
@@ -31,7 +31,7 @@ function getShowDateFromValue(value: RangePickerValue, mode?: string | string[])
|
||||
if (mode && mode[0] === 'month') {
|
||||
return [start, end] as RangePickerValue;
|
||||
}
|
||||
const newEnd = end && end.isSame(start, 'month') ? end.clone().add(1, 'month') : end;
|
||||
const newEnd = end && end.isSame(start!, 'month') ? end.clone().add(1, 'month') : end;
|
||||
return [start, newEnd] as RangePickerValue;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ function isEmptyArray(arr: any) {
|
||||
return false;
|
||||
}
|
||||
|
||||
function fixLocale(value: RangePickerValue | undefined, localeCode: string) {
|
||||
function fixLocale(value: RangePickerValue | undefined, localeCode: string | undefined) {
|
||||
if (!localeCode) {
|
||||
return;
|
||||
}
|
||||
@@ -70,14 +70,14 @@ function fixLocale(value: RangePickerValue | undefined, localeCode: string) {
|
||||
}
|
||||
}
|
||||
|
||||
class RangePicker extends React.Component<any, RangePickerState> {
|
||||
class RangePicker extends React.Component<RangePickerProps, RangePickerState> {
|
||||
static defaultProps = {
|
||||
allowClear: true,
|
||||
showToday: false,
|
||||
separator: '~',
|
||||
};
|
||||
|
||||
static getDerivedStateFromProps(nextProps: any, prevState: any) {
|
||||
static getDerivedStateFromProps(nextProps: RangePickerProps, prevState: RangePickerState) {
|
||||
let state = null;
|
||||
if ('value' in nextProps) {
|
||||
const value = nextProps.value || [];
|
||||
@@ -162,11 +162,13 @@ class RangePicker extends React.Component<any, RangePickerState> {
|
||||
showDate: getShowDateFromValue(value) || showDate,
|
||||
}));
|
||||
}
|
||||
if (value[0] && value[0].diff(value[1]) > 0) {
|
||||
if (value[0] && value[1] && value[0].diff(value[1]) > 0) {
|
||||
value[1] = undefined;
|
||||
}
|
||||
const [start, end] = value;
|
||||
props.onChange(value, [formatDate(start, props.format), formatDate(end, props.format)]);
|
||||
if (typeof props.onChange === 'function') {
|
||||
props.onChange(value, [formatDate(start, props.format), formatDate(end, props.format)]);
|
||||
}
|
||||
};
|
||||
|
||||
handleOpenChange = (open: boolean) => {
|
||||
@@ -241,21 +243,24 @@ class RangePicker extends React.Component<any, RangePickerState> {
|
||||
{renderExtraFooter()}
|
||||
</div>
|
||||
) : null;
|
||||
const operations = Object.keys(ranges || {}).map(range => {
|
||||
const value = ranges[range];
|
||||
return (
|
||||
<Tag
|
||||
key={range}
|
||||
prefixCls={tagPrefixCls}
|
||||
color="blue"
|
||||
onClick={() => this.handleRangeClick(value)}
|
||||
onMouseEnter={() => this.setState({ hoverValue: value })}
|
||||
onMouseLeave={this.handleRangeMouseLeave}
|
||||
>
|
||||
{range}
|
||||
</Tag>
|
||||
);
|
||||
});
|
||||
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">
|
||||
@@ -280,6 +285,7 @@ class RangePicker extends React.Component<any, RangePickerState> {
|
||||
ranges,
|
||||
onOk,
|
||||
locale,
|
||||
// @ts-ignore
|
||||
localeCode,
|
||||
format,
|
||||
dateRender,
|
||||
@@ -326,10 +332,12 @@ class RangePicker extends React.Component<any, RangePickerState> {
|
||||
calendarProps.mode = props.mode;
|
||||
}
|
||||
|
||||
const startPlaceholder =
|
||||
'placeholder' in props ? props.placeholder[0] : locale.lang.rangePlaceholder[0];
|
||||
const endPlaceholder =
|
||||
'placeholder' in props ? props.placeholder[1] : locale.lang.rangePlaceholder[1];
|
||||
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
|
||||
@@ -405,7 +413,7 @@ class RangePicker extends React.Component<any, RangePickerState> {
|
||||
return (
|
||||
<span
|
||||
ref={this.savePicker}
|
||||
id={props.id}
|
||||
id={typeof props.id === 'number' ? props.id.toString() : props.id}
|
||||
className={classNames(props.className, props.pickerClass)}
|
||||
style={{ ...style, ...pickerStyle }}
|
||||
tabIndex={props.disabled ? -1 : 0}
|
||||
|
||||
@@ -143,6 +143,7 @@ class WeekPicker extends React.Component<any, WeekPickerState> {
|
||||
onBlur,
|
||||
id,
|
||||
suffixIcon,
|
||||
defaultPickerValue,
|
||||
} = this.props;
|
||||
|
||||
const prefixCls = getPrefixCls('calendar', customizePrefixCls);
|
||||
@@ -170,6 +171,7 @@ class WeekPicker extends React.Component<any, WeekPickerState> {
|
||||
showToday={false}
|
||||
disabledDate={disabledDate}
|
||||
renderFooter={this.renderFooter}
|
||||
defaultValue={defaultPickerValue}
|
||||
/>
|
||||
);
|
||||
const clearIcon =
|
||||
|
||||
@@ -12,6 +12,8 @@ export interface PickerProps {
|
||||
disabled?: boolean;
|
||||
allowClear?: boolean;
|
||||
className?: string;
|
||||
pickerClass?: string;
|
||||
pickerInputClass?: string;
|
||||
suffixIcon?: React.ReactNode;
|
||||
style?: React.CSSProperties;
|
||||
popupStyle?: React.CSSProperties;
|
||||
@@ -21,57 +23,64 @@ export interface PickerProps {
|
||||
getCalendarContainer?: (triggerNode: Element) => HTMLElement;
|
||||
open?: boolean;
|
||||
onOpenChange?: (status: boolean) => void;
|
||||
disabledDate?: (current: moment.Moment | undefined) => boolean;
|
||||
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;
|
||||
defaultValue?: moment.Moment;
|
||||
defaultPickerValue?: moment.Moment;
|
||||
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 type DatePickerMode = typeof DatePickerModes[number];
|
||||
|
||||
export interface DatePickerProps extends PickerProps, SinglePickerProps {
|
||||
showTime?: TimePickerProps | boolean;
|
||||
showToday?: boolean;
|
||||
open?: boolean;
|
||||
disabledTime?: (
|
||||
current: moment.Moment | undefined,
|
||||
current?: moment.Moment | null,
|
||||
) => {
|
||||
disabledHours?: () => number[];
|
||||
disabledMinutes?: () => number[];
|
||||
disabledSeconds?: () => number[];
|
||||
};
|
||||
onOpenChange?: (status: boolean) => void;
|
||||
onPanelChange?: (value: moment.Moment | undefined, mode: DatePickerMode) => void;
|
||||
onOk?: (selectedTime: moment.Moment) => 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
|
||||
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;
|
||||
@@ -84,7 +93,7 @@ export interface RangePickerProps extends PickerProps {
|
||||
mode?: string | string[];
|
||||
separator?: React.ReactNode;
|
||||
disabledTime?: (
|
||||
current: moment.Moment | undefined,
|
||||
current: RangePickerValue,
|
||||
type: string,
|
||||
) => {
|
||||
disabledHours?: () => number[];
|
||||
@@ -93,6 +102,8 @@ export interface RangePickerProps extends PickerProps {
|
||||
};
|
||||
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 {
|
||||
|
||||
19
components/date-picker/locale/mk_MK.tsx
Normal file
19
components/date-picker/locale/mk_MK.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import CalendarLocale from 'rc-calendar/lib/locale/mk_MK';
|
||||
import TimePickerLocale from '../../time-picker/locale/mk_MK';
|
||||
|
||||
// Merge into a locale object
|
||||
const locale = {
|
||||
lang: {
|
||||
placeholder: 'Избери датум',
|
||||
rangePlaceholder: ['Од датум', 'До датум'],
|
||||
...CalendarLocale,
|
||||
},
|
||||
timePickerLocale: {
|
||||
...TimePickerLocale,
|
||||
},
|
||||
};
|
||||
|
||||
// All settings at:
|
||||
// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json
|
||||
|
||||
export default locale;
|
||||
@@ -3,7 +3,7 @@ import * as moment from 'moment';
|
||||
// eslint-disable-next-line import/prefer-default-export
|
||||
export function formatDate(
|
||||
value: moment.Moment | undefined | null,
|
||||
format: string | string[],
|
||||
format: string | string[] | undefined,
|
||||
): string {
|
||||
if (!value) {
|
||||
return '';
|
||||
|
||||
@@ -192,6 +192,7 @@ export default function wrapPicker(Picker: React.ComponentClass<any>, pickerType
|
||||
className={timePickerCls}
|
||||
placeholder={locale.timePickerLocale.placeholder}
|
||||
transitionName="slide-up"
|
||||
onEsc={() => {}}
|
||||
/>
|
||||
) : null;
|
||||
|
||||
|
||||
@@ -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,
|
||||
}),
|
||||
|
||||
@@ -263,7 +263,7 @@ exports[`renders ./components/descriptions/demo/border.md correctly 1`] = `
|
||||
<br />
|
||||
Storage space: 10 GB
|
||||
<br />
|
||||
Replication_factor:3
|
||||
Replication factor: 3
|
||||
<br />
|
||||
Region: East China 1
|
||||
<br />
|
||||
@@ -384,7 +384,7 @@ exports[`renders ./components/descriptions/demo/responsive.md correctly 1`] = `
|
||||
<br />
|
||||
Storage space: 10 GB
|
||||
<br />
|
||||
Replication_factor:3
|
||||
Replication factor: 3
|
||||
<br />
|
||||
Region: East China 1
|
||||
</td>
|
||||
@@ -569,7 +569,7 @@ exports[`renders ./components/descriptions/demo/size.md correctly 1`] = `
|
||||
<br />
|
||||
Storage space: 10 GB
|
||||
<br />
|
||||
Replication_factor:3
|
||||
Replication factor: 3
|
||||
<br />
|
||||
Region: East China 1
|
||||
<br />
|
||||
@@ -1025,7 +1025,7 @@ exports[`renders ./components/descriptions/demo/vertical-border.md correctly 1`]
|
||||
<br />
|
||||
Storage space: 10 GB
|
||||
<br />
|
||||
Replication_factor:3
|
||||
Replication factor: 3
|
||||
<br />
|
||||
Region: East China 1
|
||||
<br />
|
||||
|
||||
@@ -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
|
||||
@@ -376,6 +376,78 @@ exports[`Descriptions column is number 1`] = `
|
||||
</Descriptions>
|
||||
`;
|
||||
|
||||
exports[`Descriptions should work with React Fragment 1`] = `
|
||||
<div
|
||||
class="ant-descriptions"
|
||||
>
|
||||
<div
|
||||
class="ant-descriptions-view"
|
||||
>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr
|
||||
class="ant-descriptions-row"
|
||||
>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-label ant-descriptions-item-colon"
|
||||
>
|
||||
bamboo
|
||||
</span>
|
||||
<span
|
||||
class="ant-descriptions-item-content"
|
||||
>
|
||||
bamboo
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="ant-descriptions-row"
|
||||
>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-label ant-descriptions-item-colon"
|
||||
>
|
||||
bamboo
|
||||
</span>
|
||||
<span
|
||||
class="ant-descriptions-item-content"
|
||||
>
|
||||
bamboo
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="ant-descriptions-row"
|
||||
>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-label ant-descriptions-item-colon"
|
||||
>
|
||||
bamboo
|
||||
</span>
|
||||
<span
|
||||
class="ant-descriptions-item-content"
|
||||
>
|
||||
bamboo
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Descriptions vertical layout 1`] = `
|
||||
<Descriptions
|
||||
column={
|
||||
|
||||
@@ -185,4 +185,22 @@ describe('Descriptions', () => {
|
||||
|
||||
expect(wrapper.find('Col').key()).toBe('label-bamboo');
|
||||
});
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/19887
|
||||
it('should work with React Fragment', () => {
|
||||
if (!React.Fragment) {
|
||||
return;
|
||||
}
|
||||
const wrapper = mount(
|
||||
<Descriptions>
|
||||
<Descriptions.Item label="bamboo">bamboo</Descriptions.Item>
|
||||
<>
|
||||
<Descriptions.Item label="bamboo">bamboo</Descriptions.Item>
|
||||
<Descriptions.Item label="bamboo">bamboo</Descriptions.Item>
|
||||
</>
|
||||
</Descriptions>,
|
||||
);
|
||||
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -40,7 +40,7 @@ ReactDOM.render(
|
||||
<br />
|
||||
Storage space: 10 GB
|
||||
<br />
|
||||
Replication_factor:3
|
||||
Replication factor: 3
|
||||
<br />
|
||||
Region: East China 1<br />
|
||||
</Descriptions.Item>
|
||||
|
||||
@@ -39,7 +39,7 @@ const Demo = () => {
|
||||
<br />
|
||||
Storage space: 10 GB
|
||||
<br />
|
||||
Replication_factor:3
|
||||
Replication factor: 3
|
||||
<br />
|
||||
Region: East China 1
|
||||
</Descriptions.Item>
|
||||
|
||||
@@ -54,7 +54,7 @@ class Demo extends React.Component {
|
||||
<br />
|
||||
Storage space: 10 GB
|
||||
<br />
|
||||
Replication_factor:3
|
||||
Replication factor: 3
|
||||
<br />
|
||||
Region: East China 1<br />
|
||||
</Descriptions.Item>
|
||||
|
||||
@@ -40,7 +40,7 @@ ReactDOM.render(
|
||||
<br />
|
||||
Storage space: 10 GB
|
||||
<br />
|
||||
Replication_factor:3
|
||||
Replication factor: 3
|
||||
<br />
|
||||
Region: East China 1<br />
|
||||
</Descriptions.Item>
|
||||
|
||||
@@ -10,6 +10,20 @@ import ResponsiveObserve, {
|
||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||
import Col from './Col';
|
||||
|
||||
// https://github.com/smooth-code/react-flatten-children/
|
||||
function flattenChildren(children: React.ReactNode): JSX.Element[] {
|
||||
if (!children) {
|
||||
return [];
|
||||
}
|
||||
return toArray(children).reduce((flatChildren: JSX.Element[], child: JSX.Element) => {
|
||||
if (child && child.type === React.Fragment) {
|
||||
return flatChildren.concat(flattenChildren(child.props.children));
|
||||
}
|
||||
flatChildren.push(child);
|
||||
return flatChildren;
|
||||
}, []);
|
||||
}
|
||||
|
||||
export interface DescriptionsItemProps {
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
@@ -47,7 +61,7 @@ const generateChildrenRows = (
|
||||
let columns: React.ReactElement<DescriptionsItemProps>[] | null = null;
|
||||
let leftSpans: number;
|
||||
|
||||
const itemNodes = toArray(children);
|
||||
const itemNodes = flattenChildren(children);
|
||||
itemNodes.forEach((node: React.ReactElement<DescriptionsItemProps>, index: number) => {
|
||||
let itemNode = node;
|
||||
|
||||
@@ -113,7 +127,7 @@ const renderRow = (
|
||||
|
||||
const cloneChildren: JSX.Element[] = [];
|
||||
const cloneContentChildren: JSX.Element[] = [];
|
||||
toArray(children).forEach(
|
||||
flattenChildren(children).forEach(
|
||||
(childrenItem: React.ReactElement<DescriptionsItemProps>, idx: number) => {
|
||||
cloneChildren.push(renderCol(childrenItem, 'label', idx));
|
||||
if (layout === 'vertical') {
|
||||
@@ -225,7 +239,7 @@ class Descriptions extends React.Component<
|
||||
const prefixCls = getPrefixCls('descriptions', customizePrefixCls);
|
||||
|
||||
const column = this.getColumn();
|
||||
const cloneChildren = toArray(children)
|
||||
const cloneChildren = flattenChildren(children)
|
||||
.map((child: React.ReactElement<DescriptionsItemProps>) => {
|
||||
if (React.isValidElement(child)) {
|
||||
return React.cloneElement(child, {
|
||||
@@ -236,9 +250,9 @@ class Descriptions extends React.Component<
|
||||
})
|
||||
.filter((node: React.ReactElement) => node);
|
||||
|
||||
const childrenArray: Array<
|
||||
React.ReactElement<DescriptionsItemProps>[]
|
||||
> = generateChildrenRows(cloneChildren, column);
|
||||
const childrenArray: Array<React.ReactElement<
|
||||
DescriptionsItemProps
|
||||
>[]> = generateChildrenRows(cloneChildren, column);
|
||||
return (
|
||||
<div
|
||||
className={classNames(prefixCls, className, {
|
||||
|
||||
@@ -20,7 +20,7 @@ exports[`Drawer className is test_drawer 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-wrapper-body"
|
||||
style="overflow:auto;height:100%;opacity:0;transition:opacity .3s"
|
||||
style="opacity:0;transition:opacity .3s"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-header-no-title"
|
||||
@@ -82,7 +82,6 @@ exports[`Drawer closable is false 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-wrapper-body"
|
||||
style="overflow:auto;height:100%"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-body"
|
||||
@@ -116,7 +115,7 @@ exports[`Drawer destroyOnClose is true 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-wrapper-body"
|
||||
style="overflow:auto;height:100%;opacity:0;transition:opacity .3s"
|
||||
style="opacity:0;transition:opacity .3s"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-header-no-title"
|
||||
@@ -178,7 +177,6 @@ exports[`Drawer have a title 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-wrapper-body"
|
||||
style="overflow:auto;height:100%"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-header"
|
||||
@@ -245,7 +243,6 @@ exports[`Drawer render correctly 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-wrapper-body"
|
||||
style="overflow:auto;height:100%"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-header-no-title"
|
||||
@@ -369,7 +366,7 @@ exports[`Drawer style/drawerStyle/headerStyle/bodyStyle should work 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-wrapper-body"
|
||||
style="overflow:auto;height:100%;background-color:#08c"
|
||||
style="background-color:#08c"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-header-no-title"
|
||||
|
||||
@@ -29,7 +29,6 @@ exports[`Drawer render correctly 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-wrapper-body"
|
||||
style="overflow: auto; height: 100%;"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-header-no-title"
|
||||
|
||||
@@ -193,7 +193,6 @@ exports[`renders ./components/drawer/demo/render-in-current.md correctly 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-wrapper-body"
|
||||
style="overflow:auto;height:100%"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-header"
|
||||
@@ -265,7 +264,7 @@ exports[`renders ./components/drawer/demo/user-profile.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-list-item-meta-description"
|
||||
>
|
||||
Progresser AFX
|
||||
Progresser XTech
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -311,7 +310,7 @@ exports[`renders ./components/drawer/demo/user-profile.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-list-item-meta-description"
|
||||
>
|
||||
Progresser AFX
|
||||
Progresser XTech
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -45,6 +45,7 @@ class DrawerForm extends React.Component {
|
||||
width={720}
|
||||
onClose={this.onClose}
|
||||
visible={this.state.visible}
|
||||
bodyStyle={{ paddingBottom: 80 }}
|
||||
>
|
||||
<Form layout="vertical" hideRequiredMark>
|
||||
<Row gutter={16}>
|
||||
@@ -140,7 +141,7 @@ class DrawerForm extends React.Component {
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
width: '100%',
|
||||
borderTop: '1px solid #e9e9e9',
|
||||
|
||||
@@ -88,7 +88,7 @@ class App extends React.Component {
|
||||
<Avatar src="https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png" />
|
||||
}
|
||||
title={<a href="https://ant.design/index-cn">{item.name}</a>}
|
||||
description="Progresser AFX"
|
||||
description="Progresser XTech"
|
||||
/>
|
||||
</List.Item>
|
||||
)}
|
||||
@@ -146,7 +146,7 @@ class App extends React.Component {
|
||||
</Row>
|
||||
<Row>
|
||||
<Col span={12}>
|
||||
<DescriptionItem title="Department" content="AFX" />
|
||||
<DescriptionItem title="Department" content="XTech" />
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<DescriptionItem title="Supervisor" content={<a>Lin</a>} />
|
||||
|
||||
@@ -18,7 +18,7 @@ type EventType =
|
||||
type getContainerFunc = () => HTMLElement;
|
||||
|
||||
const PlacementTypes = tuple('top', 'right', 'bottom', 'left');
|
||||
type placementType = (typeof PlacementTypes)[number];
|
||||
type placementType = typeof PlacementTypes[number];
|
||||
export interface DrawerProps {
|
||||
closable?: boolean;
|
||||
destroyOnClose?: boolean;
|
||||
@@ -174,19 +174,13 @@ class Drawer extends React.Component<DrawerProps & ConfigConsumerProps, IDrawerS
|
||||
|
||||
// render drawer body dom
|
||||
renderBody = () => {
|
||||
const { bodyStyle, drawerStyle, placement, prefixCls, visible } = this.props;
|
||||
const { bodyStyle, drawerStyle, prefixCls, visible } = this.props;
|
||||
if (this.destroyClose && !visible) {
|
||||
return null;
|
||||
}
|
||||
this.destroyClose = false;
|
||||
|
||||
const containerStyle: React.CSSProperties =
|
||||
placement === 'left' || placement === 'right'
|
||||
? {
|
||||
overflow: 'auto',
|
||||
height: '100%',
|
||||
}
|
||||
: {};
|
||||
const containerStyle: React.CSSProperties = {};
|
||||
|
||||
const isDestroyOnClose = this.getDestroyOnClose();
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ title: Drawer
|
||||
| destroyOnClose | 关闭时销毁 Drawer 里的子元素 | boolean | false | 3.7.0 |
|
||||
| getContainer | 指定 Drawer 挂载的 HTML 节点, false 为挂载在当前 dom | HTMLElement \| `() => HTMLElement` \| Selectors \| false | 'body' | 3.7.0 |
|
||||
| maskClosable | 点击蒙层是否允许关闭 | boolean | true | 3.7.0 |
|
||||
| mask | 是否展示遮罩 | Boolean | true | 3.7.0 |
|
||||
| mask | 是否展示遮罩 | boolean | true | 3.7.0 |
|
||||
| maskStyle | 遮罩样式 | object | {} | 3.7.0 |
|
||||
| style | 可用于设置 Drawer 最外层容器的样式,和 `drawerStyle` 的区别是作用节点包括 `mask` | object | - | 3.7.0 |
|
||||
| drawerStyle | 用于设置 Drawer 弹出层的样式 | object | - | 3.24.0 |
|
||||
@@ -33,7 +33,7 @@ title: Drawer
|
||||
| width | 宽度 | string \| number | 256 | 3.7.0 |
|
||||
| height | 高度, 在 `placement` 为 `top` 或 `bottom` 时使用 | string \| number | 256 | 3.9.0 |
|
||||
| className | 对话框外层容器的类名 | string | - | 3.8.0 |
|
||||
| zIndex | 设置 Drawer 的 `z-index` | Number | 1000 | 3.7.0 |
|
||||
| zIndex | 设置 Drawer 的 `z-index` | number | 1000 | 3.7.0 |
|
||||
| placement | 抽屉的方向 | 'top' \| 'right' \| 'bottom' \| 'left' | 'right' | 3.7.0 |
|
||||
| onClose | 点击遮罩层或右上角叉或取消按钮的回调 | function(e) | 无 | 3.7.0 |
|
||||
| afterVisibleChange | 切换抽屉时动画结束后的回调 | function(visible) | 无 | 3.17.0 |
|
||||
|
||||
@@ -140,6 +140,7 @@
|
||||
&-content {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
overflow: auto;
|
||||
background-color: @component-background;
|
||||
background-clip: padding-box;
|
||||
border: 0;
|
||||
@@ -196,6 +197,10 @@
|
||||
line-height: @line-height-base;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
&-wrapper-body {
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
&-mask {
|
||||
position: absolute;
|
||||
|
||||
@@ -29,12 +29,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`] = `
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
|
||||
@@ -8,11 +8,15 @@ debug: true
|
||||
|
||||
## zh-CN
|
||||
|
||||
此演示需要注意查看 Dropdown 内 Menu 的样式是否正常。[#19150](https://github.com/ant-design/ant-design/pull/19150)
|
||||
此演示需要注意去掉 Reset 样式后查看 Dropdown 内 Menu 的样式是否正常。
|
||||
|
||||
[#19150](https://github.com/ant-design/ant-design/pull/19150)
|
||||
|
||||
## en-US
|
||||
|
||||
This demo was created for debugging Menu styles inside Dropdown. [#19150](https://github.com/ant-design/ant-design/pull/19150)
|
||||
This demo was created for debugging Menu styles inside Dropdown.
|
||||
|
||||
[#19150](https://github.com/ant-design/ant-design/pull/19150)
|
||||
|
||||
```jsx
|
||||
import { Menu, Dropdown, Icon } from 'antd';
|
||||
@@ -21,6 +25,10 @@ const { SubMenu } = Menu;
|
||||
|
||||
const menu = (
|
||||
<Menu selectedKeys={['1']} openKeys={['sub1']}>
|
||||
<Menu.ItemGroup key="group" title="Item Group">
|
||||
<Menu.Item key="01">Option 0</Menu.Item>
|
||||
<Menu.Item key="02">Option 0</Menu.Item>
|
||||
</Menu.ItemGroup>
|
||||
<SubMenu
|
||||
key="sub1"
|
||||
title={
|
||||
|
||||
@@ -8,7 +8,7 @@ A dropdown list.
|
||||
|
||||
## When To Use
|
||||
|
||||
If there are too many operations to display, you can wrap them in a `Dropdown`. By clicking/hovering on the trigger, a dropdown menu should appear, which allows you to choose one option and execute relevant actions.
|
||||
When there are more than a few options to choose from, you can wrap them in a `Dropdown`. By hovering or clicking on the trigger, a dropdown menu will appear, which allows you to choose an option and execute the relevant action.
|
||||
|
||||
## API
|
||||
|
||||
@@ -16,15 +16,15 @@ If there are too many operations to display, you can wrap them in a `Dropdown`.
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| disabled | whether the dropdown menu is disabled | boolean | - | |
|
||||
| getPopupContainer | to set the container of the dropdown menu. The default is to create a `div` element in `body`, you can reset it to the scrolling area and make a relative reposition. [example](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | Function(triggerNode) | `() => document.body` | |
|
||||
| overlay | the dropdown menu | [Menu](/components/menu) \| () => Menu | - | |
|
||||
| disabled | Whether the dropdown menu is disabled | boolean | - | |
|
||||
| getPopupContainer | To set the container of the dropdown menu. The default is to create a `div` element in `body`, but you can reset it to the scrolling area and make a relative reposition. [Example on CodePen](https://codepen.io/afc163/pen/zEjNOy?editors=0010). | Function(triggerNode) | `() => document.body` | |
|
||||
| overlay | The dropdown menu | [Menu](/components/menu) \| () => Menu | - | |
|
||||
| overlayClassName | Class name of the dropdown root element | string | - | 3.11.0 |
|
||||
| overlayStyle | Style of the dropdown root element | object | - | 3.11.0 |
|
||||
| placement | placement of pop menu: `bottomLeft` `bottomCenter` `bottomRight` `topLeft` `topCenter` `topRight` | String | `bottomLeft` | |
|
||||
| trigger | the trigger mode which executes the drop-down action, hover doesn't work on mobile device | Array<`click`\|`hover`\|`contextMenu`> | `['hover']` | |
|
||||
| visible | whether the dropdown menu is visible | boolean | - | |
|
||||
| onVisibleChange | a callback function takes an argument: `visible`, is executed when the visible state is changed | Function(visible) | - | |
|
||||
| placement | Placement of popup menu: `bottomLeft`, `bottomCenter`, `bottomRight`, `topLeft`, `topCenter` or `topRight` | String | `bottomLeft` | |
|
||||
| trigger | The trigger mode which executes the dropdown action. Note that hover can't be used on touchscreens. | Array<`click`\|`hover`\|`contextMenu`> | `['hover']` | |
|
||||
| visible | Whether the dropdown menu is currently visible | boolean | - | |
|
||||
| onVisibleChange | Called when the visible state is changed. | Function(visible) | - | |
|
||||
|
||||
You should use [Menu](/components/menu/) as `overlay`. The menu items and dividers are also available by using `Menu.Item` and `Menu.Divider`.
|
||||
|
||||
@@ -36,13 +36,13 @@ You should use [Menu](/components/menu/) as `overlay`. The menu items and divide
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| disabled | whether the dropdown menu is disabled | boolean | - | |
|
||||
| icon | icon of right | ReactNode | - | 3.17.0 |
|
||||
| overlay | the dropdown menu | [Menu](/components/menu) | - | |
|
||||
| placement | placement of pop menu: `bottomLeft` `bottomCenter` `bottomRight` `topLeft` `topCenter` `topRight` | String | `bottomLeft` | |
|
||||
| size | size of the button, the same as [Button](/components/button) | string | `default` | |
|
||||
| trigger | the trigger mode which executes the drop-down action | Array<`click`\|`hover`\|`contextMenu`> | `['hover']` | |
|
||||
| type | type of the button, the same as [Button](/components/button) | string | `default` | |
|
||||
| visible | whether the dropdown menu is visible | boolean | - | |
|
||||
| onClick | a callback function, the same as [Button](/components/button), which will be executed when you click the button on the left | Function | - | |
|
||||
| onVisibleChange | a callback function takes an argument: `visible`, is executed when the visible state is changed | Function | - | |
|
||||
| disabled | Whether the dropdown menu is disabled | boolean | - | |
|
||||
| icon | Icon (appears on the right) | ReactNode | - | 3.17.0 |
|
||||
| overlay | The dropdown menu | [Menu](/components/menu) | - | |
|
||||
| placement | Placement of popup menu: `bottomLeft` `bottomCenter` `bottomRight` `topLeft` `topCenter` `topRight` | String | `bottomLeft` | |
|
||||
| size | Size of the button, the same as [Button](/components/button) | string | `default` | |
|
||||
| trigger | The trigger mode which executes the dropdown action | Array<`click`\|`hover`\|`contextMenu`> | `['hover']` | |
|
||||
| type | Type of the button, the same as [Button](/components/button) | string | `default` | |
|
||||
| visible | Whether the dropdown menu is currently visible | boolean | - | |
|
||||
| onClick | The same as [Button](/components/button): called when you click the button on the left | Function | - | |
|
||||
| onVisibleChange | Called when the visible state is changed | Function | - | |
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
ul {
|
||||
margin-right: 0.3em;
|
||||
margin-left: 0.3em;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +98,7 @@
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
> .anticon:first-child,
|
||||
> span > .anticon:first-child {
|
||||
min-width: 12px;
|
||||
margin-right: 8px;
|
||||
@@ -139,6 +141,7 @@
|
||||
line-height: 0;
|
||||
background-color: @border-color-split;
|
||||
}
|
||||
|
||||
.@{dropdown-prefix-cls}-menu-submenu-arrow {
|
||||
position: absolute;
|
||||
right: @padding-xs;
|
||||
@@ -150,6 +153,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
&-item-group-list {
|
||||
margin: 0 8px;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
&-submenu-title {
|
||||
padding-right: 26px;
|
||||
}
|
||||
|
||||
@@ -513,7 +513,7 @@ exports[`renders ./components/empty/demo/config-provider.md correctly 1`] = `
|
||||
</span>
|
||||
</th>
|
||||
<th
|
||||
class=""
|
||||
class="ant-table-row-cell-last"
|
||||
>
|
||||
<span
|
||||
class="ant-table-header-column"
|
||||
|
||||
@@ -3,6 +3,7 @@ import * as ReactDOM from 'react-dom';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import Animate from 'rc-animate';
|
||||
import omit from 'omit.js';
|
||||
import Row from '../grid/row';
|
||||
import Col, { ColProps } from '../grid/col';
|
||||
import Icon from '../icon';
|
||||
@@ -14,7 +15,9 @@ import FormContext, { FormContextProps } from './context';
|
||||
|
||||
const ValidateStatuses = tuple('success', 'warning', 'error', 'validating', '');
|
||||
|
||||
export type FormLabelAlign = 'left' | 'right';
|
||||
const FormLabelAligns = tuple('left', 'right');
|
||||
|
||||
export type FormLabelAlign = typeof FormLabelAligns[number];
|
||||
|
||||
export interface FormItemProps {
|
||||
prefixCls?: string;
|
||||
@@ -27,7 +30,7 @@ export interface FormItemProps {
|
||||
wrapperCol?: ColProps;
|
||||
help?: React.ReactNode;
|
||||
extra?: React.ReactNode;
|
||||
validateStatus?: (typeof ValidateStatuses)[number];
|
||||
validateStatus?: typeof ValidateStatuses[number];
|
||||
hasFeedback?: boolean;
|
||||
required?: boolean;
|
||||
style?: React.CSSProperties;
|
||||
@@ -46,7 +49,6 @@ export default class FormItem extends React.Component<FormItemProps, any> {
|
||||
static propTypes = {
|
||||
prefixCls: PropTypes.string,
|
||||
label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
||||
labelAlign: PropTypes.string,
|
||||
labelCol: PropTypes.object,
|
||||
help: PropTypes.oneOfType([PropTypes.node, PropTypes.bool]),
|
||||
validateStatus: PropTypes.oneOf(ValidateStatuses),
|
||||
@@ -64,7 +66,8 @@ export default class FormItem extends React.Component<FormItemProps, any> {
|
||||
const { children, help, validateStatus, id } = this.props;
|
||||
warning(
|
||||
this.getControls(children, true).length <= 1 ||
|
||||
(help !== undefined || validateStatus !== undefined),
|
||||
help !== undefined ||
|
||||
validateStatus !== undefined,
|
||||
'Form.Item',
|
||||
'Cannot generate `validateStatus` and `help` automatically, ' +
|
||||
'while there are more than one `getFieldDecorator` in it.',
|
||||
@@ -399,7 +402,7 @@ export default class FormItem extends React.Component<FormItemProps, any> {
|
||||
}
|
||||
|
||||
renderFormItem = ({ getPrefixCls }: ConfigConsumerProps) => {
|
||||
const { prefixCls: customizePrefixCls, style, className } = this.props;
|
||||
const { prefixCls: customizePrefixCls, style, className, ...restProps } = this.props;
|
||||
const prefixCls = getPrefixCls('form', customizePrefixCls);
|
||||
const children = this.renderChildren(prefixCls);
|
||||
const itemClassName = {
|
||||
@@ -409,7 +412,25 @@ export default class FormItem extends React.Component<FormItemProps, any> {
|
||||
};
|
||||
|
||||
return (
|
||||
<Row className={classNames(itemClassName)} style={style} key="row">
|
||||
<Row
|
||||
className={classNames(itemClassName)}
|
||||
style={style}
|
||||
{...omit(restProps, [
|
||||
'id', // It is deprecated because `htmlFor` is its replacement.
|
||||
'htmlFor',
|
||||
'label',
|
||||
'labelAlign',
|
||||
'labelCol',
|
||||
'wrapperCol',
|
||||
'help',
|
||||
'extra',
|
||||
'validateStatus',
|
||||
'hasFeedback',
|
||||
'required',
|
||||
'colon',
|
||||
])}
|
||||
key="row"
|
||||
>
|
||||
{children}
|
||||
</Row>
|
||||
);
|
||||
|
||||
@@ -4151,9 +4151,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-form-item-children"
|
||||
>
|
||||
<span
|
||||
class=""
|
||||
>
|
||||
<span>
|
||||
<div
|
||||
class="ant-upload ant-upload-drag"
|
||||
/>
|
||||
|
||||
28
components/form/__tests__/__snapshots__/index.test.js.snap
Normal file
28
components/form/__tests__/__snapshots__/index.test.js.snap
Normal file
@@ -0,0 +1,28 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Form Form.Item should support data-*、aria-* and custom attribute 1`] = `
|
||||
<form
|
||||
class="ant-form ant-form-horizontal"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
cccc="bbbb"
|
||||
class="ant-row ant-form-item"
|
||||
data-text="123"
|
||||
>
|
||||
<div
|
||||
class="ant-col ant-form-item-control-wrapper"
|
||||
>
|
||||
<div
|
||||
class="ant-form-item-control"
|
||||
>
|
||||
<span
|
||||
class="ant-form-item-children"
|
||||
>
|
||||
text
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
`;
|
||||
@@ -1,8 +1,9 @@
|
||||
/* eslint-disable react/prefer-stateless-function */
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import { mount, render } from 'enzyme';
|
||||
import Form from '..';
|
||||
import mountTest from '../../../tests/shared/mountTest';
|
||||
import './type.test';
|
||||
|
||||
describe('Form', () => {
|
||||
mountTest(Form);
|
||||
@@ -13,6 +14,17 @@ describe('Form', () => {
|
||||
expect(wrapper.find('form').hasClass('ant-form-hide-required-mark')).toBe(true);
|
||||
});
|
||||
|
||||
it('Form.Item should support data-*、aria-* and custom attribute', () => {
|
||||
const wrapper = render(
|
||||
<Form>
|
||||
<Form.Item data-text="123" aria-hidden="true" cccc="bbbb">
|
||||
text
|
||||
</Form.Item>
|
||||
</Form>,
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
describe('wrappedComponentRef', () => {
|
||||
it('warns on functional component', () => {
|
||||
if (process.env.REACT === '15') {
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
/* 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 = {
|
||||
@@ -38,7 +38,7 @@ A form consists of one or more form fields whose type includes input, textarea,
|
||||
| --- | --- | --- | --- | --- |
|
||||
| form | Decorated by `Form.create()` will be automatically set `this.props.form` property | object | n/a | |
|
||||
| hideRequiredMark | Hide required mark of all form items | Boolean | false | |
|
||||
| labelAlign | Label text align | 'left' \| 'right' | 'right' | 3.15.0 |
|
||||
| labelAlign | text align of label of all items | 'left' \| 'right' | 'right' | 3.15.0 |
|
||||
| labelCol | (Added in 3.14.0. Previous version can only set on FormItem.) The layout of label. You can set `span` `offset` to something like `{span: 3, offset: 12}` or `sm: {span: 3, offset: 12}` same as with `<Col>` | [object](https://ant.design/components/grid/#Col) | | 3.14.0 |
|
||||
| layout | Define form layout | 'horizontal'\|'vertical'\|'inline' | 'horizontal' | |
|
||||
| onSubmit | Defines a function will be called if form data validation is successful. | Function(e:Event) | | |
|
||||
@@ -47,7 +47,7 @@ A form consists of one or more form fields whose type includes input, textarea,
|
||||
|
||||
### Form.create(options)
|
||||
|
||||
How to use:
|
||||
How to use:
|
||||
|
||||
```jsx
|
||||
class CustomizedForm extends React.Component {}
|
||||
@@ -201,6 +201,7 @@ Note: if Form.Item has multiple children that had been decorated by `getFieldDec
|
||||
| htmlFor | Set sub label `htmlFor`. | string | | 3.17.0 |
|
||||
| label | Label text | string\|ReactNode | | |
|
||||
| labelCol | The layout of label. You can set `span` `offset` to something like `{span: 3, offset: 12}` or `sm: {span: 3, offset: 12}` same as with `<Col>`. You can set on Form one time after 3.14.0. Will take FormItem's prop when both set with Form. | [object](https://ant.design/components/grid/#Col) | | |
|
||||
| labelAlign | text align of label | 'left' \| 'right' | 'right' | 3.15.0 |
|
||||
| required | Whether provided or not, it will be generated by the validation rule. | boolean | false | |
|
||||
| validateStatus | The validation status. If not provided, it will be generated by validation rule. options: 'success' 'warning' 'error' 'validating' | string | | |
|
||||
| wrapperCol | The layout for input controls, same as `labelCol`. You can set on Form one time after 3.14.0. Will take FormItem's prop when both set with Form. | [object](https://ant.design/components/grid/#Col) | | |
|
||||
@@ -274,3 +275,38 @@ validator(rule, value, callback) => {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Get form instance from function component
|
||||
|
||||
You can combine `forwardRef` with `useImperativeHandle` to get form instance:
|
||||
|
||||
```tsx
|
||||
import React, { forwardRef, useImperativeHandle } from 'react';
|
||||
import Form, { FormComponentProps } from 'antd/lib/form/Form';
|
||||
|
||||
const FCForm = forwardRef<FormComponentProps, FCFormProps>(({ form, onSubmit }, ref) => {
|
||||
useImperativeHandle(ref, () => ({
|
||||
form,
|
||||
}));
|
||||
`...the rest of your form`;
|
||||
});
|
||||
const EnhancedFCForm = Form.create<FCFormProps>()(FCForm);
|
||||
```
|
||||
|
||||
You can use your form component like this:
|
||||
|
||||
```tsx
|
||||
const TestForm = () => {
|
||||
const formRef = createRef<Ref>();
|
||||
return (
|
||||
<EnhancedFCForm
|
||||
onSubmit={() => console.log(formRef.current!.form.getFieldValue('name'))}
|
||||
wrappedComponentRef={formRef}
|
||||
/>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
Online demo:
|
||||
|
||||
[](https://codesandbox.io/s/wrappedcomponentref-in-function-component-fj43c?fontsize=14&hidenavigation=1&theme=dark)
|
||||
|
||||
@@ -203,6 +203,7 @@ validateFields(['field1', 'field2'], options, (errors, values) => {
|
||||
| htmlFor | 设置子元素 label `htmlFor` 属性 | string | | 3.17.0 |
|
||||
| label | label 标签的文本 | string\|ReactNode | | |
|
||||
| labelCol | label 标签布局,同 `<Col>` 组件,设置 `span` `offset` 值,如 `{span: 3, offset: 12}` 或 `sm: {span: 3, offset: 12}`。在 3.14.0 之后,你可以通过 Form 的 labelCol 进行统一设置。当和 Form 同时设置时,以 FormItem 为准。 | [object](https://ant.design/components/grid/#Col) | | |
|
||||
| labelAlign | 标签文本对齐方式 | 'left' \| 'right' | 'right' | 3.15.0 |
|
||||
| required | 是否必填,如不设置,则会根据校验规则自动生成 | boolean | false | |
|
||||
| validateStatus | 校验状态,如不设置,则会根据校验规则自动生成,可选:'success' 'warning' 'error' 'validating' | string | | |
|
||||
| wrapperCol | 需要为输入控件设置布局样式时,使用该属性,用法同 labelCol。在 3.14.0 之后,你可以通过 Form 的 wrapperCol 进行统一设置。当和 Form 同时设置时,以 FormItem 为准。 | [object](https://ant.design/components/grid/#Col) | | |
|
||||
@@ -276,3 +277,38 @@ validator(rule, value, callback) => {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 如何在函数组件中拿到 form 实例?
|
||||
|
||||
你需要通过 `forwardRef` 和 `useImperativeHandle` 的组合使用来实现在函数组件中正确拿到 form 实例:
|
||||
|
||||
```tsx
|
||||
import React, { forwardRef, useImperativeHandle } from 'react';
|
||||
import Form, { FormComponentProps } from 'antd/lib/form/Form';
|
||||
|
||||
const FCForm = forwardRef<FormComponentProps, FCFormProps>(({ form, onSubmit }, ref) => {
|
||||
useImperativeHandle(ref, () => ({
|
||||
form,
|
||||
}));
|
||||
`...the rest of your form`;
|
||||
});
|
||||
const EnhancedFCForm = Form.create<FCFormProps>()(FCForm);
|
||||
```
|
||||
|
||||
使用表单组件可以写成这样:
|
||||
|
||||
```tsx
|
||||
const TestForm = () => {
|
||||
const formRef = createRef<Ref>();
|
||||
return (
|
||||
<EnhancedFCForm
|
||||
onSubmit={() => console.log(formRef.current!.form.getFieldValue('name'))}
|
||||
wrappedComponentRef={formRef}
|
||||
/>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
在线示例:
|
||||
|
||||
[](https://codesandbox.io/s/wrappedcomponentref-in-function-component-fj43c?fontsize=14&hidenavigation=1&theme=dark)
|
||||
|
||||
@@ -140,6 +140,11 @@ form {
|
||||
padding-right: 24px;
|
||||
}
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/19884
|
||||
.@{ant-prefix}-input-affix-wrapper .@{ant-prefix}-input-suffix {
|
||||
padding-right: 18px;
|
||||
}
|
||||
|
||||
.@{ant-prefix}-input-password-icon {
|
||||
margin-right: 18px;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ export default function create(options: CustomIconOptions = {}): React.SFC<IconP
|
||||
content = children;
|
||||
}
|
||||
return (
|
||||
<Icon {...restProps} {...extraCommonProps}>
|
||||
<Icon {...extraCommonProps} {...restProps}>
|
||||
{content}
|
||||
</Icon>
|
||||
);
|
||||
|
||||
@@ -370,12 +370,12 @@ exports[`Icon support render svg as component 1`] = `
|
||||
</i>
|
||||
`;
|
||||
|
||||
exports[`Icon.createFromIconfontCN() should support iconfont.cn 1`] = `
|
||||
exports[`Icon.createFromIconfontCN() extraCommonProps should works fine and can be overwritten 1`] = `
|
||||
<div
|
||||
class="icons-list"
|
||||
>
|
||||
<i
|
||||
class="anticon"
|
||||
class="anticon bcd"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@@ -391,7 +391,7 @@ exports[`Icon.createFromIconfontCN() should support iconfont.cn 1`] = `
|
||||
</svg>
|
||||
</i>
|
||||
<i
|
||||
class="anticon"
|
||||
class="anticon abc"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
@@ -407,7 +407,62 @@ exports[`Icon.createFromIconfontCN() should support iconfont.cn 1`] = `
|
||||
</svg>
|
||||
</i>
|
||||
<i
|
||||
class="anticon"
|
||||
class="anticon efg"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
width="1em"
|
||||
>
|
||||
<use
|
||||
href="#icon-twitter"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Icon.createFromIconfontCN() should support iconfont.cn 1`] = `
|
||||
<div
|
||||
class="icons-list"
|
||||
>
|
||||
<i
|
||||
class="anticon abc"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
width="1em"
|
||||
>
|
||||
<use
|
||||
href="#icon-tuichu"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
<i
|
||||
class="anticon abc"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
width="1em"
|
||||
>
|
||||
<use
|
||||
href="#icon-facebook"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
<i
|
||||
class="anticon abc"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
|
||||
@@ -180,6 +180,9 @@ describe('Icon', () => {
|
||||
describe('Icon.createFromIconfontCN()', () => {
|
||||
const IconFont = Icon.createFromIconfontCN({
|
||||
scriptUrl: '//at.alicdn.com/t/font_8d5l8fzk5b87iudi.js',
|
||||
extraCommonProps: {
|
||||
className: 'abc',
|
||||
},
|
||||
});
|
||||
|
||||
it('should support iconfont.cn', () => {
|
||||
@@ -192,6 +195,17 @@ describe('Icon.createFromIconfontCN()', () => {
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('extraCommonProps should works fine and can be overwritten', () => {
|
||||
const wrapper = render(
|
||||
<div className="icons-list">
|
||||
<IconFont type="icon-tuichu" className="bcd" />
|
||||
<IconFont type="icon-facebook" />
|
||||
<IconFont type="icon-twitter" className="efg" />
|
||||
</div>,
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('utils', () => {
|
||||
|
||||
0
components/icon/__tests__/logo.svg
Normal file
0
components/icon/__tests__/logo.svg
Normal file
12
components/icon/__tests__/type.test.tsx
Normal file
12
components/icon/__tests__/type.test.tsx
Normal 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} />;
|
||||
@@ -67,7 +67,7 @@ export interface IconProps {
|
||||
title?: string;
|
||||
onKeyUp?: React.KeyboardEventHandler<HTMLElement>;
|
||||
onClick?: React.MouseEventHandler<HTMLElement>;
|
||||
component?: React.ComponentType<CustomIconComponentProps>;
|
||||
component?: React.ComponentType<CustomIconComponentProps | React.SVGProps<SVGSVGElement>>;
|
||||
twoToneColor?: string;
|
||||
viewBox?: string;
|
||||
spin?: boolean;
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.hover();
|
||||
.hover(@input-number-hover-border-color);
|
||||
}
|
||||
|
||||
&-focused {
|
||||
|
||||
181
components/input/ClearableLabeledInput.tsx
Normal file
181
components/input/ClearableLabeledInput.tsx
Normal file
@@ -0,0 +1,181 @@
|
||||
import * as React from 'react';
|
||||
import { polyfill } from 'react-lifecycles-compat';
|
||||
import classNames from 'classnames';
|
||||
import Icon from '../icon';
|
||||
import { tuple } from '../_util/type';
|
||||
import { InputProps, InputSizes, getInputClassName } from './Input';
|
||||
|
||||
const ClearableInputType = tuple('text', 'input');
|
||||
|
||||
export function hasPrefixSuffix(props: InputProps | ClearableInputProps) {
|
||||
return !!(props.prefix || props.suffix || props.allowClear);
|
||||
}
|
||||
|
||||
/**
|
||||
* This basic props required for input and textarea.
|
||||
*/
|
||||
interface BasicProps {
|
||||
prefixCls: string;
|
||||
inputType: (typeof ClearableInputType)[number];
|
||||
value?: any;
|
||||
defaultValue?: any;
|
||||
allowClear?: boolean;
|
||||
element: React.ReactElement<any>;
|
||||
handleReset: (event: React.MouseEvent<HTMLElement, MouseEvent>) => void;
|
||||
className?: string;
|
||||
style?: object;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* This props only for input.
|
||||
*/
|
||||
interface ClearableInputProps extends BasicProps {
|
||||
size?: (typeof InputSizes)[number];
|
||||
suffix?: React.ReactNode;
|
||||
prefix?: React.ReactNode;
|
||||
addonBefore?: React.ReactNode;
|
||||
addonAfter?: React.ReactNode;
|
||||
}
|
||||
|
||||
class ClearableLabeledInput extends React.Component<ClearableInputProps> {
|
||||
renderClearIcon(prefixCls: string) {
|
||||
const { allowClear, value, disabled, inputType, handleReset } = this.props;
|
||||
if (!allowClear || disabled || value === undefined || value === null || value === '') {
|
||||
return null;
|
||||
}
|
||||
const className =
|
||||
inputType === ClearableInputType[0]
|
||||
? `${prefixCls}-textarea-clear-icon`
|
||||
: `${prefixCls}-clear-icon`;
|
||||
return (
|
||||
<Icon
|
||||
type="close-circle"
|
||||
theme="filled"
|
||||
onClick={handleReset}
|
||||
className={className}
|
||||
role="button"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
renderSuffix(prefixCls: string) {
|
||||
const { suffix, allowClear } = this.props;
|
||||
if (suffix || allowClear) {
|
||||
return (
|
||||
<span className={`${prefixCls}-suffix`}>
|
||||
{this.renderClearIcon(prefixCls)}
|
||||
{suffix}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
renderLabeledIcon(prefixCls: string, element: React.ReactElement<any>) {
|
||||
const props = this.props;
|
||||
const suffix = this.renderSuffix(prefixCls);
|
||||
if (!hasPrefixSuffix(props)) {
|
||||
return React.cloneElement(element, {
|
||||
value: props.value,
|
||||
});
|
||||
}
|
||||
|
||||
const prefix = props.prefix ? (
|
||||
<span className={`${prefixCls}-prefix`}>{props.prefix}</span>
|
||||
) : null;
|
||||
|
||||
const affixWrapperCls = classNames(props.className, `${prefixCls}-affix-wrapper`, {
|
||||
[`${prefixCls}-affix-wrapper-sm`]: props.size === 'small',
|
||||
[`${prefixCls}-affix-wrapper-lg`]: props.size === 'large',
|
||||
[`${prefixCls}-affix-wrapper-input-with-clear-btn`]:
|
||||
props.suffix && props.allowClear && this.props.value,
|
||||
});
|
||||
return (
|
||||
<span className={affixWrapperCls} style={props.style}>
|
||||
{prefix}
|
||||
{React.cloneElement(element, {
|
||||
style: null,
|
||||
value: props.value,
|
||||
className: getInputClassName(prefixCls, props.size, props.disabled),
|
||||
})}
|
||||
{suffix}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
renderInputWithLabel(prefixCls: string, labeledElement: React.ReactElement<any>) {
|
||||
const { addonBefore, addonAfter, style, size, className } = this.props;
|
||||
// Not wrap when there is not addons
|
||||
if (!addonBefore && !addonAfter) {
|
||||
return labeledElement;
|
||||
}
|
||||
|
||||
const wrapperClassName = `${prefixCls}-group`;
|
||||
const addonClassName = `${wrapperClassName}-addon`;
|
||||
const addonBeforeNode = addonBefore ? (
|
||||
<span className={addonClassName}>{addonBefore}</span>
|
||||
) : null;
|
||||
const addonAfterNode = addonAfter ? <span className={addonClassName}>{addonAfter}</span> : null;
|
||||
|
||||
const mergedWrapperClassName = classNames(`${prefixCls}-wrapper`, {
|
||||
[wrapperClassName]: addonBefore || addonAfter,
|
||||
});
|
||||
|
||||
const mergedGroupClassName = classNames(className, `${prefixCls}-group-wrapper`, {
|
||||
[`${prefixCls}-group-wrapper-sm`]: size === 'small',
|
||||
[`${prefixCls}-group-wrapper-lg`]: size === 'large',
|
||||
});
|
||||
|
||||
// Need another wrapper for changing display:table to display:inline-block
|
||||
// and put style prop in wrapper
|
||||
return (
|
||||
<span className={mergedGroupClassName} style={style}>
|
||||
<span className={mergedWrapperClassName}>
|
||||
{addonBeforeNode}
|
||||
{React.cloneElement(labeledElement, { style: null })}
|
||||
{addonAfterNode}
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
renderTextAreaWithClearIcon(prefixCls: string, element: React.ReactElement<any>) {
|
||||
const { value, allowClear, className, style } = this.props;
|
||||
if (!allowClear) {
|
||||
return React.cloneElement(element, {
|
||||
value,
|
||||
});
|
||||
}
|
||||
const affixWrapperCls = classNames(
|
||||
className,
|
||||
`${prefixCls}-affix-wrapper`,
|
||||
`${prefixCls}-affix-wrapper-textarea-with-clear-btn`,
|
||||
);
|
||||
return (
|
||||
<span className={affixWrapperCls} style={style}>
|
||||
{React.cloneElement(element, {
|
||||
style: null,
|
||||
value,
|
||||
})}
|
||||
{this.renderClearIcon(prefixCls)}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
renderClearableLabeledInput() {
|
||||
const { prefixCls, inputType, element } = this.props;
|
||||
if (inputType === ClearableInputType[0]) {
|
||||
return this.renderTextAreaWithClearIcon(prefixCls, element);
|
||||
}
|
||||
return this.renderInputWithLabel(prefixCls, this.renderLabeledIcon(prefixCls, element));
|
||||
}
|
||||
|
||||
render() {
|
||||
return this.renderClearableLabeledInput();
|
||||
}
|
||||
}
|
||||
|
||||
polyfill(ClearableLabeledInput);
|
||||
|
||||
export default ClearableLabeledInput;
|
||||
@@ -1,29 +1,18 @@
|
||||
import * as React from 'react';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import { polyfill } from 'react-lifecycles-compat';
|
||||
import classNames from 'classnames';
|
||||
import omit from 'omit.js';
|
||||
import { polyfill } from 'react-lifecycles-compat';
|
||||
import Group from './Group';
|
||||
import Search from './Search';
|
||||
import TextArea from './TextArea';
|
||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||
import Password from './Password';
|
||||
import Icon from '../icon';
|
||||
import { Omit, tuple } from '../_util/type';
|
||||
import ClearableLabeledInput, { hasPrefixSuffix } from './ClearableLabeledInput';
|
||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||
import warning from '../_util/warning';
|
||||
|
||||
function fixControlledValue<T>(value: T) {
|
||||
if (typeof value === 'undefined' || value === null) {
|
||||
return '';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function hasPrefixSuffix(props: InputProps) {
|
||||
return !!('prefix' in props || props.suffix || props.allowClear);
|
||||
}
|
||||
|
||||
const InputSizes = tuple('small', 'default', 'large');
|
||||
export const InputSizes = tuple('small', 'default', 'large');
|
||||
|
||||
export interface InputProps
|
||||
extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size' | 'prefix'> {
|
||||
@@ -37,7 +26,56 @@ export interface InputProps
|
||||
allowClear?: boolean;
|
||||
}
|
||||
|
||||
class Input extends React.Component<InputProps, any> {
|
||||
export function fixControlledValue<T>(value: T) {
|
||||
if (typeof value === 'undefined' || value === null) {
|
||||
return '';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
export function resolveOnChange(
|
||||
target: HTMLInputElement | HTMLTextAreaElement,
|
||||
e:
|
||||
| React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>
|
||||
| React.MouseEvent<HTMLElement, MouseEvent>,
|
||||
onChange?: (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void,
|
||||
) {
|
||||
if (onChange) {
|
||||
let event = e;
|
||||
if (e.type === 'click') {
|
||||
// click clear icon
|
||||
event = Object.create(e);
|
||||
event.target = target;
|
||||
event.currentTarget = target;
|
||||
const originalInputValue = target.value;
|
||||
// change target ref value cause e.target.value should be '' when clear input
|
||||
target.value = '';
|
||||
onChange(event as React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>);
|
||||
// reset target ref value
|
||||
target.value = originalInputValue;
|
||||
return;
|
||||
}
|
||||
onChange(event as React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>);
|
||||
}
|
||||
}
|
||||
|
||||
export function getInputClassName(
|
||||
prefixCls: string,
|
||||
size?: (typeof InputSizes)[number],
|
||||
disabled?: boolean,
|
||||
) {
|
||||
return classNames(prefixCls, {
|
||||
[`${prefixCls}-sm`]: size === 'small',
|
||||
[`${prefixCls}-lg`]: size === 'large',
|
||||
[`${prefixCls}-disabled`]: disabled,
|
||||
});
|
||||
}
|
||||
|
||||
export interface InputState {
|
||||
value: any;
|
||||
}
|
||||
|
||||
class Input extends React.Component<InputProps, InputState> {
|
||||
static Group: typeof Group;
|
||||
|
||||
static Search: typeof Search;
|
||||
@@ -72,17 +110,10 @@ class Input extends React.Component<InputProps, any> {
|
||||
allowClear: PropTypes.bool,
|
||||
};
|
||||
|
||||
static getDerivedStateFromProps(nextProps: InputProps) {
|
||||
if ('value' in nextProps) {
|
||||
return {
|
||||
value: nextProps.value,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
input: HTMLInputElement;
|
||||
|
||||
clearableInput: ClearableLabeledInput;
|
||||
|
||||
constructor(props: InputProps) {
|
||||
super(props);
|
||||
const value = typeof props.value === 'undefined' ? props.defaultValue : props.value;
|
||||
@@ -91,6 +122,15 @@ class Input extends React.Component<InputProps, any> {
|
||||
};
|
||||
}
|
||||
|
||||
static getDerivedStateFromProps(nextProps: InputProps) {
|
||||
if ('value' in nextProps) {
|
||||
return {
|
||||
value: nextProps.value,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Since polyfill `getSnapshotBeforeUpdate` need work with `componentDidUpdate`.
|
||||
// We keep an empty function here.
|
||||
componentDidUpdate() {}
|
||||
@@ -106,67 +146,6 @@ class Input extends React.Component<InputProps, any> {
|
||||
return null;
|
||||
}
|
||||
|
||||
getInputClassName(prefixCls: string) {
|
||||
const { size, disabled } = this.props;
|
||||
return classNames(prefixCls, {
|
||||
[`${prefixCls}-sm`]: size === 'small',
|
||||
[`${prefixCls}-lg`]: size === 'large',
|
||||
[`${prefixCls}-disabled`]: disabled,
|
||||
});
|
||||
}
|
||||
|
||||
setValue(
|
||||
value: string,
|
||||
e: React.ChangeEvent<HTMLInputElement> | React.MouseEvent<HTMLElement, MouseEvent>,
|
||||
callback?: () => void,
|
||||
) {
|
||||
if (!('value' in this.props)) {
|
||||
this.setState({ value }, callback);
|
||||
}
|
||||
const { onChange } = this.props;
|
||||
if (onChange) {
|
||||
let event = e;
|
||||
if (e.type === 'click') {
|
||||
// click clear icon
|
||||
event = Object.create(e);
|
||||
event.target = this.input;
|
||||
event.currentTarget = this.input;
|
||||
const originalInputValue = this.input.value;
|
||||
// change input value cause e.target.value should be '' when clear input
|
||||
this.input.value = '';
|
||||
onChange(event as React.ChangeEvent<HTMLInputElement>);
|
||||
// reset input value
|
||||
this.input.value = originalInputValue;
|
||||
return;
|
||||
}
|
||||
onChange(event as React.ChangeEvent<HTMLInputElement>);
|
||||
}
|
||||
}
|
||||
|
||||
saveInput = (node: HTMLInputElement) => {
|
||||
this.input = node;
|
||||
};
|
||||
|
||||
handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
const { onPressEnter, onKeyDown } = this.props;
|
||||
if (e.keyCode === 13 && onPressEnter) {
|
||||
onPressEnter(e);
|
||||
}
|
||||
if (onKeyDown) {
|
||||
onKeyDown(e);
|
||||
}
|
||||
};
|
||||
|
||||
handleReset = (e: React.MouseEvent<HTMLElement, MouseEvent>) => {
|
||||
this.setValue('', e, () => {
|
||||
this.focus();
|
||||
});
|
||||
};
|
||||
|
||||
handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
this.setValue(e.target.value, e);
|
||||
};
|
||||
|
||||
focus() {
|
||||
this.input.focus();
|
||||
}
|
||||
@@ -179,105 +158,29 @@ class Input extends React.Component<InputProps, any> {
|
||||
this.input.select();
|
||||
}
|
||||
|
||||
renderClearIcon(prefixCls: string) {
|
||||
const { allowClear, disabled } = this.props;
|
||||
const { value } = this.state;
|
||||
if (!allowClear || disabled || value === undefined || value === null || value === '') {
|
||||
return null;
|
||||
saveClearableInput = (input: ClearableLabeledInput) => {
|
||||
this.clearableInput = input;
|
||||
};
|
||||
|
||||
saveInput = (input: HTMLInputElement) => {
|
||||
this.input = input;
|
||||
};
|
||||
|
||||
setValue(value: string, callback?: () => void) {
|
||||
if (!('value' in this.props)) {
|
||||
this.setState({ value }, callback);
|
||||
}
|
||||
return (
|
||||
<Icon
|
||||
type="close-circle"
|
||||
theme="filled"
|
||||
onClick={this.handleReset}
|
||||
className={`${prefixCls}-clear-icon`}
|
||||
role="button"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
renderSuffix(prefixCls: string) {
|
||||
const { suffix, allowClear } = this.props;
|
||||
if (suffix || allowClear) {
|
||||
return (
|
||||
<span className={`${prefixCls}-suffix`}>
|
||||
{this.renderClearIcon(prefixCls)}
|
||||
{suffix}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
renderLabeledInput(prefixCls: string, children: React.ReactElement<any>) {
|
||||
const { addonBefore, addonAfter, style, size, className } = this.props;
|
||||
// Not wrap when there is not addons
|
||||
if (!addonBefore && !addonAfter) {
|
||||
return children;
|
||||
}
|
||||
|
||||
const wrapperClassName = `${prefixCls}-group`;
|
||||
const addonClassName = `${wrapperClassName}-addon`;
|
||||
const addonBeforeNode = addonBefore ? (
|
||||
<span className={addonClassName}>{addonBefore}</span>
|
||||
) : null;
|
||||
const addonAfterNode = addonAfter ? <span className={addonClassName}>{addonAfter}</span> : null;
|
||||
|
||||
const mergedWrapperClassName = classNames(`${prefixCls}-wrapper`, {
|
||||
[wrapperClassName]: addonBefore || addonAfter,
|
||||
handleReset = (e: React.MouseEvent<HTMLElement, MouseEvent>) => {
|
||||
this.setValue('', () => {
|
||||
this.focus();
|
||||
});
|
||||
resolveOnChange(this.input, e, this.props.onChange);
|
||||
};
|
||||
|
||||
const mergedGroupClassName = classNames(className, `${prefixCls}-group-wrapper`, {
|
||||
[`${prefixCls}-group-wrapper-sm`]: size === 'small',
|
||||
[`${prefixCls}-group-wrapper-lg`]: size === 'large',
|
||||
});
|
||||
|
||||
// Need another wrapper for changing display:table to display:inline-block
|
||||
// and put style prop in wrapper
|
||||
return (
|
||||
<span className={mergedGroupClassName} style={style}>
|
||||
<span className={mergedWrapperClassName}>
|
||||
{addonBeforeNode}
|
||||
{React.cloneElement(children, { style: null })}
|
||||
{addonAfterNode}
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
renderLabeledIcon(prefixCls: string, children: React.ReactElement<any>) {
|
||||
const { props } = this;
|
||||
const suffix = this.renderSuffix(prefixCls);
|
||||
|
||||
if (!hasPrefixSuffix(props)) {
|
||||
return children;
|
||||
}
|
||||
|
||||
const prefix = props.prefix ? (
|
||||
<span className={`${prefixCls}-prefix`}>{props.prefix}</span>
|
||||
) : null;
|
||||
|
||||
const affixWrapperCls = classNames(props.className, `${prefixCls}-affix-wrapper`, {
|
||||
[`${prefixCls}-affix-wrapper-sm`]: props.size === 'small',
|
||||
[`${prefixCls}-affix-wrapper-lg`]: props.size === 'large',
|
||||
[`${prefixCls}-affix-wrapper-with-clear-btn`]:
|
||||
props.suffix && props.allowClear && this.state.value,
|
||||
});
|
||||
return (
|
||||
<span className={affixWrapperCls} style={props.style}>
|
||||
{prefix}
|
||||
{React.cloneElement(children, {
|
||||
style: null,
|
||||
className: this.getInputClassName(prefixCls),
|
||||
})}
|
||||
{suffix}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
renderInput(prefixCls: string) {
|
||||
const { className, addonBefore, addonAfter } = this.props;
|
||||
const { value } = this.state;
|
||||
renderInput = (prefixCls: string) => {
|
||||
const { className, addonBefore, addonAfter, size, disabled } = this.props;
|
||||
// Fix https://fb.me/react-unknown-prop
|
||||
const otherProps = omit(this.props, [
|
||||
'prefixCls',
|
||||
@@ -291,27 +194,51 @@ class Input extends React.Component<InputProps, any> {
|
||||
// specify either the value prop, or the defaultValue prop, but not both.
|
||||
'defaultValue',
|
||||
'size',
|
||||
'inputType',
|
||||
]);
|
||||
|
||||
return this.renderLabeledIcon(
|
||||
prefixCls,
|
||||
return (
|
||||
<input
|
||||
{...otherProps}
|
||||
value={fixControlledValue(value)}
|
||||
onChange={this.handleChange}
|
||||
className={classNames(this.getInputClassName(prefixCls), {
|
||||
onKeyDown={this.handleKeyDown}
|
||||
className={classNames(getInputClassName(prefixCls, size, disabled), {
|
||||
[className!]: className && !addonBefore && !addonAfter,
|
||||
})}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
ref={this.saveInput}
|
||||
/>,
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
this.setValue(e.target.value);
|
||||
resolveOnChange(this.input, e, this.props.onChange);
|
||||
};
|
||||
|
||||
handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
const { onPressEnter, onKeyDown } = this.props;
|
||||
if (e.keyCode === 13 && onPressEnter) {
|
||||
onPressEnter(e);
|
||||
}
|
||||
if (onKeyDown) {
|
||||
onKeyDown(e);
|
||||
}
|
||||
};
|
||||
|
||||
renderComponent = ({ getPrefixCls }: ConfigConsumerProps) => {
|
||||
const { value } = this.state;
|
||||
const { prefixCls: customizePrefixCls } = this.props;
|
||||
const prefixCls = getPrefixCls('input', customizePrefixCls);
|
||||
return this.renderLabeledInput(prefixCls, this.renderInput(prefixCls));
|
||||
return (
|
||||
<ClearableLabeledInput
|
||||
{...this.props}
|
||||
prefixCls={prefixCls}
|
||||
inputType="input"
|
||||
value={fixControlledValue(value)}
|
||||
element={this.renderInput(prefixCls)}
|
||||
handleReset={this.handleReset}
|
||||
ref={this.saveClearableInput}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
|
||||
120
components/input/ResizableTextArea.tsx
Normal file
120
components/input/ResizableTextArea.tsx
Normal file
@@ -0,0 +1,120 @@
|
||||
import * as React from 'react';
|
||||
import { polyfill } from 'react-lifecycles-compat';
|
||||
import ResizeObserver from 'rc-resize-observer';
|
||||
import omit from 'omit.js';
|
||||
import classNames from 'classnames';
|
||||
import calculateNodeHeight from './calculateNodeHeight';
|
||||
import raf from '../_util/raf';
|
||||
import warning from '../_util/warning';
|
||||
import { TextAreaProps } from './TextArea';
|
||||
|
||||
export interface AutoSizeType {
|
||||
minRows?: number;
|
||||
maxRows?: number;
|
||||
}
|
||||
|
||||
export interface TextAreaState {
|
||||
textareaStyles?: React.CSSProperties;
|
||||
/** We need add process style to disable scroll first and then add back to avoid unexpected scrollbar */
|
||||
resizing?: boolean;
|
||||
}
|
||||
|
||||
class ResizableTextArea extends React.Component<TextAreaProps, TextAreaState> {
|
||||
nextFrameActionId: number;
|
||||
|
||||
resizeFrameId: number;
|
||||
|
||||
constructor(props: TextAreaProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
textareaStyles: {},
|
||||
resizing: false,
|
||||
};
|
||||
}
|
||||
|
||||
textArea: HTMLTextAreaElement;
|
||||
|
||||
saveTextArea = (textArea: HTMLTextAreaElement) => {
|
||||
this.textArea = textArea;
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.resizeTextarea();
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: TextAreaProps) {
|
||||
// Re-render with the new content then recalculate the height as required.
|
||||
if (prevProps.value !== this.props.value) {
|
||||
this.resizeTextarea();
|
||||
}
|
||||
}
|
||||
|
||||
resizeOnNextFrame = () => {
|
||||
raf.cancel(this.nextFrameActionId);
|
||||
this.nextFrameActionId = raf(this.resizeTextarea);
|
||||
};
|
||||
|
||||
resizeTextarea = () => {
|
||||
const autoSize = this.props.autoSize || this.props.autosize;
|
||||
if (!autoSize || !this.textArea) {
|
||||
return;
|
||||
}
|
||||
const { minRows, maxRows } = autoSize as AutoSizeType;
|
||||
const textareaStyles = calculateNodeHeight(this.textArea, false, minRows, maxRows);
|
||||
this.setState({ textareaStyles, resizing: true }, () => {
|
||||
raf.cancel(this.resizeFrameId);
|
||||
this.resizeFrameId = raf(() => {
|
||||
this.setState({ resizing: false });
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
componentWillUnmount() {
|
||||
raf.cancel(this.nextFrameActionId);
|
||||
raf.cancel(this.resizeFrameId);
|
||||
}
|
||||
|
||||
renderTextArea = () => {
|
||||
const { prefixCls, autoSize, autosize, className, disabled } = this.props;
|
||||
const { textareaStyles, resizing } = this.state;
|
||||
warning(
|
||||
autosize === undefined,
|
||||
'Input.TextArea',
|
||||
'autosize is deprecated, please use autoSize instead.',
|
||||
);
|
||||
const otherProps = omit(this.props, [
|
||||
'prefixCls',
|
||||
'onPressEnter',
|
||||
'autoSize',
|
||||
'autosize',
|
||||
'defaultValue',
|
||||
'allowClear',
|
||||
]);
|
||||
const cls = classNames(prefixCls, className, {
|
||||
[`${prefixCls}-disabled`]: disabled,
|
||||
});
|
||||
// Fix https://github.com/ant-design/ant-design/issues/6776
|
||||
// Make sure it could be reset when using form.getFieldDecorator
|
||||
if ('value' in otherProps) {
|
||||
otherProps.value = otherProps.value || '';
|
||||
}
|
||||
const style = {
|
||||
...this.props.style,
|
||||
...textareaStyles,
|
||||
...(resizing ? { overflow: 'hidden' } : null),
|
||||
};
|
||||
return (
|
||||
<ResizeObserver onResize={this.resizeOnNextFrame} disabled={!(autoSize || autosize)}>
|
||||
<textarea {...otherProps} className={cls} style={style} ref={this.saveTextArea} />
|
||||
</ResizeObserver>
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
return this.renderTextArea();
|
||||
}
|
||||
}
|
||||
|
||||
polyfill(ResizableTextArea);
|
||||
|
||||
export default ResizableTextArea;
|
||||
@@ -1,17 +1,9 @@
|
||||
import * as React from 'react';
|
||||
import omit from 'omit.js';
|
||||
import classNames from 'classnames';
|
||||
import { polyfill } from 'react-lifecycles-compat';
|
||||
import ResizeObserver from 'rc-resize-observer';
|
||||
import calculateNodeHeight from './calculateNodeHeight';
|
||||
import ClearableLabeledInput from './ClearableLabeledInput';
|
||||
import ResizableTextArea, { AutoSizeType } from './ResizableTextArea';
|
||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||
import raf from '../_util/raf';
|
||||
import warning from '../_util/warning';
|
||||
|
||||
export interface AutoSizeType {
|
||||
minRows?: number;
|
||||
maxRows?: number;
|
||||
}
|
||||
import { fixControlledValue, resolveOnChange } from './Input';
|
||||
|
||||
export type HTMLTextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>;
|
||||
|
||||
@@ -21,54 +13,62 @@ export interface TextAreaProps extends HTMLTextareaProps {
|
||||
autosize?: boolean | AutoSizeType;
|
||||
autoSize?: boolean | AutoSizeType;
|
||||
onPressEnter?: React.KeyboardEventHandler<HTMLTextAreaElement>;
|
||||
allowClear?: boolean;
|
||||
}
|
||||
|
||||
export interface TextAreaState {
|
||||
textareaStyles?: React.CSSProperties;
|
||||
/** We need add process style to disable scroll first and then add back to avoid unexpected scrollbar */
|
||||
resizing?: boolean;
|
||||
value: any;
|
||||
}
|
||||
|
||||
class TextArea extends React.Component<TextAreaProps, TextAreaState> {
|
||||
nextFrameActionId: number;
|
||||
resizableTextArea: ResizableTextArea;
|
||||
|
||||
resizeFrameId: number;
|
||||
clearableInput: ClearableLabeledInput;
|
||||
|
||||
state = {
|
||||
textareaStyles: {},
|
||||
resizing: false,
|
||||
};
|
||||
|
||||
private textAreaRef: HTMLTextAreaElement;
|
||||
|
||||
componentDidMount() {
|
||||
this.resizeTextarea();
|
||||
constructor(props: TextAreaProps) {
|
||||
super(props);
|
||||
const value = typeof props.value === 'undefined' ? props.defaultValue : props.value;
|
||||
this.state = {
|
||||
value,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: TextAreaProps) {
|
||||
// Re-render with the new content then recalculate the height as required.
|
||||
if (prevProps.value !== this.props.value) {
|
||||
this.resizeTextarea();
|
||||
static getDerivedStateFromProps(nextProps: TextAreaProps) {
|
||||
if ('value' in nextProps) {
|
||||
return {
|
||||
value: nextProps.value,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
raf.cancel(this.nextFrameActionId);
|
||||
raf.cancel(this.resizeFrameId);
|
||||
}
|
||||
|
||||
saveTextAreaRef = (textArea: HTMLTextAreaElement) => {
|
||||
this.textAreaRef = textArea;
|
||||
};
|
||||
|
||||
handleTextareaChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||
setValue(value: string, callback?: () => void) {
|
||||
if (!('value' in this.props)) {
|
||||
this.resizeTextarea();
|
||||
}
|
||||
const { onChange } = this.props;
|
||||
if (onChange) {
|
||||
onChange(e);
|
||||
this.setState({ value }, callback);
|
||||
}
|
||||
}
|
||||
|
||||
focus() {
|
||||
this.resizableTextArea.textArea.focus();
|
||||
}
|
||||
|
||||
blur() {
|
||||
this.resizableTextArea.textArea.blur();
|
||||
}
|
||||
|
||||
saveTextArea = (resizableTextArea: ResizableTextArea) => {
|
||||
this.resizableTextArea = resizableTextArea;
|
||||
};
|
||||
|
||||
saveClearableInput = (clearableInput: ClearableLabeledInput) => {
|
||||
this.clearableInput = clearableInput;
|
||||
};
|
||||
|
||||
handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||
this.setValue(e.target.value, () => {
|
||||
this.resizableTextArea.resizeTextarea();
|
||||
});
|
||||
resolveOnChange(this.resizableTextArea.textArea, e, this.props.onChange);
|
||||
};
|
||||
|
||||
handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
||||
@@ -81,76 +81,45 @@ class TextArea extends React.Component<TextAreaProps, TextAreaState> {
|
||||
}
|
||||
};
|
||||
|
||||
resizeOnNextFrame = () => {
|
||||
raf.cancel(this.nextFrameActionId);
|
||||
this.nextFrameActionId = raf(this.resizeTextarea);
|
||||
handleReset = (e: React.MouseEvent<HTMLElement, MouseEvent>) => {
|
||||
this.setValue('', () => {
|
||||
this.resizableTextArea.renderTextArea();
|
||||
this.focus();
|
||||
});
|
||||
resolveOnChange(this.resizableTextArea.textArea, e, this.props.onChange);
|
||||
};
|
||||
|
||||
resizeTextarea = () => {
|
||||
const autoSize = this.props.autoSize || this.props.autosize;
|
||||
if (!autoSize || !this.textAreaRef) {
|
||||
return;
|
||||
}
|
||||
const { minRows, maxRows } = autoSize as AutoSizeType;
|
||||
const textareaStyles = calculateNodeHeight(this.textAreaRef, false, minRows, maxRows);
|
||||
this.setState({ textareaStyles, resizing: true }, () => {
|
||||
raf.cancel(this.resizeFrameId);
|
||||
this.resizeFrameId = raf(() => {
|
||||
this.setState({ resizing: false });
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
focus() {
|
||||
this.textAreaRef.focus();
|
||||
}
|
||||
|
||||
blur() {
|
||||
this.textAreaRef.blur();
|
||||
}
|
||||
|
||||
renderTextArea = ({ getPrefixCls }: ConfigConsumerProps) => {
|
||||
const { textareaStyles, resizing } = this.state;
|
||||
const { prefixCls: customizePrefixCls, className, disabled, autoSize, autosize } = this.props;
|
||||
const { ...props } = this.props;
|
||||
const otherProps = omit(props, ['prefixCls', 'onPressEnter', 'autoSize', 'autosize']);
|
||||
const prefixCls = getPrefixCls('input', customizePrefixCls);
|
||||
const cls = classNames(prefixCls, className, {
|
||||
[`${prefixCls}-disabled`]: disabled,
|
||||
});
|
||||
|
||||
warning(
|
||||
autosize === undefined,
|
||||
'Input.TextArea',
|
||||
'autosize is deprecated, please use autoSize instead.',
|
||||
);
|
||||
|
||||
const style = {
|
||||
...props.style,
|
||||
...textareaStyles,
|
||||
...(resizing ? { overflow: 'hidden' } : null),
|
||||
};
|
||||
// Fix https://github.com/ant-design/ant-design/issues/6776
|
||||
// Make sure it could be reset when using form.getFieldDecorator
|
||||
if ('value' in otherProps) {
|
||||
otherProps.value = otherProps.value || '';
|
||||
}
|
||||
renderTextArea = (prefixCls: string) => {
|
||||
return (
|
||||
<ResizeObserver onResize={this.resizeOnNextFrame} disabled={!(autoSize || autosize)}>
|
||||
<textarea
|
||||
{...otherProps}
|
||||
className={cls}
|
||||
style={style}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
onChange={this.handleTextareaChange}
|
||||
ref={this.saveTextAreaRef}
|
||||
/>
|
||||
</ResizeObserver>
|
||||
<ResizableTextArea
|
||||
{...this.props}
|
||||
prefixCls={prefixCls}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
onChange={this.handleChange}
|
||||
ref={this.saveTextArea}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
renderComponent = ({ getPrefixCls }: ConfigConsumerProps) => {
|
||||
const { value } = this.state;
|
||||
const { prefixCls: customizePrefixCls } = this.props;
|
||||
const prefixCls = getPrefixCls('input', customizePrefixCls);
|
||||
return (
|
||||
<ClearableLabeledInput
|
||||
{...this.props}
|
||||
prefixCls={prefixCls}
|
||||
inputType="text"
|
||||
value={fixControlledValue(value)}
|
||||
element={this.renderTextArea(prefixCls)}
|
||||
handleReset={this.handleReset}
|
||||
ref={this.saveClearableInput}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
return <ConfigConsumer>{this.renderTextArea}</ConfigConsumer>;
|
||||
return <ConfigConsumer>{this.renderComponent}</ConfigConsumer>;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,68 +21,95 @@ exports[`Input.Password should change type when click 1`] = `
|
||||
}
|
||||
type="password"
|
||||
>
|
||||
<span
|
||||
className="ant-input-password ant-input-affix-wrapper"
|
||||
>
|
||||
<input
|
||||
action="click"
|
||||
className="ant-input"
|
||||
onChange={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
style={null}
|
||||
type="password"
|
||||
value="111"
|
||||
/>
|
||||
<span
|
||||
className="ant-input-suffix"
|
||||
>
|
||||
<ClearableLabeledInput
|
||||
action="click"
|
||||
className="ant-input-password"
|
||||
element={
|
||||
<input
|
||||
action="click"
|
||||
className="ant-input ant-input-password"
|
||||
onChange={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
type="password"
|
||||
/>
|
||||
}
|
||||
handleReset={[Function]}
|
||||
inputType="input"
|
||||
prefixCls="ant-input"
|
||||
suffix={
|
||||
<Icon
|
||||
className="ant-input-password-icon"
|
||||
key="passwordIcon"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
type="eye-invisible"
|
||||
/>
|
||||
}
|
||||
type="password"
|
||||
value="111"
|
||||
>
|
||||
<span
|
||||
className="ant-input-password ant-input-affix-wrapper"
|
||||
>
|
||||
<input
|
||||
action="click"
|
||||
className="ant-input"
|
||||
onChange={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
style={null}
|
||||
type="password"
|
||||
value="111"
|
||||
/>
|
||||
<span
|
||||
className="ant-input-suffix"
|
||||
>
|
||||
<LocaleReceiver
|
||||
componentName="Icon"
|
||||
<Icon
|
||||
className="ant-input-password-icon"
|
||||
key="passwordIcon"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
type="eye-invisible"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: eye-invisible"
|
||||
className="anticon anticon-eye-invisible ant-input-password-icon"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
tabIndex={-1}
|
||||
<LocaleReceiver
|
||||
componentName="Icon"
|
||||
>
|
||||
<IconReact
|
||||
className=""
|
||||
type="eye-invisible-o"
|
||||
<i
|
||||
aria-label="icon: eye-invisible"
|
||||
className="anticon anticon-eye-invisible ant-input-password-icon"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
tabIndex={-1}
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
<IconReact
|
||||
className=""
|
||||
data-icon="eye-invisible"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
key="svg-eye-invisible"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
type="eye-invisible-o"
|
||||
>
|
||||
<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"
|
||||
key="svg-eye-invisible-svg-0"
|
||||
/>
|
||||
<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"
|
||||
key="svg-eye-invisible-svg-1"
|
||||
/>
|
||||
</svg>
|
||||
</IconReact>
|
||||
</i>
|
||||
</LocaleReceiver>
|
||||
</Icon>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
className=""
|
||||
data-icon="eye-invisible"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
key="svg-eye-invisible"
|
||||
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"
|
||||
key="svg-eye-invisible-svg-0"
|
||||
/>
|
||||
<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"
|
||||
key="svg-eye-invisible-svg-1"
|
||||
/>
|
||||
</svg>
|
||||
</IconReact>
|
||||
</i>
|
||||
</LocaleReceiver>
|
||||
</Icon>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</ClearableLabeledInput>
|
||||
</Input>
|
||||
</Password>
|
||||
`;
|
||||
@@ -108,64 +135,91 @@ exports[`Input.Password should change type when click 2`] = `
|
||||
}
|
||||
type="text"
|
||||
>
|
||||
<span
|
||||
className="ant-input-password ant-input-affix-wrapper"
|
||||
>
|
||||
<input
|
||||
action="click"
|
||||
className="ant-input"
|
||||
onChange={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
style={null}
|
||||
type="text"
|
||||
value="111"
|
||||
/>
|
||||
<span
|
||||
className="ant-input-suffix"
|
||||
>
|
||||
<ClearableLabeledInput
|
||||
action="click"
|
||||
className="ant-input-password"
|
||||
element={
|
||||
<input
|
||||
action="click"
|
||||
className="ant-input ant-input-password"
|
||||
onChange={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
type="text"
|
||||
/>
|
||||
}
|
||||
handleReset={[Function]}
|
||||
inputType="input"
|
||||
prefixCls="ant-input"
|
||||
suffix={
|
||||
<Icon
|
||||
className="ant-input-password-icon"
|
||||
key="passwordIcon"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
type="eye"
|
||||
/>
|
||||
}
|
||||
type="text"
|
||||
value="111"
|
||||
>
|
||||
<span
|
||||
className="ant-input-password ant-input-affix-wrapper"
|
||||
>
|
||||
<input
|
||||
action="click"
|
||||
className="ant-input"
|
||||
onChange={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
style={null}
|
||||
type="text"
|
||||
value="111"
|
||||
/>
|
||||
<span
|
||||
className="ant-input-suffix"
|
||||
>
|
||||
<LocaleReceiver
|
||||
componentName="Icon"
|
||||
<Icon
|
||||
className="ant-input-password-icon"
|
||||
key="passwordIcon"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
type="eye"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: eye"
|
||||
className="anticon anticon-eye ant-input-password-icon"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
tabIndex={-1}
|
||||
<LocaleReceiver
|
||||
componentName="Icon"
|
||||
>
|
||||
<IconReact
|
||||
className=""
|
||||
type="eye-o"
|
||||
<i
|
||||
aria-label="icon: eye"
|
||||
className="anticon anticon-eye ant-input-password-icon"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
tabIndex={-1}
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
<IconReact
|
||||
className=""
|
||||
data-icon="eye"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
key="svg-eye"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
type="eye-o"
|
||||
>
|
||||
<path
|
||||
d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 0 0 0 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"
|
||||
key="svg-eye-svg-0"
|
||||
/>
|
||||
</svg>
|
||||
</IconReact>
|
||||
</i>
|
||||
</LocaleReceiver>
|
||||
</Icon>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
className=""
|
||||
data-icon="eye"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
key="svg-eye"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 0 0 0 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"
|
||||
key="svg-eye-svg-0"
|
||||
/>
|
||||
</svg>
|
||||
</IconReact>
|
||||
</i>
|
||||
</LocaleReceiver>
|
||||
</Icon>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</ClearableLabeledInput>
|
||||
</Input>
|
||||
</Password>
|
||||
`;
|
||||
@@ -191,68 +245,95 @@ exports[`Input.Password should change type when click 3`] = `
|
||||
}
|
||||
type="password"
|
||||
>
|
||||
<span
|
||||
className="ant-input-password ant-input-affix-wrapper"
|
||||
>
|
||||
<input
|
||||
action="click"
|
||||
className="ant-input"
|
||||
onChange={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
style={null}
|
||||
type="password"
|
||||
value="111"
|
||||
/>
|
||||
<span
|
||||
className="ant-input-suffix"
|
||||
>
|
||||
<ClearableLabeledInput
|
||||
action="click"
|
||||
className="ant-input-password"
|
||||
element={
|
||||
<input
|
||||
action="click"
|
||||
className="ant-input ant-input-password"
|
||||
onChange={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
type="password"
|
||||
/>
|
||||
}
|
||||
handleReset={[Function]}
|
||||
inputType="input"
|
||||
prefixCls="ant-input"
|
||||
suffix={
|
||||
<Icon
|
||||
className="ant-input-password-icon"
|
||||
key="passwordIcon"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
type="eye-invisible"
|
||||
/>
|
||||
}
|
||||
type="password"
|
||||
value="111"
|
||||
>
|
||||
<span
|
||||
className="ant-input-password ant-input-affix-wrapper"
|
||||
>
|
||||
<input
|
||||
action="click"
|
||||
className="ant-input"
|
||||
onChange={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
style={null}
|
||||
type="password"
|
||||
value="111"
|
||||
/>
|
||||
<span
|
||||
className="ant-input-suffix"
|
||||
>
|
||||
<LocaleReceiver
|
||||
componentName="Icon"
|
||||
<Icon
|
||||
className="ant-input-password-icon"
|
||||
key="passwordIcon"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
type="eye-invisible"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: eye-invisible"
|
||||
className="anticon anticon-eye-invisible ant-input-password-icon"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
tabIndex={-1}
|
||||
<LocaleReceiver
|
||||
componentName="Icon"
|
||||
>
|
||||
<IconReact
|
||||
className=""
|
||||
type="eye-invisible-o"
|
||||
<i
|
||||
aria-label="icon: eye-invisible"
|
||||
className="anticon anticon-eye-invisible ant-input-password-icon"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
tabIndex={-1}
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
<IconReact
|
||||
className=""
|
||||
data-icon="eye-invisible"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
key="svg-eye-invisible"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
type="eye-invisible-o"
|
||||
>
|
||||
<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"
|
||||
key="svg-eye-invisible-svg-0"
|
||||
/>
|
||||
<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"
|
||||
key="svg-eye-invisible-svg-1"
|
||||
/>
|
||||
</svg>
|
||||
</IconReact>
|
||||
</i>
|
||||
</LocaleReceiver>
|
||||
</Icon>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
className=""
|
||||
data-icon="eye-invisible"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
key="svg-eye-invisible"
|
||||
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"
|
||||
key="svg-eye-invisible-svg-0"
|
||||
/>
|
||||
<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"
|
||||
key="svg-eye-invisible-svg-1"
|
||||
/>
|
||||
</svg>
|
||||
</IconReact>
|
||||
</i>
|
||||
</LocaleReceiver>
|
||||
</Icon>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</ClearableLabeledInput>
|
||||
</Input>
|
||||
</Password>
|
||||
`;
|
||||
|
||||
@@ -853,19 +853,31 @@ exports[`renders ./components/input/demo/align.md correctly 1`] = `
|
||||
`;
|
||||
|
||||
exports[`renders ./components/input/demo/allowClear.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-input-affix-wrapper"
|
||||
>
|
||||
<input
|
||||
class="ant-input"
|
||||
placeholder="input with clear icon"
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
<div>
|
||||
<span
|
||||
class="ant-input-suffix"
|
||||
/>
|
||||
</span>
|
||||
class="ant-input-affix-wrapper"
|
||||
>
|
||||
<input
|
||||
class="ant-input"
|
||||
placeholder="input with clear icon"
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
<span
|
||||
class="ant-input-suffix"
|
||||
/>
|
||||
</span>
|
||||
<br />
|
||||
<br />
|
||||
<span
|
||||
class="ant-input-affix-wrapper ant-input-affix-wrapper-textarea-with-clear-btn"
|
||||
>
|
||||
<textarea
|
||||
class="ant-input"
|
||||
placeholder="textarea with clear icon"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/input/demo/autosize-textarea.md correctly 1`] = `
|
||||
@@ -1968,7 +1980,7 @@ exports[`renders ./components/input/demo/textarea-resize.md correctly 1`] = `
|
||||
class="ant-input"
|
||||
rows="4"
|
||||
>
|
||||
autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象,指定最小行数和最大行数。autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象,指定最小行数和最大行数。autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象,指定最小行数和最大行数。autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象,指定最小行数和最大行数。autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象,指定最小行数和最大行数。autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象,指定最小行数和最大行数。autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象,指定最小行数和最大行数。ending
|
||||
The autoSize property applies to textarea nodes, and only the height changes automatically. In addition, autoSize can be set to an object, specifying the minimum number of rows and the maximum number of rows. The autoSize property applies to textarea nodes, and only the height changes automatically. In addition, autoSize can be set to an object, specifying the minimum number of rows and the maximum number of rows.
|
||||
</textarea>
|
||||
</div>
|
||||
`;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -75,7 +75,7 @@ describe('TextArea', () => {
|
||||
|
||||
it('should auto calculate height according to content length', () => {
|
||||
const wrapper = mount(<TextArea value="" readOnly autoSize />);
|
||||
const mockFunc = jest.spyOn(wrapper.instance(), 'resizeTextarea');
|
||||
const mockFunc = jest.spyOn(wrapper.instance().resizableTextArea, 'resizeTextarea');
|
||||
wrapper.setProps({ value: '1111\n2222\n3333' });
|
||||
jest.runAllTimers();
|
||||
expect(mockFunc).toHaveBeenCalledTimes(1);
|
||||
@@ -161,7 +161,7 @@ describe('TextArea', () => {
|
||||
|
||||
it('when prop value not in this.props, resizeTextarea should be called', () => {
|
||||
const wrapper = mount(<TextArea aria-label="textarea" />);
|
||||
const resizeTextarea = jest.spyOn(wrapper.instance(), 'resizeTextarea');
|
||||
const resizeTextarea = jest.spyOn(wrapper.instance().resizableTextArea, 'resizeTextarea');
|
||||
wrapper.find('textarea').simulate('change', 'test');
|
||||
expect(resizeTextarea).toHaveBeenCalled();
|
||||
});
|
||||
@@ -317,3 +317,101 @@ describe('Input allowClear', () => {
|
||||
expect(wrapper.find('.ant-input-clear-icon').length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('TextArea allowClear', () => {
|
||||
it('should change type when click', () => {
|
||||
const wrapper = mount(<TextArea allowClear />);
|
||||
wrapper.find('textarea').simulate('change', { target: { value: '111' } });
|
||||
expect(wrapper.find('textarea').getDOMNode().value).toEqual('111');
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
wrapper
|
||||
.find('.ant-input-textarea-clear-icon')
|
||||
.at(0)
|
||||
.simulate('click');
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(wrapper.find('textarea').getDOMNode().value).toEqual('');
|
||||
});
|
||||
|
||||
it('should not show icon if value is undefined, null or empty string', () => {
|
||||
const wrappers = [null, undefined, ''].map(val => mount(<TextArea allowClear value={val} />));
|
||||
wrappers.forEach(wrapper => {
|
||||
expect(wrapper.find('textarea').getDOMNode().value).toEqual('');
|
||||
expect(wrapper.find('.ant-input-textarea-clear-icon').exists()).toEqual(false);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
it('should not show icon if defaultValue is undefined, null or empty string', () => {
|
||||
const wrappers = [null, undefined, ''].map(val =>
|
||||
mount(<TextArea allowClear defaultValue={val} />),
|
||||
);
|
||||
wrappers.forEach(wrapper => {
|
||||
expect(wrapper.find('textarea').getDOMNode().value).toEqual('');
|
||||
expect(wrapper.find('.ant-textarea-clear-icon').exists()).toEqual(false);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
it('should trigger event correctly', () => {
|
||||
let argumentEventObject;
|
||||
let argumentEventObjectValue;
|
||||
const onChange = e => {
|
||||
argumentEventObject = e;
|
||||
argumentEventObjectValue = e.target.value;
|
||||
};
|
||||
const wrapper = mount(<TextArea allowClear defaultValue="111" onChange={onChange} />);
|
||||
wrapper
|
||||
.find('.ant-input-textarea-clear-icon')
|
||||
.at(0)
|
||||
.simulate('click');
|
||||
expect(argumentEventObject.type).toBe('click');
|
||||
expect(argumentEventObjectValue).toBe('');
|
||||
expect(
|
||||
wrapper
|
||||
.find('textarea')
|
||||
.at(0)
|
||||
.getDOMNode().value,
|
||||
).toBe('');
|
||||
});
|
||||
|
||||
it('should trigger event correctly on controlled mode', () => {
|
||||
let argumentEventObject;
|
||||
let argumentEventObjectValue;
|
||||
const onChange = e => {
|
||||
argumentEventObject = e;
|
||||
argumentEventObjectValue = e.target.value;
|
||||
};
|
||||
const wrapper = mount(<TextArea allowClear value="111" onChange={onChange} />);
|
||||
wrapper
|
||||
.find('.ant-input-textarea-clear-icon')
|
||||
.at(0)
|
||||
.simulate('click');
|
||||
expect(argumentEventObject.type).toBe('click');
|
||||
expect(argumentEventObjectValue).toBe('');
|
||||
expect(
|
||||
wrapper
|
||||
.find('textarea')
|
||||
.at(0)
|
||||
.getDOMNode().value,
|
||||
).toBe('111');
|
||||
});
|
||||
|
||||
it('should focus textarea after clear', () => {
|
||||
const wrapper = mount(<TextArea allowClear defaultValue="111" />);
|
||||
wrapper
|
||||
.find('.ant-input-textarea-clear-icon')
|
||||
.at(0)
|
||||
.simulate('click');
|
||||
expect(document.activeElement).toBe(
|
||||
wrapper
|
||||
.find('textarea')
|
||||
.at(0)
|
||||
.getDOMNode(),
|
||||
);
|
||||
});
|
||||
|
||||
it('should not support allowClear when it is disabled', () => {
|
||||
const wrapper = mount(<TextArea allowClear defaultValue="111" disabled />);
|
||||
expect(wrapper.find('.ant-input-textarea-clear-icon').length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -16,12 +16,19 @@ Input box with the remove icon, click the icon to delete everything.
|
||||
```jsx
|
||||
import { Input } from 'antd';
|
||||
|
||||
const { TextArea } = Input;
|
||||
|
||||
const onChange = e => {
|
||||
console.log(e);
|
||||
};
|
||||
|
||||
ReactDOM.render(
|
||||
<Input placeholder="input with clear icon" allowClear onChange={onChange} />,
|
||||
<div>
|
||||
<Input placeholder="input with clear icon" allowClear onChange={onChange} />
|
||||
<br />
|
||||
<br />
|
||||
<TextArea placeholder="textarea with clear icon" allowClear onChange={onChange} />
|
||||
</div>,
|
||||
mountNode,
|
||||
);
|
||||
```
|
||||
|
||||
@@ -20,7 +20,7 @@ import { Input, Button } from 'antd';
|
||||
const { TextArea } = Input;
|
||||
|
||||
const defaultValue =
|
||||
'autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象,指定最小行数和最大行数。autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象,指定最小行数和最大行数。autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象,指定最小行数和最大行数。autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象,指定最小行数和最大行数。autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象,指定最小行数和最大行数。autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象,指定最小行数和最大行数。autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象,指定最小行数和最大行数。ending';
|
||||
'The autoSize property applies to textarea nodes, and only the height changes automatically. In addition, autoSize can be set to an object, specifying the minimum number of rows and the maximum number of rows. The autoSize property applies to textarea nodes, and only the height changes automatically. In addition, autoSize can be set to an object, specifying the minimum number of rows and the maximum number of rows.';
|
||||
|
||||
class Demo extends React.Component {
|
||||
state = {
|
||||
|
||||
@@ -46,6 +46,7 @@ The rest of the props of Input are exactly the same as the original [input](http
|
||||
| defaultValue | The initial input content | string | | |
|
||||
| value | The input content value | string | | |
|
||||
| onPressEnter | The callback function that is triggered when Enter key is pressed. | function(e) | | |
|
||||
| allowClear | allow to remove input content with clear icon | boolean | | 3.25.0 |
|
||||
|
||||
The rest of the props of `Input.TextArea` are the same as the original [textarea](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea).
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ Input 的其他属性和 React 自带的 [input](https://facebook.github.io/reac
|
||||
| defaultValue | 输入框默认内容 | string | | |
|
||||
| value | 输入框内容 | string | | |
|
||||
| onPressEnter | 按下回车的回调 | function(e) | | |
|
||||
| allowClear | 可以点击清除图标删除内容 | boolean | | 3.25.0 |
|
||||
|
||||
`Input.TextArea` 的其他属性和浏览器自带的 [textarea](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea) 一致。
|
||||
|
||||
|
||||
@@ -42,25 +42,16 @@
|
||||
}
|
||||
|
||||
.@{ant-prefix}-input-clear-icon {
|
||||
color: @disabled-color;
|
||||
font-size: @font-size-sm;
|
||||
// https://github.com/ant-design/ant-design/pull/18151
|
||||
// https://codesandbox.io/s/wizardly-sun-u10br
|
||||
.clear-icon;
|
||||
vertical-align: 0;
|
||||
cursor: pointer;
|
||||
transition: color 0.3s;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: @text-color-secondary;
|
||||
}
|
||||
|
||||
&:active {
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
+ i {
|
||||
margin-left: 6px;
|
||||
}
|
||||
.@{ant-prefix}-input-textarea-clear-icon {
|
||||
.clear-icon;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
margin: 8px 8px 0 0;
|
||||
}
|
||||
|
||||
@import './search-input';
|
||||
|
||||
@@ -307,13 +307,14 @@
|
||||
float: none;
|
||||
}
|
||||
|
||||
// reset border for Select, DatePicker, AutoComplete, Cascader, Mention, TimePicker
|
||||
// reset border for Select, DatePicker, AutoComplete, Cascader, Mention, TimePicker, Input
|
||||
& > .@{ant-prefix}-select > .@{ant-prefix}-select-selection,
|
||||
& > .@{ant-prefix}-calendar-picker .@{ant-prefix}-input,
|
||||
& > .@{ant-prefix}-select-auto-complete .@{ant-prefix}-input,
|
||||
& > .@{ant-prefix}-cascader-picker .@{ant-prefix}-input,
|
||||
& > .@{ant-prefix}-mention-wrapper .@{ant-prefix}-mention-editor,
|
||||
& > .@{ant-prefix}-time-picker .@{ant-prefix}-time-picker-input {
|
||||
& > .@{ant-prefix}-time-picker .@{ant-prefix}-time-picker-input,
|
||||
& > .@{ant-prefix}-input-group-wrapper .@{ant-prefix}-input {
|
||||
border-right-width: @border-width-base;
|
||||
border-radius: 0;
|
||||
|
||||
@@ -417,7 +418,32 @@
|
||||
padding-right: @input-padding-horizontal-base + @input-affix-width;
|
||||
}
|
||||
|
||||
&.@{inputClass}-affix-wrapper-with-clear-btn .@{inputClass}:not(:last-child) {
|
||||
&.@{inputClass}-affix-wrapper-input-with-clear-btn .@{inputClass}:not(:last-child) {
|
||||
padding-right: @input-padding-horizontal-base + @input-affix-with-clear-btn-width;
|
||||
}
|
||||
|
||||
&.@{inputClass}-affix-wrapper-textarea-with-clear-btn .@{inputClass} {
|
||||
padding-right: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
.clear-icon() {
|
||||
color: @disabled-color;
|
||||
font-size: @font-size-sm;
|
||||
// https://github.com/ant-design/ant-design/pull/18151
|
||||
// https://codesandbox.io/s/wizardly-sun-u10br
|
||||
cursor: pointer;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: @text-color-secondary;
|
||||
}
|
||||
|
||||
&:active {
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
+ i {
|
||||
margin-left: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ The sidebar.
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| breakpoint | [breakpoints](/components/grid#api) of the responsive layout | Enum { 'xs', 'sm', 'md', 'lg', 'xl', 'xxl' } | - | |
|
||||
| breakpoint | [breakpoints](/components/grid#Col) of the responsive layout | Enum { 'xs', 'sm', 'md', 'lg', 'xl', 'xxl' } | - | |
|
||||
| className | container className | string | - | |
|
||||
| collapsed | to set the current status | boolean | - | |
|
||||
| collapsedWidth | width of the collapsed sidebar, by setting to `0` a special trigger will appear | number | 80 | |
|
||||
@@ -99,7 +99,7 @@ The sidebar.
|
||||
| trigger | specify the customized trigger, set to null to hide the trigger | string\|ReactNode | - | |
|
||||
| width | width of the sidebar | number\|string | 200 | |
|
||||
| onCollapse | the callback function, executed by clicking the trigger or activating the responsive layout | (collapsed, type) => {} | - | |
|
||||
| onBreakpoint | the callback function, executed when [breakpoints](/components/grid#api) changed | (broken) => {} | - | 3.7.0 |
|
||||
| onBreakpoint | the callback function, executed when [breakpoints](/components/grid#API) changed | (broken) => {} | - | 3.7.0 |
|
||||
| zeroWidthTriggerStyle | to customize the styles of the special trigger that appears when `collapsedWidth` is 0 | object | - | 3.24.0 |
|
||||
|
||||
#### breakpoint width
|
||||
|
||||
@@ -88,7 +88,7 @@ title: Layout
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| breakpoint | 触发响应式布局的[断点](/components/grid#api) | Enum { 'xs', 'sm', 'md', 'lg', 'xl', 'xxl' } | - | |
|
||||
| breakpoint | 触发响应式布局的[断点](/components/grid-cn/#Col) | Enum { 'xs', 'sm', 'md', 'lg', 'xl', 'xxl' } | - | |
|
||||
| className | 容器 className | string | - | |
|
||||
| collapsed | 当前收起状态 | boolean | - | |
|
||||
| collapsedWidth | 收缩宽度,设置为 0 会出现特殊 trigger | number | 80 | |
|
||||
@@ -100,7 +100,7 @@ title: Layout
|
||||
| trigger | 自定义 trigger,设置为 null 时隐藏 trigger | string\|ReactNode | - | |
|
||||
| width | 宽度 | number\|string | 200 | |
|
||||
| onCollapse | 展开-收起时的回调函数,有点击 trigger 以及响应式反馈两种方式可以触发 | (collapsed, type) => {} | - | |
|
||||
| onBreakpoint | 触发响应式布局[断点](/components/grid#api)时的回调 | (broken) => {} | - | 3.7.0 |
|
||||
| onBreakpoint | 触发响应式布局[断点](/components/grid#API)时的回调 | (broken) => {} | - | 3.7.0 |
|
||||
| zeroWidthTriggerStyle | 指定当 `collapsedWidth` 为 0 时出现的特殊 trigger 的样式 | object | - | 3.24.0 |
|
||||
|
||||
#### breakpoint width
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -1862,7 +1862,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
|
||||
</i>
|
||||
</th>
|
||||
<th
|
||||
class=""
|
||||
class="ant-table-row-cell-last"
|
||||
>
|
||||
<span
|
||||
class="ant-table-header-column"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -43,6 +43,7 @@ import jaJP from '../ja_JP';
|
||||
import knIN from '../kn_IN';
|
||||
import koKR from '../ko_KR';
|
||||
import kuIQ from '../ku_IQ';
|
||||
import mkMK from '../mk_MK';
|
||||
import mnMN from '../mn_MN';
|
||||
import msMY from '../ms_MY';
|
||||
import nbNO from '../nb_NO';
|
||||
@@ -95,6 +96,7 @@ const locales = [
|
||||
knIN,
|
||||
koKR,
|
||||
kuIQ,
|
||||
mkMK,
|
||||
msMY,
|
||||
mnMN,
|
||||
nbNO,
|
||||
|
||||
3
components/locale-provider/mk_MK.tsx
Normal file
3
components/locale-provider/mk_MK.tsx
Normal file
@@ -0,0 +1,3 @@
|
||||
import locale from '../locale/mk_MK';
|
||||
|
||||
export default locale;
|
||||
@@ -35,6 +35,7 @@ export default {
|
||||
removeFile: 'احذف الملف',
|
||||
uploadError: 'مشكلة فى الرفع',
|
||||
previewFile: 'استعرض الملف',
|
||||
downloadFile: 'تحميل الملف',
|
||||
},
|
||||
Empty: {
|
||||
description: 'لا توجد بيانات',
|
||||
|
||||
@@ -35,6 +35,7 @@ export default {
|
||||
removeFile: 'Премахване',
|
||||
uploadError: 'Грешка при качването',
|
||||
previewFile: 'Преглед',
|
||||
downloadFile: 'Свали файл',
|
||||
},
|
||||
Empty: {
|
||||
description: 'Няма данни',
|
||||
|
||||
@@ -28,6 +28,13 @@ export default {
|
||||
itemUnit: 'item',
|
||||
itemsUnit: 'items',
|
||||
},
|
||||
Upload: {
|
||||
uploading: 'Carregant...',
|
||||
removeFile: 'Elimina el fitxer',
|
||||
uploadError: 'Error de càrrega',
|
||||
previewFile: 'Vista prèvia del fitxer',
|
||||
downloadFile: "Descarrega l'arxiu",
|
||||
},
|
||||
Empty: {
|
||||
description: 'Sense dades',
|
||||
},
|
||||
|
||||
@@ -33,6 +33,7 @@ export default {
|
||||
removeFile: 'Odstranit soubor',
|
||||
uploadError: 'Chyba při nahrávání',
|
||||
previewFile: 'Zobrazit soubor',
|
||||
downloadFile: 'Stáhnout soubor',
|
||||
},
|
||||
Empty: {
|
||||
description: 'Žádná data',
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user