Compare commits

..

45 Commits

Author SHA1 Message Date
诸岳
996ba5159b Merge pull request #29300 from ant-design/release-4.12.3
docs(): release changelog 4.12.3
2021-02-10 22:44:33 +08:00
诸岳
6f4dc771f8 chore(docs): Update changelog of 4.12.3 2021-02-10 22:37:22 +08:00
诸岳
c5fd0eda1b Merge branch 'master' of github.com:ant-design/ant-design into release-4.12.3 2021-02-10 20:15:48 +08:00
诸岳
172093048f test: Update snapshots 2021-02-10 20:03:28 +08:00
诸岳
545e431a74 chore(docs): Update changelog of 4.12.3 2021-02-10 19:40:27 +08:00
xrkffgg
eb720d3f84 ci: update verify acition 2021-02-10 18:23:03 +08:00
zombiej
7ffacd6051 chore: Update icons version 2021-02-10 17:57:18 +08:00
07akioni
5edc935d94 feat: new antd-colors, smaller size (#29307)
* feat: new colors, smaller size

* feat: alpha version icons, test ci
2021-02-10 17:46:25 +08:00
Kermit
a93767562a chore(slider): optimize tooltip align (#29308) 2021-02-10 15:53:07 +08:00
Kermit
7368b05b05 fix: update snapshot (#29309) 2021-02-10 15:10:39 +08:00
诸岳
e5c777e58d chore(docs): Use national flag for locale changelog 2021-02-09 21:56:19 +08:00
诸岳
367a64676f test: Update snapshots 2021-02-09 21:22:59 +08:00
诸岳
b03f7bd6c3 Merge branch 'master' of github.com:ant-design/ant-design into release-4.12.3 2021-02-09 21:02:31 +08:00
诸岳
3103d388c8 docs(): release 4.12.3 2021-02-09 20:11:43 +08:00
afc163
1d437534a0 docs: fix broken links
close #29294
2021-02-09 19:25:55 +08:00
xrkffgg
b9a7317c28 test: update snap 2021-02-08 10:04:27 +08:00
xrkffgg
dc317d1c14 ci: update pr welcome 2021-02-07 23:54:59 +08:00
雷玮杰
ac022b1d15 docs: add rowKey prop into doc (#29269)
update index.zh-CN.md
2021-02-07 20:57:18 +08:00
mumiao
d83e5fdd0a fix: pagination componnet is not displayed at the position is none of… (#29256)
* fix: pagination componnet is not displayed at the position is none of array

* docs: update table/pagination position column typeValue

* fix: named invalid column

* fix: delete unless code

* refactor: refactor pagination position logic

* ci: fix lint error

* ci: fix lint error

* test: update snapshot
2021-02-07 20:23:40 +08:00
mumiao
bcd58bdc12 fix: image ru_RU locale (#29271) 2021-02-07 14:22:40 +08:00
Li C. Pan
cf156b9c4a docs: Update overview.zh-CN.md (#29264)
* Update overview.zh-CN.md

* Update docs/spec/overview.zh-CN.md

Co-authored-by: Amumu <yoyo837@hotmail.com>

Co-authored-by: afc163 <afc163@gmail.com>
Co-authored-by: Amumu <yoyo837@hotmail.com>
2021-02-06 23:08:42 +08:00
xrkffgg
3779fec2cf ci: add pr welcome (#29238)
* ci: add pr welcome

* Update .github/workflows/pr-welcome.yml

Co-authored-by: Rustin Liu <rustin.liu@gmail.com>

* Update .github/workflows/pr-welcome.yml

Co-authored-by: Rustin Liu <rustin.liu@gmail.com>

Co-authored-by: Rustin Liu <rustin.liu@gmail.com>
2021-02-06 19:16:09 +08:00
Jeff Wen
ec81e9418e docs: Fix data visualization color palette url (#29257) 2021-02-05 22:22:08 +08:00
afc163
a64056eb8a fix: TextArea showCount should not be interactive (#29245)
close #29240
2021-02-05 20:34:28 +08:00
Seyed Amirali Taheri
0fc27299d5 fix: Locale fa (#29232)
* fix: Fix typo in fa_IR.tsx

Signed-off-by: amiralitaheri <amiralitaheri64@gmail.com>

* feat: Add missing values for fa_IR.tsx

Signed-off-by: amiralitaheri <amiralitaheri64@gmail.com>

* feat: Add missing locale values for date-picker/locale/fa_IR.tsx

Signed-off-by: amiralitaheri <amiralitaheri64@gmail.com>

* feat: Add missing locale value for time-picker/locale/fa_IR.tsx

Signed-off-by: amiralitaheri <amiralitaheri64@gmail.com>

* test: Update snapshot

Signed-off-by: amiralitaheri <amiralitaheri64@gmail.com>
2021-02-05 20:34:10 +08:00
xrkffgg
cb2fc79a5f fix: multiple Select disabled background in dark (#29242) 2021-02-05 14:43:22 +08:00
mumiao
b5d7670391 fix: fix confirm paramter ts type error (#29241) 2021-02-05 11:19:57 +08:00
afc163
4ee9253467 refactor(drawer): rewrite with hook from @hosseinmd (#29229)
* refactor: drawer to functional component and  hooks

* chore: clean code default value

* perf: remove doesn't necessary useCallback

* chore: useContext instead of Consumer

* fix ref

* Add Drawer displayName

* fix tsc

* fix tsc

Co-authored-by: Hossein Mohammadi <hosseinm.developer@gmail.com>
2021-02-05 10:47:17 +08:00
Renny Ren
d7d2cefe21 docs: Update index.en-US.md (#29234)
Fix grammar
2021-02-05 10:03:01 +08:00
zj9495
f77a9ac402 docs: add missing docs for array rule (#28437)
* docs: add missing docs for array rule

* update docs

* update docs
2021-02-04 22:04:34 +08:00
afc163
e5c4092509 test: fix codesandbox ci node version (#29228) 2021-02-04 17:32:38 +08:00
二货机器人
eb557abeaa docs: 4.12.2 changelog (#29223) 2021-02-04 11:23:09 +08:00
xrkffgg
c56a434cca ci: update verify trigger
review_requested 这个应该用不上,有点多余
2021-02-04 11:10:50 +08:00
einq7
69a5be7c40 docs: Update FAQ (#29210)
* docs: Modify FAQ

* Components don't need to use inline code

* Update anchors

* Apply suggestions from code review

Co-authored-by: afc163 <afc163@gmail.com>

* Apply suggestions from code review

Co-authored-by: afc163 <afc163@gmail.com>

* Update more links

Co-authored-by: afc163 <afc163@gmail.com>
2021-02-04 10:56:24 +08:00
afc163
f6683ebfc3 style: make Table expand icon same size as checkbox (#29214)
close #29207
2021-02-03 22:36:44 +08:00
xrkffgg
f434440bd1 ci: update verify package version 2021-02-03 21:50:19 +08:00
afc163
d5097a88e9 Delete codeql-analysis.yml 2021-02-03 19:09:06 +08:00
xrkffgg
c1f5f19001 ci: add verify-package-version (#29205)
* ci: add verify-package-version

* Update verify-package-version.yml

* Update verify-package-version.yml

* Update package.json

* Update package.json
2021-02-03 18:09:27 +08:00
二货机器人
a26e5036e6 fix: only row gutter use gap (#29211)
* fix: only row gutter use gap

* test: Update test case
2021-02-03 18:06:51 +08:00
二货机器人
1f7d200f70 docs: 4.12.1 changelog (#29204) 2021-02-03 15:58:49 +08:00
陈帅
c234b33c19 chore: add changelog check script (#29198)
* chore: add changelog check script

* add \n
2021-02-03 15:58:27 +08:00
二货机器人
9914ceb6be fix: Grid flexGap lazy check (#29202)
* fix: get flex gap support before render

* chore: patch unit

* chore: rename

* test: fix test case
2021-02-03 15:39:51 +08:00
zombiej
a8ce4d404a docs: Fix mobile res missing 2021-02-03 14:46:36 +08:00
afc163
b69c3351b1 fix: Table pagination current change logic (#29184)
* refactor: code style

* fix: Table pagination current when pageSize changed

close #29175

* fix current when have pagination.total
2021-02-03 11:42:11 +08:00
chenshuai2144
a21c66a97a docs: add 4.11.3 changelog 2021-02-03 02:57:05 +08:00
47 changed files with 710 additions and 437 deletions

View File

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

View File

@@ -1,54 +0,0 @@
name: "CodeQL"
on:
push:
branches: [master, 0.12-stable, 1.x-stable, 2.x-stable, 3.x-stable, feature, gh-pages]
pull_request:
# The branches below must be a subset of the branches above
branches: [master]
schedule:
- cron: '0 13 * * 1'
jobs:
analyse:
name: Analyse
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
fetch-depth: 2
# If this run was triggered by a pull request event, then checkout
# the head of the pull request instead of the merge commit.
- run: git checkout HEAD^2
if: ${{ github.event_name == 'pull_request' }}
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
# Override language selection by uncommenting this and choosing your languages
# with:
# languages: go, javascript, csharp, python, cpp, java
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

22
.github/workflows/pr-welcome.yml vendored Normal file
View File

@@ -0,0 +1,22 @@
name: PR Welcome
on:
pull_request_target:
types: [opened, edited, reopened]
jobs:
welcome:
runs-on: ubuntu-latest
steps:
- uses: actions-cool/pr-welcome@v1.1.0
with:
token: ${{ secrets.ANT_BOT_TOKEN }}
refuse-issue-label: '🎱 Collaborate PR only'
need-creator-authority: 'write'
comment: |
Hi @${{ github.event.pull_request.user.login }}. The issue mentioned in this PR needs to be confirmed with the designer or core team. This PR is temporarily not accepted. Thank you again for your contribution! 😊
你好 @${{ github.event.pull_request.user.login }}。这个 PR 提及的 issue 需要和设计师或核心团队进行确认,暂时不接受 PR再次感谢你的贡献😊
emoji: 'heart'
pr-emoji: 'heart'
close: true

View File

@@ -0,0 +1,19 @@
name: Verify Package Version
on:
pull_request:
types: [opened, edited, reopened, synchronize, ready_for_review]
jobs:
verify:
runs-on: ubuntu-latest
if: contains(github.event.pull_request.title, 'changelog') || contains(github.event.pull_request.title, 'release')
steps:
- uses: actions/checkout@v2
- name: verify-version
uses: actions-cool/verify-package-version@v1.1.1
with:
token: ${{ secrets.ANT_BOT_TOKEN }}
title-include-content: 'docs'
title-include-version: true
open-comment: true

View File

@@ -15,8 +15,39 @@ timeline: true
---
## 4.12.3
`2021-02-10`
- 🛠 Refactor Drawer with React hooks. [#29229](https://github.com/ant-design/ant-design/pull/29229)
- 🐞 Fix Table pagination not disappear when `pagination.position` is `['none', 'none']`. [#29256](https://github.com/ant-design/ant-design/pull/29256) [@mumiao](https://github.com/mumiao)
- 🐞 Fix TextArea `showCount` should not be interactive. [#29245](https://github.com/ant-design/ant-design/pull/29245)
- 🐞 Fix abnormal background color for `multiple` and `disabled` Select in dark. [#29242](https://github.com/ant-design/ant-design/pull/29242)
- ⚡️ Optimize Slider align performance of tooltip. [#29308](https://github.com/ant-design/ant-design/pull/29308) [@kerm1it](https://github.com/kerm1it)
- ⚡️ Upgrade `@ant-design/colors` to 6.x to reduce gzipped bundle size `1KB`. [#29307](https://github.com/ant-design/ant-design/pull/29307) [@07akioni](https://github.com/07akioni)
- 🇷🇺 Add `ru_RU` locale text for Image. [#29271](https://github.com/ant-design/ant-design/pull/29271) [@mumiao](https://github.com/mumiao)
- 🇮🇷 Add `fa_IR` locale text for DatePicker, Form, Table, TimePicker and Transfer. [#29232](https://github.com/ant-design/ant-design/pull/29232) [@amiralitaheri](https://github.com/amiralitaheri)
- TypeScript
- 🤖 Fix type definition for Table FilterDropdownProps `confirm` parameter. [#29241](https://github.com/ant-design/ant-design/pull/29241) [@mumiao](https://github.com/mumiao)
## 4.12.2
`2021-02-04`
- 💄 Make Table expand icon and checkbox same size and aligned. [#29214](https://github.com/ant-design/ant-design/pull/29214)
- 🐞 Fix List with `gutter` makes column break line. [#29211](https://github.com/ant-design/ant-design/pull/29211)
## 4.12.1
`2021-02-03`
- 🐞 Fix antd crash when load before page ready. [#29202](https://github.com/ant-design/ant-design/pull/29202)
- 🐞 Fix Table pagination `current` change logic when `pageSize` changes. [#29184](https://github.com/ant-design/ant-design/pull/29184)
## 4.12.0
`2021-02-03`
- 🆕 Image.PreviewGroup add `current` prop. [#29153](https://github.com/ant-design/ant-design/pull/29153)
- InputNumber
- 🆕 InputNumber support `bordered` prop. [#29105](https://github.com/ant-design/ant-design/pull/29105)
@@ -38,6 +69,12 @@ timeline: true
- Less
- 💄 Add less variable `@progress-info-text-color`. [#28981](https://github.com/ant-design/ant-design/pull/28981) [@yuxuan](https://github.com/yuxuan)
## 4.11.3
`2021-02-03`
Wrong release is the same as `4.12.0`, if you need to lock the version, you need to lock it to `4.11.2`.
## 4.11.2
`2021-01-26`

View File

@@ -15,8 +15,39 @@ timeline: true
---
## 4.12.3
`2021-02-10`
- 🛠 使用 React hooks 重构 Drawer。[#29229](https://github.com/ant-design/ant-design/pull/29229)
- 🐞 修复 Table 的 `pagination. position``['none', 'none']`时分页器仍然展示的问题。[#29256](https://github.com/ant-design/ant-design/pull/29256) [@mumiao](https://github.com/mumiao)
- 🐞 修复 TextArea `showCount` 字数会遮挡 Form.Item `extra` 的问题。[#29245](https://github.com/ant-design/ant-design/pull/29245)
- 🐞 修复多选 Select 在暗黑模式下禁用的背景颜色异常的问题。[#29242](https://github.com/ant-design/ant-design/pull/29242)
- ⚡️ 优化 Slider 提示的对齐性能。[#29308](https://github.com/ant-design/ant-design/pull/29308) [@kerm1it](https://github.com/kerm1it)
- ⚡️ 升级 `@ant-design/colors` 依赖到 6.x减少 gzipped 包体积 `1KB`。[#29307](https://github.com/ant-design/ant-design/pull/29307) [@07akioni](https://github.com/07akioni)
- 🇷🇺 为 Image 组件添加 `ru_RU` 俄语翻译。[#29271](https://github.com/ant-design/ant-design/pull/29271) [@mumiao](https://github.com/mumiao)
- 🇮🇷 为 DatePicker、Form、Table、TimePicker 和 Transfer 组件添加 `fa_IR` 波斯语翻译。[#29232](https://github.com/ant-design/ant-design/pull/29232) [@amiralitaheri](https://github.com/amiralitaheri)
- TypeScript
- 🤖 修复 Table FilterDropdownProps 的 `confirm` 入参为可选类型。[#29241](https://github.com/ant-design/ant-design/pull/29241) [@mumiao](https://github.com/mumiao)
## 4.12.2
`2021-02-04`
- 💄 调整 Table 展开图标和选择框的大小一致并对齐。[#29214](https://github.com/ant-design/ant-design/pull/29214)
- 🐞 修复 List 配置 `gutter` 时列会折行的问题。[#29211](https://github.com/ant-design/ant-design/pull/29211)
## 4.12.1
`2021-02-03`
- 🐞 修复 antd 在页面加载之前载入导致的页面崩溃问题。[#29202](https://github.com/ant-design/ant-design/pull/29202)
- 🐞 修正 Table 改变 `pageSize` 重置 `current` 的逻辑,现在若超出会重置到最大页数。[#29184](https://github.com/ant-design/ant-design/pull/29184)
## 4.12.0
`2021-02-03`
- 🆕 Image.PreviewGroup 添加 `current` 属性支持受控模式。[#29153](https://github.com/ant-design/ant-design/pull/29153)
- InputNumber
- 🆕 InputNumber 支持 `bordered` 属性。[#29105](https://github.com/ant-design/ant-design/pull/29105)
@@ -38,6 +69,12 @@ timeline: true
- Less
- 💄 增加 less 变量 `@progress-info-text-color`。 [#28981](https://github.com/ant-design/ant-design/pull/28981) [@yuxuan](https://github.com/yuxuan)
## 4.11.3
`2021-02-03`
错误的发布,与 `4.12.0` 相同,如果需要锁定版本,需要锁定到 `4.11.2`
## 4.11.2
`2021-01-26`

View File

@@ -10,7 +10,7 @@ import {
import getDataOrAriaProps from '../getDataOrAriaProps';
import Wave from '../wave';
import TransButton from '../transButton';
import { isStyleSupport, isFlexSupported } from '../styleChecker';
import { isStyleSupport } from '../styleChecker';
import { sleep } from '../../../tests/utils';
describe('Test utils function', () => {
@@ -208,10 +208,6 @@ describe('Test utils function', () => {
});
describe('style', () => {
it('isFlexSupported', () => {
expect(isFlexSupported).toBe(true);
});
it('isStyleSupport', () => {
expect(isStyleSupport('color')).toBe(true);
expect(isStyleSupport('not-existed')).toBe(false);

View File

@@ -12,13 +12,16 @@ export const isStyleSupport = (styleName: string | Array<string>): boolean => {
return false;
};
export const isFlexSupported = isStyleSupport(['flex', 'webkitFlex', 'Flex', 'msFlex']);
export const isFlexGapSupported = (() => {
let flexGapSupported: boolean | undefined;
export const detectFlexGapSupported = () => {
if (!canUseDocElement()) {
return false;
}
if (flexGapSupported !== undefined) {
return flexGapSupported;
}
// create flex container with row-gap set
const flex = document.createElement('div');
flex.style.display = 'flex';
@@ -31,8 +34,8 @@ export const isFlexGapSupported = (() => {
// append to the DOM (needed to obtain scrollHeight)
document.body.appendChild(flex);
const isSupported = flex.scrollHeight === 1; // flex container should be 1px high from the row-gap
flexGapSupported = flex.scrollHeight === 1; // flex container should be 1px high from the row-gap
document.body.removeChild(flex);
return isSupported;
})();
return flexGapSupported;
};

View File

@@ -6,7 +6,14 @@ import { PickerLocale } from '../generatePicker';
const locale: PickerLocale = {
lang: {
placeholder: 'انتخاب تاریخ',
yearPlaceholder: 'انتخاب سال',
quarterPlaceholder: 'انتخاب فصل',
monthPlaceholder: 'انتخاب ماه',
weekPlaceholder: 'انتخاب هفته',
rangePlaceholder: ['تاریخ شروع', 'تاریخ پایان'],
rangeYearPlaceholder: ['سال شروع', 'سال پایان'],
rangeMonthPlaceholder: ['ماه شروع', 'ماه پایان'],
rangeWeekPlaceholder: ['هفته شروع', 'هفته پایان'],
...CalendarLocale,
},
timePickerLocale: {

View File

@@ -147,4 +147,15 @@ describe('Drawer', () => {
errorSpy.mockRestore();
});
it('should support ref', () => {
const ref = React.createRef();
mount(
<Drawer visible ref={ref} width={400}>
Here is content of Drawer
</Drawer>,
);
expect(typeof ref.current.push).toBe('function');
expect(typeof ref.current.pull).toBe('function');
});
});

View File

@@ -0,0 +1,23 @@
import * as React from 'react';
import Drawer from '..';
describe('Drawer.typescript', () => {
it('Drawer', () => {
const onClose = jest.fn();
const wrapper = (
<Drawer
title="Basic Drawer"
placement="right"
closable={false}
onClose={onClose}
visible={false}
>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Drawer>
);
expect(wrapper).toBeTruthy();
});
});

View File

@@ -3,11 +3,16 @@ import RcDrawer from 'rc-drawer';
import getScrollBarSize from 'rc-util/lib/getScrollBarSize';
import CloseOutlined from '@ant-design/icons/CloseOutlined';
import classNames from 'classnames';
import omit from 'rc-util/lib/omit';
import { ConfigContext, DirectionType } from '../config-provider';
import { tuple } from '../_util/type';
import useForceUpdate from '../_util/hooks/useForceUpdate';
const DrawerContext = React.createContext<Drawer | null>(null);
type DrawerRef = {
push(): void;
pull(): void;
};
const DrawerContext = React.createContext<DrawerRef | null>(null);
type EventType =
| React.KeyboardEvent<HTMLDivElement>
@@ -50,6 +55,7 @@ export interface DrawerProps {
keyboard?: boolean;
footer?: React.ReactNode;
footerStyle?: React.CSSProperties;
level?: string | string[] | null | undefined;
}
export interface IDrawerState {
@@ -61,223 +67,222 @@ interface InternalDrawerProps extends DrawerProps {
}
const defaultPushState: PushState = { distance: 180 };
class Drawer extends React.Component<InternalDrawerProps, IDrawerState> {
static defaultProps = {
width: 256,
height: 256,
closable: true,
placement: 'right' as placementType,
maskClosable: true,
mask: true,
level: null,
keyboard: true,
push: defaultPushState,
};
readonly state = {
push: false,
};
parentDrawer: Drawer | null;
destroyClose: boolean;
public componentDidMount() {
// fix: delete drawer in child and re-render, no push started.
// <Drawer>{show && <Drawer />}</Drawer>
const { visible } = this.props;
if (visible && this.parentDrawer) {
this.parentDrawer.push();
}
}
public componentDidUpdate(preProps: DrawerProps) {
const { visible } = this.props;
if (preProps.visible !== visible && this.parentDrawer) {
if (visible) {
this.parentDrawer.push();
} else {
this.parentDrawer.pull();
}
}
}
public componentWillUnmount() {
// unmount drawer in child, clear push.
if (this.parentDrawer) {
this.parentDrawer.pull();
this.parentDrawer = null;
}
}
push = () => {
if (this.props.push) {
this.setState({ push: true });
}
};
pull = () => {
if (this.props.push) {
this.setState({ push: false });
}
};
onDestroyTransitionEnd = () => {
const isDestroyOnClose = this.getDestroyOnClose();
if (!isDestroyOnClose) {
return;
}
if (!this.props.visible) {
this.destroyClose = true;
this.forceUpdate();
}
};
getDestroyOnClose = () => this.props.destroyOnClose && !this.props.visible;
getPushDistance = () => {
const { push } = this.props;
let distance: number | string;
if (typeof push === 'boolean') {
distance = push ? defaultPushState.distance : 0;
} else {
distance = push!.distance;
}
return parseFloat(String(distance || 0));
};
// get drawer push width or height
getPushTransform = (placement?: placementType) => {
const distance = this.getPushDistance();
if (placement === 'left' || placement === 'right') {
return `translateX(${placement === 'left' ? distance : -distance}px)`;
}
if (placement === 'top' || placement === 'bottom') {
return `translateY(${placement === 'top' ? distance : -distance}px)`;
}
};
getOffsetStyle() {
const { placement, width, height, visible, mask } = this.props;
// https://github.com/ant-design/ant-design/issues/24287
if (!visible && !mask) {
return {};
}
const offsetStyle: any = {};
if (placement === 'left' || placement === 'right') {
offsetStyle.width = width;
} else {
offsetStyle.height = height;
}
return offsetStyle;
}
getRcDrawerStyle = () => {
const { zIndex, placement, mask, style } = this.props;
const { push } = this.state;
// 当无 mask 时,将 width 应用到外层容器上
// 解决 https://github.com/ant-design/ant-design/issues/12401 的问题
const offsetStyle = mask ? {} : this.getOffsetStyle();
return {
const Drawer = React.forwardRef<DrawerRef, InternalDrawerProps>(
(
{
width = 256,
height = 256,
closable = true,
placement = 'right' as placementType,
maskClosable = true,
mask = true,
level = null,
keyboard = true,
push = defaultPushState,
closeIcon = <CloseOutlined />,
bodyStyle,
drawerStyle,
prefixCls,
className,
direction,
visible,
children,
zIndex,
transform: push ? this.getPushTransform(placement) : undefined,
...offsetStyle,
...style,
};
};
destroyOnClose,
style,
title,
headerStyle,
onClose,
footer,
footerStyle,
...rest
},
ref,
) => {
const forceUpdate = useForceUpdate();
const [internalPush, setPush] = React.useState(false);
const parentDrawer = React.useContext(DrawerContext);
const destroyClose = React.useRef<boolean>(false);
renderHeader() {
const { title, prefixCls, closable, headerStyle } = this.props;
if (!title && !closable) {
return null;
}
React.useEffect(() => {
// fix: delete drawer in child and re-render, no push started.
// <Drawer>{show && <Drawer />}</Drawer>
if (visible && parentDrawer) {
parentDrawer.push();
}
const headerClassName = title ? `${prefixCls}-header` : `${prefixCls}-header-no-title`;
return (
<div className={headerClassName} style={headerStyle}>
{title && <div className={`${prefixCls}-title`}>{title}</div>}
{closable && this.renderCloseIcon()}
</div>
);
}
return () => {
if (parentDrawer) {
parentDrawer.pull();
// parentDrawer = null;
}
};
}, []);
renderFooter() {
const { footer, footerStyle, prefixCls } = this.props;
if (!footer) {
return null;
}
React.useEffect(() => {
if (parentDrawer) {
if (visible) {
parentDrawer.push();
} else {
parentDrawer.pull();
}
}
}, [visible]);
const footerClassName = `${prefixCls}-footer`;
return (
<div className={footerClassName} style={footerStyle}>
{footer}
</div>
);
}
renderCloseIcon() {
const { closable, closeIcon = <CloseOutlined />, prefixCls, onClose } = this.props;
return (
closable && (
<button
type="button"
onClick={onClose}
aria-label="Close"
className={`${prefixCls}-close`}
style={
{
'--scroll-bar': `${getScrollBarSize()}px`,
} as any
const operations = React.useMemo(
() => ({
push() {
if (push) {
setPush(true);
}
>
{closeIcon}
</button>
)
},
pull() {
if (push) {
setPush(false);
}
},
}),
[push],
);
}
// render drawer body dom
renderBody = () => {
const { bodyStyle, drawerStyle, prefixCls, visible } = this.props;
if (this.destroyClose && !visible) {
return null;
}
this.destroyClose = false;
React.useImperativeHandle(ref, () => operations, [operations]);
const containerStyle: React.CSSProperties = {};
const isDestroyOnClose = destroyOnClose && !visible;
const isDestroyOnClose = this.getDestroyOnClose();
const onDestroyTransitionEnd = () => {
if (!isDestroyOnClose) {
return;
}
if (!visible) {
destroyClose.current = true;
forceUpdate();
}
};
if (isDestroyOnClose) {
// Increase the opacity transition, delete children after closing.
containerStyle.opacity = 0;
containerStyle.transition = 'opacity .3s';
const getOffsetStyle = () => {
// https://github.com/ant-design/ant-design/issues/24287
if (!visible && !mask) {
return {};
}
const offsetStyle: any = {};
if (placement === 'left' || placement === 'right') {
offsetStyle.width = width;
} else {
offsetStyle.height = height;
}
return offsetStyle;
};
const getRcDrawerStyle = () => {
// get drawer push width or height
const getPushTransform = (_placement?: placementType) => {
let distance: number | string;
if (typeof push === 'boolean') {
distance = push ? defaultPushState.distance : 0;
} else {
distance = push!.distance;
}
distance = parseFloat(String(distance || 0));
if (_placement === 'left' || _placement === 'right') {
return `translateX(${_placement === 'left' ? distance : -distance}px)`;
}
if (_placement === 'top' || _placement === 'bottom') {
return `translateY(${_placement === 'top' ? distance : -distance}px)`;
}
};
// 当无 mask 时,将 width 应用到外层容器上
// 解决 https://github.com/ant-design/ant-design/issues/12401 的问题
const offsetStyle = mask ? {} : getOffsetStyle();
return {
zIndex,
transform: internalPush ? getPushTransform(placement) : undefined,
...offsetStyle,
...style,
};
};
function renderCloseIcon() {
return (
closable && (
<button
type="button"
onClick={onClose}
aria-label="Close"
className={`${prefixCls}-close`}
style={
{
'--scroll-bar': `${getScrollBarSize()}px`,
} as any
}
>
{closeIcon}
</button>
)
);
}
return (
<div
className={`${prefixCls}-wrapper-body`}
style={{
...containerStyle,
...drawerStyle,
}}
onTransitionEnd={this.onDestroyTransitionEnd}
>
{this.renderHeader()}
<div className={`${prefixCls}-body`} style={bodyStyle}>
{this.props.children}
function renderHeader() {
if (!title && !closable) {
return null;
}
const headerClassName = title ? `${prefixCls}-header` : `${prefixCls}-header-no-title`;
return (
<div className={headerClassName} style={headerStyle}>
{title && <div className={`${prefixCls}-title`}>{title}</div>}
{closable && renderCloseIcon()}
</div>
{this.renderFooter()}
</div>
);
};
);
}
// render Provider for Multi-level drawer
renderProvider = (value: Drawer) => {
this.parentDrawer = value;
function renderFooter() {
if (!footer) {
return null;
}
const { prefixCls, placement, className, mask, direction, visible, ...rest } = this.props;
const footerClassName = `${prefixCls}-footer`;
return (
<div className={footerClassName} style={footerStyle}>
{footer}
</div>
);
}
// render drawer body dom
const renderBody = () => {
if (destroyClose.current && !visible) {
return null;
}
destroyClose.current = false;
const containerStyle: React.CSSProperties = {};
if (isDestroyOnClose) {
// Increase the opacity transition, delete children after closing.
containerStyle.opacity = 0;
containerStyle.transition = 'opacity .3s';
}
return (
<div
className={`${prefixCls}-wrapper-body`}
style={{
...containerStyle,
...drawerStyle,
}}
onTransitionEnd={onDestroyTransitionEnd}
>
{renderHeader()}
<div className={`${prefixCls}-body`} style={bodyStyle}>
{children}
</div>
{renderFooter()}
</div>
);
};
const drawerClassName = classNames(
{
@@ -286,61 +291,60 @@ class Drawer extends React.Component<InternalDrawerProps, IDrawerState> {
},
className,
);
const offsetStyle = mask ? this.getOffsetStyle() : {};
const offsetStyle = mask ? getOffsetStyle() : {};
return (
<DrawerContext.Provider value={this}>
<DrawerContext.Provider value={operations}>
<RcDrawer
handler={false}
{...omit(rest, [
'zIndex',
'closable',
'closeIcon',
'destroyOnClose',
'drawerStyle',
'headerStyle',
'bodyStyle',
'footerStyle',
'footer',
'title',
'push',
'width',
'height',
])}
{...{
placement,
prefixCls,
maskClosable,
level,
keyboard,
children,
onClose,
...rest,
}}
{...offsetStyle}
prefixCls={prefixCls}
open={visible}
showMask={mask}
placement={placement}
style={this.getRcDrawerStyle()}
style={getRcDrawerStyle()}
className={drawerClassName}
>
{this.renderBody()}
{renderBody()}
</RcDrawer>
</DrawerContext.Provider>
);
};
},
);
render() {
return <DrawerContext.Consumer>{this.renderProvider}</DrawerContext.Consumer>;
}
}
Drawer.displayName = 'Drawer';
const DrawerWrapper: React.FC<DrawerProps> = props => {
const { prefixCls: customizePrefixCls, getContainer: customizeGetContainer } = props;
const { getPopupContainer, getPrefixCls, direction } = React.useContext(ConfigContext);
const DrawerWrapper: React.FC<DrawerProps> = React.forwardRef<DrawerRef, DrawerProps>(
(props, ref) => {
const { prefixCls: customizePrefixCls, getContainer: customizeGetContainer } = props;
const { getPopupContainer, getPrefixCls, direction } = React.useContext(ConfigContext);
const prefixCls = getPrefixCls('drawer', customizePrefixCls);
const getContainer =
// 有可能为 false所以不能直接判断
customizeGetContainer === undefined && getPopupContainer
? () => getPopupContainer(document.body)
: customizeGetContainer;
const prefixCls = getPrefixCls('drawer', customizePrefixCls);
const getContainer =
// 有可能为 false所以不能直接判断
customizeGetContainer === undefined && getPopupContainer
? () => getPopupContainer(document.body)
: customizeGetContainer;
return (
<Drawer {...props} prefixCls={prefixCls} getContainer={getContainer} direction={direction} />
);
};
return (
<Drawer
{...props}
ref={ref}
prefixCls={prefixCls}
getContainer={getContainer}
direction={direction}
/>
);
},
);
DrawerWrapper.displayName = 'DrawerWrapper';

View File

@@ -316,6 +316,8 @@ type Rule = RuleConfig | ((form: FormInstance) => RuleConfig);
| validateTrigger | Set validate trigger event. Must be the sub set of `validateTrigger` in Form.Item | string \| string\[] |
| validator | Customize validation rule. Accept Promise as return. See [example](#components-form-demo-register) | ([rule](#Rule), value) => Promise |
| whitespace | Failed if only has whitespace | boolean |
| defaultField | Validate rule for all array elements, valid when `type` is `array` | [rule](#Rule) |
| fields | Validate rule for child elements, valid when `type` is `array` or `object` | Record<string, [rule](#Rule)> |
## Migrate to v4

View File

@@ -315,6 +315,8 @@ type Rule = RuleConfig | ((form: FormInstance) => RuleConfig);
| validateTrigger | 设置触发验证时机,必须是 Form.Item 的 `validateTrigger` 的子集 | string \| string\[] |
| validator | 自定义校验,接收 Promise 作为返回值。[示例](#components-form-demo-register)参考 | ([rule](#Rule), value) => Promise |
| whitespace | 如果字段仅包含空格则校验不通过 | boolean |
| defaultField | 仅在 `type``array` 类型时有效,用于指定数组元素的校验规则 | [rule](#Rule) |
| fields | 仅在 `type``array``object` 类型时有效,用于指定子元素的校验规则 | Record<string, [rule](#Rule)> |
## 从 v3 升级到 v4

View File

@@ -191,9 +191,7 @@
.@{ant-prefix}-input-textarea-show-count {
&::after {
position: absolute;
bottom: -22px;
width: 100%;
margin-bottom: -22px;
}
}
}

View File

@@ -7,7 +7,7 @@ import * as styleChecker from '../../_util/styleChecker';
jest.mock('../../_util/styleChecker', () => ({
canUseDocElement: () => true,
isStyleSupport: () => true,
isFlexGapSupported: true,
detectFlexGapSupported: () => true,
}));
describe('Grid.Gap', () => {
@@ -20,8 +20,9 @@ describe('Grid.Gap', () => {
expect(wrapper.find('.ant-row').props().style).toEqual(
expect.objectContaining({
'--column-gap': '16px',
'--row-gap': '8px',
marginLeft: -8,
rowGap: 8,
marginRight: -8,
}),
);
});

View File

@@ -2,7 +2,7 @@ import * as React from 'react';
import classNames from 'classnames';
import RowContext from './RowContext';
import { ConfigContext } from '../config-provider';
import { isFlexGapSupported } from '../_util/styleChecker';
import { detectFlexGapSupported } from '../_util/styleChecker';
// https://github.com/ant-design/ant-design/issues/14324
type ColSpanType = number | string;
@@ -103,24 +103,21 @@ const Col = React.forwardRef<HTMLDivElement, ColProps>((props, ref) => {
sizeClassObj,
);
let mergedStyle: React.CSSProperties = { ...style };
if (gutter && !isFlexGapSupported) {
mergedStyle = {
...(gutter[0]! > 0
? {
paddingLeft: gutter[0]! / 2,
paddingRight: gutter[0]! / 2,
}
: {}),
...(gutter[1]! > 0
? {
paddingTop: gutter[1]! / 2,
paddingBottom: gutter[1]! / 2,
}
: {}),
...mergedStyle,
};
const mergedStyle: React.CSSProperties = {};
// Horizontal gutter use padding
if (gutter && gutter[0] > 0) {
const horizontalGutter = gutter[0] / 2;
mergedStyle.paddingLeft = horizontalGutter;
mergedStyle.paddingRight = horizontalGutter;
}
// Vertical gutter use padding when gap not support
if (gutter && gutter[1] > 0 && !detectFlexGapSupported()) {
const verticalGutter = gutter[1] / 2;
mergedStyle.paddingTop = verticalGutter;
mergedStyle.paddingBottom = verticalGutter;
}
if (flex) {
mergedStyle.flex = parseFlex(flex);
@@ -132,7 +129,7 @@ const Col = React.forwardRef<HTMLDivElement, ColProps>((props, ref) => {
}
return (
<div {...others} style={mergedStyle} className={classes} ref={ref}>
<div {...others} style={{ ...mergedStyle, ...style }} className={classes} ref={ref}>
{children}
</div>
);

View File

@@ -8,7 +8,7 @@ import ResponsiveObserve, {
ScreenMap,
responsiveArray,
} from '../_util/responsiveObserve';
import { isFlexGapSupported } from '../_util/styleChecker';
import { detectFlexGapSupported } from '../_util/styleChecker';
const RowAligns = tuple('top', 'middle', 'bottom', 'stretch');
const RowJustify = tuple('start', 'end', 'center', 'space-around', 'space-between');
@@ -95,37 +95,19 @@ const Row = React.forwardRef<HTMLDivElement, RowProps>((props, ref) => {
);
// Add gutter related style
let rowStyle: React.CSSProperties & {
'--column-gap'?: string | number;
'--row-gap'?: string | number;
} = {};
const rowStyle: React.CSSProperties = {};
const horizontalGutter = gutters[0] > 0 ? gutters[0] / -2 : undefined;
const verticalGutter = gutters[1] > 0 ? gutters[1] / -2 : undefined;
if (isFlexGapSupported) {
rowStyle = {
'--column-gap': 0,
'--row-gap': 0,
};
rowStyle.marginLeft = horizontalGutter;
rowStyle.marginRight = horizontalGutter;
if (gutters[0]! > 0) {
const gap = gutters[0];
rowStyle.columnGap = gap;
rowStyle['--column-gap'] = `${gap}px`;
}
if (gutters[1]! > 0) {
const gap = gutters[1];
rowStyle.rowGap = gap;
rowStyle['--row-gap'] = `${gap}px`;
}
if (detectFlexGapSupported()) {
// Set gap direct if flex gap support
[, rowStyle.rowGap] = gutters;
} else {
const horizontalGutter = gutters[0]! > 0 ? gutters[0] / -2 : undefined;
const verticalGutter = gutters[1]! > 0 ? gutters[1] / -2 : undefined;
rowStyle = {
marginLeft: horizontalGutter,
marginRight: horizontalGutter,
marginTop: verticalGutter,
marginBottom: verticalGutter,
};
rowStyle.marginTop = verticalGutter;
rowStyle.marginBottom = verticalGutter;
}
return (

View File

@@ -7,9 +7,7 @@
.@{ant-prefix}-col@{class}-@{index} {
display: block;
flex: 0 0 percentage((@index / @grid-columns));
min-width: 0;
max-width: percentage((@index / @grid-columns));
max-width: calc(percentage((@index / @grid-columns)) - ~'var(--column-gap)');
}
.@{ant-prefix}-col@{class}-push-@{index} {
left: percentage((@index / @grid-columns));

View File

@@ -46,10 +46,11 @@
&-textarea {
&-show-count::after {
display: block;
float: right;
color: @text-color-secondary;
text-align: right;
white-space: nowrap;
content: attr(data-count);
pointer-events: none;
}
}
}

View File

@@ -32,6 +32,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/5FrZKStG_/List.svg
| locale | 默认文案设置,目前包括空数据文案 | object | {emptyText: `暂无数据`} | |
| pagination | 对应的 `pagination` 配置, 设置 false 不显示 | boolean \| object | false | |
| renderItem | 当使用 dataSource 时,可以用 `renderItem` 自定义渲染列表项 | (item) => ReactNode | - | |
| rowKey | 当 `renderItem` 自定义渲染列表项有效时,自定义每一行的 `key` 的获取方式 | ((item: T) => string) | `list-item-${index}` | |
| size | list 的尺寸 | `default` \| `large` \| `small` | `default` | |
| split | 是否展示分割线 | boolean | true | |

View File

@@ -70699,7 +70699,7 @@ exports[`Locale Provider should display the text as fa 1`] = `
<span
class="ant-transfer-list-header-selected"
>
0
0 عدد
</span>
<span
class="ant-transfer-list-header-title"
@@ -70891,7 +70891,7 @@ exports[`Locale Provider should display the text as fa 1`] = `
<span
class="ant-transfer-list-header-selected"
>
0
0 عدد
</span>
<span
class="ant-transfer-list-header-title"
@@ -235109,7 +235109,7 @@ exports[`Locale Provider should display the text as ru 1`] = `
type="button"
>
<span>
Ok
ОК
</span>
</button>
</li>

View File

@@ -13,12 +13,18 @@ const localeValues: Locale = {
DatePicker,
TimePicker,
Calendar,
global: {
placeholder: 'لطفاً انتخاب کنید',
},
Table: {
filterTitle: 'منوی فیلتر',
filterConfirm: 'تایید',
filterReset: 'پاک کردن',
filterEmptyText: 'بدون فیلتر',
emptyText: 'بدون داده',
selectAll: 'انتخاب صفحه‌ی کنونی',
selectInvert: 'معکوس کردن انتخاب‌ها در صفحه ی کنونی',
selectNone: 'انتخاب هیچکدام',
selectionAll: 'انتخاب همه داده‌ها',
sortTitle: 'مرتب سازی',
expand: 'باز شدن ردیف',
@@ -39,8 +45,14 @@ const localeValues: Locale = {
Transfer: {
titles: ['', ''],
searchPlaceholder: 'جستجو',
itemUnit: '',
itemsUnit: '',
itemUnit: 'عدد',
itemsUnit: 'عدد',
remove: 'حذف',
selectCurrent: 'انتخاب صفحه فعلی',
removeCurrent: 'پاک کردن انتخاب‌های صفحه فعلی',
selectAll: 'انتخاب همه',
removeAll: 'پاک کردن همه انتخاب‌ها',
selectInvert: 'معکوس کردن انتخاب‌ها در صفحه ی کنونی',
},
Upload: {
uploading: 'در حال آپلود...',
@@ -57,7 +69,7 @@ const localeValues: Locale = {
},
Text: {
edit: 'ویرایش',
copy: 'کپس',
copy: 'کپی',
copied: 'کپی شد',
expand: 'توسعه',
},
@@ -65,6 +77,7 @@ const localeValues: Locale = {
back: 'برگشت',
},
Form: {
optional: '(اختیاری)',
defaultValidateMessages: {
default: 'خطا در ${label}',
required: 'فیلد ${label} اجباریست',
@@ -104,8 +117,8 @@ const localeValues: Locale = {
},
array: {
len: 'تعداد ${label} باید ${len} باشد.',
min: 'تعداد ${lable} حداقل باید ${min} باشد',
max: 'تعداد ${lable} حداکثر باید ${max} باشد',
min: 'تعداد ${label} حداقل باید ${min} باشد',
max: 'تعداد ${label} حداکثر باید ${max} باشد',
range: 'مقدار ${label} باید بین ${min}-${max} باشد',
},
pattern: {
@@ -113,6 +126,9 @@ const localeValues: Locale = {
},
},
},
Image: {
preview: 'نمایش',
},
};
export default localeValues;

View File

@@ -124,6 +124,9 @@ const localeValues: Locale = {
},
},
},
Image: {
preview: 'Превью',
},
};
export default localeValues;

View File

@@ -67,7 +67,7 @@ Select component to select value from options.
| onBlur | Called when blur | function | - | |
| onChange | Called when select an option or input value change | function(value, option:Option \| Array&lt;Option>) | - | |
| onClear | Called when clear | function | - | 4.6.0 |
| onDeselect | Called when a option is deselected, param is the selected option's value. Only called for `multiple` or `tags`, effective in multiple or tags mode only | function(string \| number \| LabeledValue) | - | |
| onDeselect | Called when an option is deselected, param is the selected option's value. Only called for `multiple` or `tags`, effective in multiple or tags mode only | function(string \| number \| LabeledValue) | - | |
| onDropdownVisibleChange | Called when dropdown open | function(open) | - | |
| onFocus | Called when focus | function | - | |
| onInputKeyDown | Called when key pressed | function | - | |
@@ -75,7 +75,7 @@ Select component to select value from options.
| onMouseLeave | Called when mouse leave | function | - | |
| onPopupScroll | Called when dropdown scrolls | function | - | |
| onSearch | Callback function that is fired when input changed | function(value: string) | - | |
| onSelect | Called when a option is selected, the params are option's value (or key) and option instance | function(string \| number \| LabeledValue, option: Option) | - | |
| onSelect | Called when an option is selected, the params are option's value (or key) and option instance | function(string \| number \| LabeledValue, option: Option) | - | |
> Note, if you find that the drop-down menu scrolls with the page, or you need to trigger Select in other popup layers, please try to use `getPopupContainer={triggerNode => triggerNode.parentElement}` to fix the drop-down popup rendering node in the parent element of the trigger .

View File

@@ -37,6 +37,10 @@
background: @input-disabled-bg;
cursor: not-allowed;
.@{select-prefix-cls}-multiple& {
background: @select-multiple-disabled-background;
}
input {
cursor: not-allowed;
}

View File

@@ -19,7 +19,6 @@ const SliderTooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
rafRef.current = raf(() => {
innerRef.current?.forcePopupAlign();
rafRef.current = null;
keepAlign();
});
}
@@ -31,7 +30,7 @@ const SliderTooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
}
return cancelKeepAlign;
}, [visible]);
}, [visible, props.title]);
return <Tooltip ref={composeRef(innerRef, ref)} {...props} />;
});

View File

@@ -238,9 +238,10 @@ function Table<RecordType extends object = any>(props: TableProps<RecordType>) {
};
/**
* Controlled state in `columns` is not a good idea that makes too many code (1000+ line?) to read
* state out and then put it back to title render. Move these code into `hooks` but still too
* complex. We should provides Table props like `sorter` & `filter` to handle control in next big version.
* Controlled state in `columns` is not a good idea that makes too many code (1000+ line?) to
* read state out and then put it back to title render. Move these code into `hooks` but still
* too complex. We should provides Table props like `sorter` & `filter` to handle control in next
* big version.
*/
// ============================ Sorter =============================
@@ -439,18 +440,19 @@ function Table<RecordType extends object = any>(props: TableProps<RecordType>) {
/>
);
const defaultPosition = direction === 'rtl' ? 'left' : 'right';
if (mergedPagination.position !== null && Array.isArray(mergedPagination.position)) {
const topPos = mergedPagination.position.find(p => p.indexOf('top') !== -1);
const bottomPos = mergedPagination.position.find(p => p.indexOf('bottom') !== -1);
if (!topPos && !bottomPos) {
const { position } = mergedPagination;
if (position !== null && Array.isArray(position)) {
const topPos = position.find(p => p.indexOf('top') !== -1);
const bottomPos = position.find(p => p.indexOf('bottom') !== -1);
const isDisable = position.every(p => `${p}` === 'none');
if (!topPos && !bottomPos && !isDisable) {
bottomPaginationNode = renderPagination(defaultPosition);
} else {
if (topPos) {
topPaginationNode = renderPagination(topPos!.toLowerCase().replace('top', ''));
}
if (bottomPos) {
bottomPaginationNode = renderPagination(bottomPos!.toLowerCase().replace('bottom', ''));
}
}
if (topPos) {
topPaginationNode = renderPagination(topPos!.toLowerCase().replace('top', ''));
}
if (bottomPos) {
bottomPaginationNode = renderPagination(bottomPos!.toLowerCase().replace('bottom', ''));
}
} else {
bottomPaginationNode = renderPagination(defaultPosition);

View File

@@ -22,6 +22,11 @@ describe('Table.pagination', () => {
{ key: 3, name: 'Jerry' },
];
const longData = [];
for (let i = 0; i < 100; i += 1) {
longData.push({ key: i, name: `${i}` });
}
const pagination = { className: 'my-page', pageSize: 2 };
function createTable(props) {
@@ -192,7 +197,7 @@ describe('Table.pagination', () => {
});
// https://github.com/ant-design/ant-design/issues/24913
it('should onChange called when pageSize change', () => {
it('should called onChange when pageSize change', () => {
const onChange = jest.fn();
const onShowSizeChange = jest.fn();
const wrapper = mount(
@@ -223,6 +228,91 @@ describe('Table.pagination', () => {
);
});
// https://github.com/ant-design/ant-design/issues/29175
it('should change page to max page count when pageSize change without pagination.total', () => {
const onChange = jest.fn();
const onShowSizeChange = jest.fn();
const wrapper = mount(
createTable({
pagination: {
current: 10,
pageSize: 10,
onChange,
onShowSizeChange,
},
dataSource: longData,
}),
);
wrapper.find('.ant-select-selector').simulate('mousedown');
expect(wrapper.find('.ant-select-item-option').length).toBe(4);
wrapper.find('.ant-select-item-option').at(1).simulate('click');
const newPageSize = parseInt(wrapper.find('.ant-select-item-option').at(1).text(), 10);
expect(onChange).toHaveBeenCalledWith(longData.length / newPageSize, 20);
});
it('should change page to max page count when pageSize change with pagination.total', () => {
const onChange = jest.fn();
const onShowSizeChange = jest.fn();
const total = 20000;
const wrapper = mount(
createTable({
pagination: {
current: total / 10,
pageSize: 10,
onChange,
total,
onShowSizeChange,
},
dataSource: longData,
}),
);
wrapper.find('.ant-select-selector').simulate('mousedown');
expect(wrapper.find('.ant-select-item-option').length).toBe(4);
wrapper.find('.ant-select-item-option').at(1).simulate('click');
const newPageSize = parseInt(wrapper.find('.ant-select-item-option').at(1).text(), 10);
expect(onChange).toHaveBeenCalledWith(total / newPageSize, 20);
});
// https://github.com/ant-design/ant-design/issues/29175
it('should not change page to max page if current is not greater max page when pageSize change', () => {
const onChange = jest.fn();
const onShowSizeChange = jest.fn();
const wrapper = mount(
createTable({
pagination: {
current: 4,
pageSize: 10,
onChange,
onShowSizeChange,
},
dataSource: longData,
}),
);
wrapper.find('.ant-select-selector').simulate('mousedown');
expect(wrapper.find('.ant-select-item-option').length).toBe(4);
wrapper.find('.ant-select-item-option').at(1).simulate('click');
expect(onChange).toHaveBeenCalledWith(4, 20);
});
it('should reset current to max page when data length is cut', () => {
const onChange = jest.fn();
const wrapper = mount(
createTable({
pagination: {
current: 10,
pageSize: 10,
onChange,
},
dataSource: longData,
}),
);
expect(wrapper.find('.ant-pagination-item-active').text()).toBe('10');
wrapper.setProps({
dataSource: longData.filter(item => item.key < 60),
});
expect(wrapper.find('.ant-pagination-item-active').text()).toBe('6');
});
it('specify the position of pagination', () => {
const wrapper = mount(createTable({ pagination: { position: ['topLeft'] } }));
expect(wrapper.find('.ant-spin-container').children()).toHaveLength(2);
@@ -234,13 +324,17 @@ describe('Table.pagination', () => {
expect(wrapper.find('.ant-spin-container').children()).toHaveLength(3);
expect(wrapper.find('.ant-spin-container').childAt(0).find('.ant-pagination')).toHaveLength(1);
expect(wrapper.find('.ant-spin-container').childAt(2).find('.ant-pagination')).toHaveLength(1);
wrapper.setProps({ pagination: { position: ['none', 'none'] } });
expect(wrapper.find('.ant-pagination')).toHaveLength(0);
wrapper.setProps({ pagination: { position: ['invalid'] } });
expect(wrapper.find('.ant-pagination')).toHaveLength(1);
wrapper.setProps({ pagination: { position: ['invalid', 'invalid'] } });
expect(wrapper.find('.ant-pagination')).toHaveLength(1);
});
/**
* `pagination` is not designed to accept `true` value, but in practice, many people assign `true`
* to `pagination`, since they misunderstand that `pagination` can accept a boolean value.
* `pagination` is not designed to accept `true` value, but in practice, many people assign
* `true` to `pagination`, since they misunderstand that `pagination` can accept a boolean value.
*/
it('Accepts pagination as true', () => {
const wrapper = mount(createTable({ pagination: true }));

View File

@@ -68,12 +68,10 @@ export default function usePagination(
},
);
if (!paginationTotal) {
// Reset `current` if data length changed. Only reset when paginationObj do not have total
const maxPage = Math.ceil(total / mergedPagination.pageSize!);
if (maxPage < mergedPagination.current!) {
mergedPagination.current = 1;
}
// Reset `current` if data length or pageSize changed
const maxPage = Math.ceil((paginationTotal || total) / mergedPagination.pageSize!);
if (mergedPagination.current! > maxPage) {
mergedPagination.current = maxPage;
}
const refreshPagination = (current: number = 1, pageSize?: number) => {
@@ -84,14 +82,11 @@ export default function usePagination(
};
const onInternalChange: PaginationProps['onChange'] = (current, pageSize) => {
const paginationPageSize = mergedPagination?.pageSize;
if (pageSize && pageSize !== paginationPageSize) {
current = 1;
if (pagination) {
pagination.onChange?.(current, pageSize);
}
if (pagination && pagination.onChange) pagination.onChange(current, pageSize);
refreshPagination(current, pageSize);
onChange(current, pageSize || paginationPageSize!);
onChange(current, pageSize || mergedPagination?.pageSize!);
};
if (pagination === false) {

View File

@@ -157,7 +157,7 @@ Properties for pagination.
| Property | Description | Type | Default |
| --- | --- | --- | --- |
| position | Specify the position of `Pagination`, could be `topLeft` \| `topCenter` \| `topRight` \|`bottomLeft` \| `bottomCenter` \| `bottomRight` | Array | \[`bottomRight`] |
| position | Specify the position of `Pagination`, could be`topLeft` \| `topCenter` \| `topRight` \|`bottomLeft` \| `bottomCenter` \| `bottomRight` | Array | \[`bottomRight`] |
More about pagination, please check [`Pagination`](/components/pagination/).

View File

@@ -76,7 +76,7 @@ export interface FilterDropdownProps {
prefixCls: string;
setSelectedKeys: (selectedKeys: React.Key[]) => void;
selectedKeys: React.Key[];
confirm: (param: FilterConfirmProps) => void;
confirm: (param?: FilterConfirmProps) => void;
clearFilters?: () => void;
filters?: ColumnFilterItem[];
visible: boolean;

View File

@@ -416,9 +416,8 @@
display: inline-flex;
float: left;
box-sizing: border-box;
width: ceil(((@font-size-sm * 1.4 - @border-width-base * 3) / 2)) * 2 + @border-width-base * 3;
height: ceil(((@font-size-sm * 1.4 - @border-width-base * 3) / 2)) * 2 + @border-width-base * 3;
width: @expand-icon-size;
height: @expand-icon-size;
padding: 0;
color: inherit;
line-height: ceil(((@font-size-sm * 1.4 - @border-width-base * 3) / 2)) * 2 + @border-width-base *
@@ -427,8 +426,12 @@
border: @border-width-base @border-style-base @table-border-color;
border-radius: @border-radius-base;
outline: none;
transform: scale((unit(@checkbox-size) / unit(@expand-icon-size)));
transform-origin: bottom;
transition: all 0.3s;
user-select: none;
@expand-icon-size: ceil(((@font-size-sm * 1.4 - @border-width-base * 3) / 2)) * 2 +
@border-width-base * 3;
&:focus,
&:hover,

View File

@@ -2,6 +2,7 @@ import { TimePickerLocale } from '../index';
const locale: TimePickerLocale = {
placeholder: 'انتخاب زمان',
rangePlaceholder: ['زمان شروع', 'زمان پایان'],
};
export default locale;

View File

@@ -68,7 +68,7 @@ exports[`renders ./components/typography/demo/basic.md correctly 1`] = `
<li>
<a
class="ant-typography"
href="/docs/pattern/navigation"
href="/docs/spec/overview"
>
Patterns
</a>
@@ -76,7 +76,7 @@ exports[`renders ./components/typography/demo/basic.md correctly 1`] = `
<li>
<a
class="ant-typography"
href="/docs/resource/download"
href="/docs/resources"
>
Resource Download
</a>
@@ -164,7 +164,7 @@ exports[`renders ./components/typography/demo/basic.md correctly 1`] = `
<li>
<a
class="ant-typography"
href="/docs/spec/proximity"
href="/docs/spec/proximity-cn"
>
设计原则
</a>
@@ -172,7 +172,7 @@ exports[`renders ./components/typography/demo/basic.md correctly 1`] = `
<li>
<a
class="ant-typography"
href="/docs/pattern/navigation"
href="/docs/spec/overview-cn"
>
设计模式
</a>
@@ -180,7 +180,7 @@ exports[`renders ./components/typography/demo/basic.md correctly 1`] = `
<li>
<a
class="ant-typography"
href="/docs/resource/download"
href="/docs/resources-cn"
>
设计资源
</a>

View File

@@ -51,10 +51,10 @@ ReactDOM.render(
<Link href="/docs/spec/proximity">Principles</Link>
</li>
<li>
<Link href="/docs/pattern/navigation">Patterns</Link>
<Link href="/docs/spec/overview">Patterns</Link>
</li>
<li>
<Link href="/docs/resource/download">Resource Download</Link>
<Link href="/docs/resources">Resource Download</Link>
</li>
</ul>
</Paragraph>
@@ -84,13 +84,13 @@ ReactDOM.render(
<Paragraph>
<ul>
<li>
<Link href="/docs/spec/proximity">设计原则</Link>
<Link href="/docs/spec/proximity-cn">设计原则</Link>
</li>
<li>
<Link href="/docs/pattern/navigation">设计模式</Link>
<Link href="/docs/spec/overview-cn">设计模式</Link>
</li>
<li>
<Link href="/docs/resource/download">设计资源</Link>
<Link href="/docs/resources-cn">设计资源</Link>
</li>
</ul>
</Paragraph>

View File

@@ -49,7 +49,7 @@ antd use shallow compare of props to optimize performance. You should always pas
### After I set the `value` of an `Input`/`Select`(etc.) component, the value cannot be changed by user's action.
Try `defaultValue` or `onChange` to change `value`, and please read [React's documentation](https://facebook.github.io/react/docs/forms.html#controlled-components).
Try `onChange` to change `value`, and please read [React's documentation](https://reactjs.org/docs/forms.html#controlled-components).
### Components are not vertically aligned when placed in single row.
@@ -59,7 +59,7 @@ Try [Space](https://ant.design/components/space/) component to make them aligned
Yes, antd is designed to help you develop a complete background application. To do so, we override some global styles for styling convenience, and currently these cannot be removed or changed. More info at https://github.com/ant-design/ant-design/issues/4331 .
Alternatively, follow the instructions in [How to avoid modifying global styles?](docs/react/customize-theme#How-to-avoid-modifying-global-styles-?)
Alternatively, follow the instructions in [How to avoid modifying global styles?](/docs/react/customize-theme#How-to-avoid-modifying-global-styles)
### I cannot install `antd` and `antd`'s dependencies in mainland China.
@@ -116,7 +116,7 @@ Or you can simply upgrade to [antd@4.0](https://github.com/ant-design/ant-design
Static methods like message/notification/Modal.confirm are not using the same render tree as `<Button />`, but rendered to indepent DOM node created by `ReactDOM.render`, which cannot access React context from ConfigProvider. Consider two solutions here:
1. Replace original usages with [message.useMessage](https://ant.design/components/message/#components-message-demo-hooks), [notification.useNotification](https://ant.design/components/notification/#Why-I-can-not-access-context,-redux-in-notification) and [Modal.useModal](https://ant.design/components/modal/#Why-I-can-not-access-context,-redux-in-Modal.xxx).
1. Replace original usages with [message.useMessage](/components/message/#components-message-demo-hooks), [notification.useNotification](/components/notification/#Why-I-can-not-access-context,-redux,-ConfigProvider-locale/prefixCls-in-notification) and [Modal.useModal](/components/modal/#Why-I-can-not-access-context,-redux,-ConfigProvider-locale/prefixCls-in-Modal.xxx).
2. Use `message.config`, `notification.config` and `Modal.config` to config `prefixCls` globally.

View File

@@ -45,11 +45,11 @@ https://ant.design/components/select/#Select-props
### 为什么修改组件传入的对象或数组属性组件不会更新?
antd 内部会对 props 进行浅比较实现性能优化。当状态变更,你总是应该传递一个新的对象。具体请参考[React 的文档](https://reactjs.org/docs/thinking-in-react.html)
antd 内部会对 props 进行浅比较实现性能优化。当状态变更,你总是应该传递一个新的对象。具体请参考 [React 的文档](https://reactjs.org/docs/thinking-in-react.html)
### 当我设置了 `Input`/`Select` 等的 `value` 时它就无法修改了。
尝试使用 `defaultValue``onChange` 来改变 `value`,请参考 [React 的文档](https://reactjs.org/docs/forms.html#controlled-components)。
尝试使用 `onChange` 来改变 `value`,请参考 [React 的文档](https://reactjs.org/docs/forms.html#controlled-components)。
### 多个组件放一排时没有垂直对齐怎么办?
@@ -57,7 +57,7 @@ antd 内部会对 props 进行浅比较实现性能优化。当状态变更,
### antd 覆盖了我的全局样式!
是的antd 在设计的时候就是用来开发一个完整的应用的,为了方便,我们覆盖了一些全局样式,现在还不能移除,想要了解更多请追踪这个 issuehttps://github.com/ant-design/ant-design/issues/4331 ,或者参考这个教程 [How to avoid modifying global styles?](docs/react/customize-theme#How-to-avoid-modifying-global-styles-?)
是的antd 在设计的时候就是用来开发一个完整的应用的,为了方便,我们覆盖了一些全局样式,现在还不能移除,想要了解更多请追踪 [这个 issue](https://github.com/ant-design/ant-design/issues/4331),或者参考这个教程 [How to avoid modifying global styles?](/docs/react/customize-theme#How-to-avoid-modifying-global-styles)
### 我没法安装 `antd` 和 `antd` 的依赖,顺便提一句,我在中国大陆。
@@ -116,7 +116,7 @@ antd 内部会对 props 进行浅比较实现性能优化。当状态变更,
- 重现链接https://codesandbox.io/s/dank-brook-v1csy
- 相同 issue[#15572](https://github.com/ant-design/ant-design/issues/15572)、[#16436](https://github.com/ant-design/ant-design/issues/16436)、[#11938](https://github.com/ant-design/ant-design/issues/11938)、[#11735](https://github.com/ant-design/ant-design/issues/11735)、[#11586](https://github.com/ant-design/ant-design/issues/11586)、[#10425](https://github.com/ant-design/ant-design/issues/10425)、[#11053](https://github.com/ant-design/ant-design/issues/11053)
就像[这个回复](https://github.com/ant-design/ant-design/issues/15572#issuecomment-475476135)里解释的一样,这是因为 `<DatePicker mode="year" />` 不等于 `YearPicker``<RangePicker mode="month" />` 不等于 `MonthRangePicker``mode` 属性是在 antd 3.0 时,为了控制面板展现状态而添加的属性,以支持[展示时间面板](https://github.com/ant-design/ant-design/issues/5190)等需求而添加的。`mode` 只会简单的改变当前显示的面板,不会修改默认的交互行为(比如 DatePicker 依然是点击日才会完成选择并关闭面板)。
就像 [这个回复](https://github.com/ant-design/ant-design/issues/15572#issuecomment-475476135) 里解释的一样,这是因为 `<DatePicker mode="year" />` 不等于 `YearPicker``<RangePicker mode="month" />` 不等于 `MonthRangePicker``mode` 属性是在 antd 3.0 时,为了控制面板展现状态而添加的属性,以支持[展示时间面板](https://github.com/ant-design/ant-design/issues/5190)等需求而添加的。`mode` 只会简单的改变当前显示的面板,不会修改默认的交互行为(比如 DatePicker 依然是点击日才会完成选择并关闭面板)。
同样的,`disabledDate` 对于任何 `<DatePicker />` 也只会针对**日面板**生效,[并不会对 `<DatePicker mode="year/month" />` 上的年/月面板生效](https://github.com/ant-design/ant-design/issues/9008#issuecomment-358554118)。
@@ -130,7 +130,7 @@ antd 内部会对 props 进行浅比较实现性能优化。当状态变更,
message/notification/Modal.confirm 等静态方法不同于 `<Button />` 的渲染方式,是单独渲染在 `ReactDOM.render` 生成的 DOM 树节点上,无法共享 ConfigProvider 提供的 context 信息。你有两种解决方式:
1. 使用官方提供的 [message.useMessage](<[message.useMessage](https://ant.design/components/message-cn/#components-message-demo-hooks)>)、[notification.useNotification](https://ant.design/components/notification-cn/#%E4%B8%BA%E4%BB%80%E4%B9%88-notification-%E4%B8%8D%E8%83%BD%E8%8E%B7%E5%8F%96-context%E3%80%81redux-%E7%9A%84%E5%86%85%E5%AE%B9%EF%BC%9F) 和 [Modal.useModal](https://ant.design/components/modal-cn/#%E4%B8%BA%E4%BB%80%E4%B9%88-Modal-%E6%96%B9%E6%B3%95%E4%B8%8D%E8%83%BD%E8%8E%B7%E5%8F%96-context%E3%80%81redux-%E7%9A%84%E5%86%85%E5%AE%B9%EF%BC%9F) 来调用这些方法。
1. 使用官方提供的 [message.useMessage](/components/message-cn/#components-message-demo-hooks)、[notification.useNotification](/components/notification-cn/#%E4%B8%BA%E4%BB%80%E4%B9%88-notification-%E4%B8%8D%E8%83%BD%E8%8E%B7%E5%8F%96-context%E3%80%81redux-%E7%9A%84%E5%86%85%E5%AE%B9%E5%92%8C-ConfigProvider-%E7%9A%84-locale/prefixCls-%E9%85%8D%E7%BD%AE%EF%BC%9F) 和 [Modal.useModal](/components/modal-cn/#%E4%B8%BA%E4%BB%80%E4%B9%88-Modal-%E6%96%B9%E6%B3%95%E4%B8%8D%E8%83%BD%E8%8E%B7%E5%8F%96-context%E3%80%81redux%E3%80%81%E7%9A%84%E5%86%85%E5%AE%B9%E5%92%8C-ConfigProvider-locale/prefixCls-%E9%85%8D%E7%BD%AE%EF%BC%9F) 来调用这些方法。
2. 使用 `message.config``notification.config``Modal.config` 方法全局设置 `prefixCls`

View File

@@ -21,7 +21,7 @@ Please find below some of the design resources and tools about Ant Design that w
- Mobile Components
- https://gw.alipayobjects.com/zos/basement_prod/c0c3852c-d245-4330-886b-cb02ef49eb6d.svg
- Sketch Symbols File for Mobile
- http://p.tb.cn/rmsportal_3436_AntDesignMobile_20Template_20V1.0.sketch
- https://gw.alipayobjects.com/os/bmw-prod/d6266aef-25b7-4892-b275-ce214121831c.sketch
- Ant Design Pro
- https://gw.alipayobjects.com/zos/basement_prod/5edc7f4d-3302-4710-963b-7b6c77ea8d06.svg
- Common Templates and Pages

View File

@@ -21,7 +21,7 @@ toc: false
- Mobile Components
- https://gw.alipayobjects.com/zos/basement_prod/c0c3852c-d245-4330-886b-cb02ef49eb6d.svg
- 移动组件 Sketch 模板
- http://p.tb.cn/rmsportal_3436_AntDesignMobile_20Template_20V1.0.sketch
- https://gw.alipayobjects.com/os/bmw-prod/d6266aef-25b7-4892-b275-ce214121831c.sketch
- Ant Design Pro
- https://gw.alipayobjects.com/zos/basement_prod/5edc7f4d-3302-4710-963b-7b6c77ea8d06.svg
- 典型页面 + 通用业务模板

View File

@@ -40,7 +40,7 @@ ReactDOM.render(<Palette color={{ name: 'gray', count: 13 }} direction="horizont
### Data Visualization Color Palette
Data visualization color palette is based on the basic color palette and neutral color palette, and based on the principle that AntV's "effective, clear, accurate and beautiful". [View Palette](https://antv.vision/en/docs/specification/principles/visual)
Data visualization color palette is based on the basic color palette and neutral color palette, and based on the principle that AntV's "effective, clear, accurate and beautiful". [View Palette](https://antv.vision/en/docs/specification/language/palette)
### Palette Generation Tool

View File

@@ -48,7 +48,7 @@ ReactDOM.render(<Palette color={{ name: 'gray', count: 13 }} direction="horizont
### 数据可视化色板
数据可视化色板是在基础色板以及中性色板的基础上,融合 AntV 「有效、清晰、准确、美」的原则产生的。[查看色板](https://antv.vision/zh/docs/specification/principles/basic/)
数据可视化色板是在基础色板以及中性色板的基础上,融合 AntV 「有效、清晰、准确、美」的原则产生的。[查看色板](https://antv.vision/zh/docs/specification/language/palette)
### 色板生成工具

View File

@@ -6,7 +6,7 @@ title: 概览
> 这是一份动态更新的设计文档,你的阅读和反馈是我们前进的动力。
秉承 [Ant Design 设计价值观](/docs/spec/values),针对企业级产品反复出现的设计问题,设计模式给出一般性的解决方案,实现跨应用交互一致性的有效融合。依照设计模式使用 [antd 组件](/docs/react/introduce)设计界面,既减少了不必要的认知成本,又能够提升交互确定性和设计的效率。考虑到需要适应各种独特的业务场景,模式的规则具有一定的灵活性,变不离宗,通过了解设计模式的构建逻辑,可以衍生出更具场景特性的解决方案。设计模式包含以下内容:
秉承 [Ant Design 设计价值观](/docs/spec/values),针对企业级产品反复出现的设计问题,设计模式给出一般性的解决方案,实现跨应用交互一致性的有效融合。依照设计模式使用 [antd 组件](/docs/react/introduce)设计界面,既减少了不必要的认知成本,又能够提升交互确定性和设计的效率。考虑到需要适应各种独特的业务场景,模式的规则具有一定的灵活性,变不离宗,通过了解设计模式的构建逻辑,可以衍生出更具场景特性的解决方案。设计模式包含以下内容:
### 原则

View File

@@ -1,6 +1,6 @@
{
"name": "antd",
"version": "4.12.0",
"version": "4.12.3",
"description": "An enterprise-class UI design language and React components implementation",
"title": "Ant Design",
"keywords": [
@@ -109,8 +109,8 @@
"ie >= 11"
],
"dependencies": {
"@ant-design/colors": "^5.0.0",
"@ant-design/icons": "^4.4.0",
"@ant-design/colors": "^6.0.0",
"@ant-design/icons": "^4.5.0",
"@ant-design/react-slick": "~0.28.1",
"@babel/runtime": "^7.12.5",
"array-tree-filter": "^2.1.0",

View File

@@ -0,0 +1,59 @@
const chalk = require('chalk');
const fs = require('fs');
const { join } = require('path');
const moment = require('moment');
const getChangelogByVersion = (content, version) => {
const lines = content.split('\n');
const changeLog = [];
const startPattern = new RegExp(`^## ${version}`);
const stopPattern = /^## /; // 前一个版本
let begin = false;
for (let i = 0; i < lines.length; i += 1) {
const line = lines[i];
if (begin && stopPattern.test(line)) {
break;
}
if (begin && line) {
changeLog.push(line);
}
if (!begin) {
begin = startPattern.test(line);
}
}
return changeLog.join('\n');
};
// eslint-disable-next-line import/no-dynamic-require
const packageJson = require(join(__dirname, '..', 'package.json'));
const { version } = packageJson;
const changeLogContent = fs.readFileSync(join(__dirname, '..', 'CHANGELOG.en-US.md')).toString();
const changeLog = getChangelogByVersion(changeLogContent, version);
if (!changeLog) {
console.log('\n');
console.log(chalk.red('[check-version-md]: No changelog found for the version to be released'));
console.log('\n');
process.exit(1);
}
if (changeLog) {
const text = changeLog.split('\n')[0];
if (text.trim().startsWith('`') && text.trim().endsWith('`')) {
const date = moment(text.trim().replace('`', '').replace('`', ''));
if (date.isBetween(moment().add(-2, 'day'), moment().add(2, 'day'))) {
console.log('\n');
console.log(chalk.blue('[check-version-md]: Check Passed'));
console.log('\n');
process.exit(0);
return;
}
}
console.log('\n');
console.log(chalk.red('[check-version-md]: The date wrongly written'));
console.log('\n');
process.exit(1);
}

View File

@@ -3,6 +3,9 @@
echo "[CLEAN] clean"
npm run clean
echo "[TEST ALL] test changlog"
node ./scripts/check-version-md.js
echo "[TEST ALL] check-commit"
npm run check-commit

View File

@@ -124,6 +124,12 @@
object-fit: cover;
background: #d8d8d8;
border-radius: 100%;
cursor: pointer;
transition: box-shadow 0.3s;
&:hover {
box-shadow: @shadow-2;
}
}
}
}