From 117495e28f96b09e2cdc274a5197207a8f233137 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=81=8F=E5=8F=B3?= Date: Wed, 8 Jan 2020 16:31:25 +0800 Subject: [PATCH 01/19] :bug: Fix .iconfont-size-under-12px not working (#20765) Fix InputNumber and Other components icon size close #20752 --- components/pagination/style/index.less | 3 +-- components/style/mixins/iconfont.less | 5 ++--- components/table/style/index.less | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/components/pagination/style/index.less b/components/pagination/style/index.less index 43a1723228..56c7f43461 100644 --- a/components/pagination/style/index.less +++ b/components/pagination/style/index.less @@ -110,9 +110,8 @@ position: relative; .@{pagination-prefix-cls}-item-link-icon { - .iconfont-size-under-12px(12px); - color: @primary-color; + font-size: @font-size-sm; letter-spacing: -1px; opacity: 0; transition: all 0.2s; diff --git a/components/style/mixins/iconfont.less b/components/style/mixins/iconfont.less index 413591b371..9718535184 100644 --- a/components/style/mixins/iconfont.less +++ b/components/style/mixins/iconfont.less @@ -29,8 +29,7 @@ // for iconfont font size // fix chrome 12px bug -.iconfont-size-under-12px(@size, @rotate: 0deg) { +.iconfont-size-under-12px(@size) { display: inline-block; - @font-scale: unit(@size / 12px); - font-size: 12px; + font-size: @size; } diff --git a/components/table/style/index.less b/components/table/style/index.less index 5b29196fdc..64386a9de7 100644 --- a/components/table/style/index.less +++ b/components/table/style/index.less @@ -248,7 +248,7 @@ } &-up + &-down { - margin-top: -0.42em; + margin-top: -0.3em; } } From 37b61c1adae5fa3aee96f39ceda765dd79349b0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=81=8F=E5=8F=B3?= Date: Wed, 8 Jan 2020 17:14:29 +0800 Subject: [PATCH 02/19] :bug: Fix Grid initial gutter (#20762) like SSR situation --- components/_util/responsiveObserve.ts | 5 +++-- components/descriptions/index.tsx | 6 +++--- .../grid/__tests__/__snapshots__/demo.test.js.snap | 10 +++++----- components/grid/row.tsx | 13 ++++++++++--- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/components/_util/responsiveObserve.ts b/components/_util/responsiveObserve.ts index e017c802a7..f0318eb409 100644 --- a/components/_util/responsiveObserve.ts +++ b/components/_util/responsiveObserve.ts @@ -1,5 +1,6 @@ export type Breakpoint = 'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs'; export type BreakpointMap = Partial>; +export type ScreenMap = Partial>; export const responsiveArray: Breakpoint[] = ['xxl', 'xl', 'lg', 'md', 'sm', 'xs']; @@ -12,7 +13,7 @@ export const responsiveMap: BreakpointMap = { xxl: '(min-width: 1600px)', }; -type SubscribeFunc = (screens: BreakpointMap) => void; +type SubscribeFunc = (screens: ScreenMap) => void; let subscribers: Array<{ token: string; @@ -23,7 +24,7 @@ let screens = {}; const responsiveObserve = { matchHandlers: {}, - dispatch(pointMap: BreakpointMap) { + dispatch(pointMap: ScreenMap) { screens = pointMap; if (subscribers.length < 1) { return false; diff --git a/components/descriptions/index.tsx b/components/descriptions/index.tsx index beae4c8adb..db339983a1 100644 --- a/components/descriptions/index.tsx +++ b/components/descriptions/index.tsx @@ -4,7 +4,7 @@ import toArray from 'rc-util/lib/Children/toArray'; import warning from '../_util/warning'; import ResponsiveObserve, { Breakpoint, - BreakpointMap, + ScreenMap, responsiveArray, } from '../_util/responsiveObserve'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; @@ -168,7 +168,7 @@ const defaultColumnMap = { class Descriptions extends React.Component< DescriptionsProps, { - screens: BreakpointMap; + screens: ScreenMap; } > { static defaultProps: DescriptionsProps = { @@ -179,7 +179,7 @@ class Descriptions extends React.Component< static Item: typeof DescriptionsItem = DescriptionsItem; state: { - screens: BreakpointMap; + screens: ScreenMap; } = { screens: {}, }; diff --git a/components/grid/__tests__/__snapshots__/demo.test.js.snap b/components/grid/__tests__/__snapshots__/demo.test.js.snap index 37eb045530..9c071ced42 100644 --- a/components/grid/__tests__/__snapshots__/demo.test.js.snap +++ b/components/grid/__tests__/__snapshots__/demo.test.js.snap @@ -487,11 +487,11 @@ exports[`renders ./components/grid/demo/gutter.md correctly 1`] = `
{ } export interface RowState { - screens: BreakpointMap; + screens: ScreenMap; } export default class Row extends React.Component { @@ -30,7 +30,14 @@ export default class Row extends React.Component { }; state: RowState = { - screens: {}, + screens: { + xs: true, + sm: true, + md: true, + lg: true, + xl: true, + xxl: true, + }, }; token: string; From 563f46b1302a399bd9293dcc96f586f843ab8516 Mon Sep 17 00:00:00 2001 From: zouxiaomingya <41714119+zouxiaomingya@users.noreply.github.com> Date: Wed, 8 Jan 2020 19:21:23 +0800 Subject: [PATCH 03/19] feat: update article length (#20767) --- components/typography/__tests__/__snapshots__/demo.test.js.snap | 2 +- components/typography/demo/suffix.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/typography/__tests__/__snapshots__/demo.test.js.snap b/components/typography/__tests__/__snapshots__/demo.test.js.snap index cb94c16bce..fafeb355cb 100644 --- a/components/typography/__tests__/__snapshots__/demo.test.js.snap +++ b/components/typography/__tests__/__snapshots__/demo.test.js.snap @@ -580,7 +580,7 @@ exports[`renders ./components/typography/demo/suffix.md correctly 1`] = `
- To be, or not to be, that is a question: Whether it is nobler in the mind to suffer. The slings and arrows of outrageous fortune--William Shakespeare + To be, or not to be, that is a question: Whether it is nobler in the mind to suffer. The slings and arrows of outrageous fortune Or to take arms against a sea of troubles, And by opposing end them? To die: to sleep; No more; and by a sleep to say we end The heart-ache and the thousand natural shocks That flesh is heir to, 'tis a consummation Devoutly to be wish'd. To die, to sleep To sleep- perchance to dream: ay, there's the rub! For in that sleep of death what dreams may come When we have shuffled off this mortal coil, Must give us pause. There 's the respect That makes calamity of so long life--William Shakespeare
`; diff --git a/components/typography/demo/suffix.md b/components/typography/demo/suffix.md index 8a512a5a4a..e3c251dcb2 100644 --- a/components/typography/demo/suffix.md +++ b/components/typography/demo/suffix.md @@ -30,7 +30,7 @@ class Demo extends React.Component { render() { const { rows } = this.state; const article = - 'To be, or not to be, that is a question: Whether it is nobler in the mind to suffer. The slings and arrows of outrageous fortune'; + "To be, or not to be, that is a question: Whether it is nobler in the mind to suffer. The slings and arrows of outrageous fortune Or to take arms against a sea of troubles, And by opposing end them? To die: to sleep; No more; and by a sleep to say we end The heart-ache and the thousand natural shocks That flesh is heir to, 'tis a consummation Devoutly to be wish'd. To die, to sleep To sleep- perchance to dream: ay, there's the rub! For in that sleep of death what dreams may come When we have shuffled off this mortal coil, Must give us pause. There 's the respect That makes calamity of so long life"; return (
From 313c8f9a3343989aef42faf8fd8e8dfd401a29d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E6=9C=BA=E5=99=A8=E4=BA=BA?= Date: Wed, 8 Jan 2020 23:01:15 +0800 Subject: [PATCH 04/19] chore: Add log generate (#20777) * chore: Add log generate * add author support * fix: only one author --- package.json | 1 + scripts/print-changelog.js | 164 +++++++++++++++++++++++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 scripts/print-changelog.js diff --git a/package.json b/package.json index 58b1bed435..398abc359e 100644 --- a/package.json +++ b/package.json @@ -196,6 +196,7 @@ "immutability-helper": "^3.0.0", "intersection-observer": "^0.7.0", "jest": "^24.8.0", + "jquery": "^3.4.1", "jsdom": "^15.1.1", "jsonml.js": "^0.1.0", "less-vars-to-js": "^1.3.0", diff --git a/scripts/print-changelog.js b/scripts/print-changelog.js new file mode 100644 index 0000000000..510bb000fa --- /dev/null +++ b/scripts/print-changelog.js @@ -0,0 +1,164 @@ +/* eslint-disable no-await-in-loop */ +const chalk = require('chalk'); +const jsdom = require('jsdom'); +const jQuery = require('jquery'); +const fetch = require('node-fetch'); +const simpleGit = require('simple-git/promise'); + +const { JSDOM } = jsdom; +const { window } = new JSDOM(); +const { document } = new JSDOM('').window; +global.document = document; + +const $ = jQuery(window); + +const QUERY_TITLE = '.gh-header-title .js-issue-title'; +const QUERY_DESCRIPTION_LINES = '.comment-body table tbody tr'; +const QUERY_AUTHOR = '.timeline-comment-header-text .author:first'; +const MAINTAINERS = ['zombiej', 'afc163', 'chenshuai2144']; + +const fromVersion = process.argv[process.argv.length - 2]; +const toVersion = process.argv[process.argv.length - 1]; +const cwd = process.cwd(); +const git = simpleGit(cwd); + +function getDescription(row = '') { + return row + .trim() + .replace('🇺🇸 English', '') + .replace('🇨🇳 Chinese', '') + .trim(); +} + +async function printLog() { + if (!/\d+\.\d+\.\d+/.test(fromVersion)) { + console.log( + chalk.red( + '🤪 Not pass validate tags. Please execute like `print-changelog.js 3.26.0 master` instead.', + ), + ); + } + + const logs = await git.log({ from: fromVersion, to: toVersion }); + + let prList = []; + + for (let i = 0; i < logs.all.length; i += 1) { + const { message, body, hash } = logs.all[i]; + + const text = `${message} ${body}`; + + const match = text.match(/#\d+/g); + const prs = (match || []).map(pr => pr.slice(1)); + const validatePRs = []; + + console.log( + `[${i + 1}/${logs.all.length}]`, + hash.slice(0, 6), + '-', + prs.length ? prs.map(pr => `#${pr}`).join(',') : '?', + ); + for (let j = 0; j < prs.length; j += 1) { + const pr = prs[j]; + + // Use jquery to get full html page since it don't need auth token + const res = await fetch(`https://github.com/ant-design/ant-design/pull/${pr}`); + if (res.url.includes('/issues/')) { + continue; + } + + const html = await res.text(); + + const $html = $(html); + + const prTitle = $html + .find(QUERY_TITLE) + .text() + .trim(); + const prAuthor = $html + .find(QUERY_AUTHOR) + .text() + .trim(); + const prLines = $html.find(QUERY_DESCRIPTION_LINES); + + const lines = []; + prLines.each(function getDesc() { + lines.push( + $(this) + .text() + .trim(), + ); + }); + + const english = getDescription(lines.find(line => line.includes('🇺🇸 English'))); + const chinese = getDescription(lines.find(line => line.includes('🇨🇳 Chinese'))); + + validatePRs.push({ + pr, + hash, + title: prTitle, + author: prAuthor, + english: english || prTitle, + chinese: chinese || prTitle, + }); + } + + if (validatePRs.length === 1) { + console.log(chalk.cyan(' - Match PR:', `#${validatePRs[0].pr}`)); + prList = prList.concat(validatePRs); + } else if (message.includes('docs:')) { + console.log(chalk.cyan(' - Skip document!')); + } else { + console.log(chalk.yellow(' - Miss match!')); + prList.push({ + hash, + title: message, + }); + } + } + + console.log('\n', chalk.green('Done. Here is the log:')); + + function printPR(lang, postLang) { + prList.forEach(entity => { + const { pr, author, hash, title } = entity; + if (pr) { + const str = postLang(entity[lang]); + let icon = ''; + if (str.toLowerCase().includes('fix') || str.includes('修复')) { + icon = '🐞'; + } + + let authorText = ''; + if (!MAINTAINERS.includes(author)) { + authorText = ` [@${author}](https://github.com/${author})`; + } + + console.log( + `- ${icon} ${str}[#${pr}](https://github.com/ant-design/ant-design/pull/${pr})${authorText}`, + ); + } else { + console.log( + `🆘 Miss Match: ${title} -> https://github.com/ant-design/ant-design/commit/${hash}`, + ); + } + }); + } + + // Chinese + printPR('chinese', chinese => (chinese[chinese.length - 1] === '。' ? chinese : `${chinese}。`)); + + console.log('-----'); + + // English + printPR('english', english => { + english = english.trim(); + if (english[english.length - 1] !== '.') { + english = `${english}.`; + } + return `${english} `; + }); +} + +printLog(); +/* eslint-enable */ From 0800063f34da538e47491ae47c73d25e42020970 Mon Sep 17 00:00:00 2001 From: xrkffgg Date: Thu, 9 Jan 2020 10:23:53 +0800 Subject: [PATCH 05/19] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20Carousel=20?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20left/right=20=E6=A8=A1=E5=BC=8F=E4=B8=8B?= =?UTF-8?q?=E5=8D=A1=E7=89=87=E8=BD=AE=E6=92=AD=E6=96=B9=E5=90=91=20(#2078?= =?UTF-8?q?1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 修复 Carousel 组件 left/right 模式下卡片轮播方向 * fix: snap * add: test * remove: unnecessary code --- .../carousel/__tests__/__snapshots__/index.test.js.snap | 4 ++-- components/carousel/index.tsx | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/components/carousel/__tests__/__snapshots__/index.test.js.snap b/components/carousel/__tests__/__snapshots__/index.test.js.snap index 0cd05b6ab9..0285452d38 100644 --- a/components/carousel/__tests__/__snapshots__/index.test.js.snap +++ b/components/carousel/__tests__/__snapshots__/index.test.js.snap @@ -58,7 +58,7 @@ exports[`Carousel should works for dotPosition left 1`] = ` class="ant-carousel ant-carousel-vertical" >
{ const prefixCls = getPrefixCls('carousel', props.prefixCls); const dotsClass = 'slick-dots'; const dotPosition = this.getDotPosition(); + props.vertical = dotPosition === 'left' || dotPosition === 'right'; props.dotsClass = `${dotsClass} ${dotsClass}-${dotPosition || 'bottom'}`; const className = classNames(prefixCls, { [`${prefixCls}-rtl`]: direction === 'rtl', - [`${prefixCls}-vertical`]: dotPosition === 'left' || dotPosition === 'right', + [`${prefixCls}-vertical`]: props.vertical, }); return ( From 05ebf0f8ccd212204a1df184d166f81baa1f3ce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E6=9C=BA=E5=99=A8=E4=BA=BA?= Date: Thu, 9 Jan 2020 11:13:07 +0800 Subject: [PATCH 06/19] chore: Not block input when Input value is `undefined` (#20783) * chore: Input should not block input when `value` is undefined * add test casw * Fix test case & add breaking change in changelog * fix prevValue logic * patch change log --- CHANGELOG.en-US.md | 2 ++ CHANGELOG.zh-CN.md | 2 ++ components/input/ClearableLabeledInput.tsx | 1 - components/input/Input.tsx | 17 ++++++++++------- components/input/__tests__/index.test.js | 11 +++++++++++ docs/react/migration-v4.en-US.md | 1 + docs/react/migration-v4.zh-CN.md | 1 + 7 files changed, 27 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md index 1a9f017c07..17f542983b 100644 --- a/CHANGELOG.en-US.md +++ b/CHANGELOG.en-US.md @@ -68,7 +68,9 @@ Ant Design 4.0-rc released! Here is the release [document](https://github.com/an - 🌟 Tree supports virtual scrolling. [#18172](https://github.com/ant-design/ant-design/pull/18172) - 🌟 Tree Enhanced accessibility support and keyboard interaction. [#18866](https://github.com/ant-design/ant-design/pull/18866) - 🌟 Select uses virtual scrolling and enhanced accessibility support and keyboard interaction. [#18658](https://github.com/ant-design/ant-design/pull/18658) + - 🌟 Uncontrolled mode when `value` is `undefined` now. - 🌟 TreeSelect uses virtual scrolling and optimizes keyboard support. [#19040](https://github.com/ant-design/ant-design/pull/19040) + - 🌟 Uncontrolled mode when `value` is `undefined` now. - 🌟 Button adds `default` and`link` styles for `danger`. [#19837](https://github.com/ant-design/ant-design/pull/19837) - 🌟 Form and ConfigProvider support `size` setting to include component size. [#20570](https://github.com/ant-design/ant-design/pull/20570) - 🌟 Typography adds `suffix` attribute. [#20224](https://github.com/ant-design/ant-design/pull/20224) diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index 6367ac5633..087cd38d95 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -68,7 +68,9 @@ Ant Design 4.0-rc 发布,发布文档请查看[此处](https://github.com/ant- - 🌟 Tree 支持虚拟滚动。[#18172](https://github.com/ant-design/ant-design/pull/18172) - 🌟 Tree 增强无障碍支持以及键盘交互。[#18866](https://github.com/ant-design/ant-design/pull/18866) - 🌟 Select 使用虚拟滚动并增强无障碍支持以及键盘交互。[#18658](https://github.com/ant-design/ant-design/pull/18658) + - 🌟 `value` 为 `undefined` 时,改为非受控模式。 - 🌟 TreeSelect 使用虚拟滚动并优化键盘支持。[#19040](https://github.com/ant-design/ant-design/pull/19040) + - 🌟 `value` 为 `undefined` 时,改为非受控模式。 - 🌟 Button 添加 `danger` 的 `default` 和 `link` 样式。[#19837](https://github.com/ant-design/ant-design/pull/19837) - 🌟 Form 与 ConfigProvider 支持 `size` 设置包含组件尺寸。[#20570](https://github.com/ant-design/ant-design/pull/20570) - 🌟 Typography 增加 `suffix` 属性。[#20224](https://github.com/ant-design/ant-design/pull/20224) diff --git a/components/input/ClearableLabeledInput.tsx b/components/input/ClearableLabeledInput.tsx index 3b082d62d8..fae2294b46 100644 --- a/components/input/ClearableLabeledInput.tsx +++ b/components/input/ClearableLabeledInput.tsx @@ -18,7 +18,6 @@ interface BasicProps { prefixCls: string; inputType: typeof ClearableInputType[number]; value?: any; - defaultValue?: any; allowClear?: boolean; element: React.ReactElement; handleReset: (event: React.MouseEvent) => void; diff --git a/components/input/Input.tsx b/components/input/Input.tsx index b3fbc71662..4eafdfd0af 100644 --- a/components/input/Input.tsx +++ b/components/input/Input.tsx @@ -72,6 +72,8 @@ export function getInputClassName( export interface InputState { value: any; + /** `value` from prev props */ + prevValue: any; } class Input extends React.Component { @@ -100,16 +102,17 @@ class Input extends React.Component { const value = typeof props.value === 'undefined' ? props.defaultValue : props.value; this.state = { value, + // eslint-disable-next-line react/no-unused-state + prevValue: props.value, }; } - static getDerivedStateFromProps(nextProps: InputProps) { - if ('value' in nextProps) { - return { - value: nextProps.value, - }; + static getDerivedStateFromProps(nextProps: InputProps, { prevValue }: InputState) { + const newState: Partial = { prevValue: nextProps.value }; + if (nextProps.value !== undefined || prevValue !== nextProps.value) { + newState.value = nextProps.value; } - return null; + return newState; } componentDidMount() { @@ -158,7 +161,7 @@ class Input extends React.Component { }; setValue(value: string, callback?: () => void) { - if (!('value' in this.props)) { + if (this.props.value === undefined) { this.setState({ value }, callback); } } diff --git a/components/input/__tests__/index.test.js b/components/input/__tests__/index.test.js index ba324d4639..a4948a7c93 100644 --- a/components/input/__tests__/index.test.js +++ b/components/input/__tests__/index.test.js @@ -442,4 +442,15 @@ describe('TextArea allowClear', () => { const wrapper = mount(