From fc6f7336be9ed85b6f2cde3a3ea5366fd49bde59 Mon Sep 17 00:00:00 2001 From: zombiej Date: Tue, 29 Jan 2019 11:04:22 +0800 Subject: [PATCH 01/19] update style --- components/empty/style/index.less | 7 +++---- package.json | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/components/empty/style/index.less b/components/empty/style/index.less index 21788e2cff..e88289d37e 100644 --- a/components/empty/style/index.less +++ b/components/empty/style/index.less @@ -45,8 +45,7 @@ } // Patch for popup adjust -.@{ant-prefix}-select-dropdown--multiple .@{ant-prefix}-select-dropdown-menu-item { - .@{empty-prefix-cls}-small { - margin-left: @control-padding-horizontal + 20; - } +.@{ant-prefix}-select-dropdown--empty .@{ant-prefix}-select-dropdown-menu-item { + padding-left: 0; + padding-right: 0; } diff --git a/package.json b/package.json index fc107d57be..7b5da7975e 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "rc-pagination": "~1.17.7", "rc-progress": "~2.3.0", "rc-rate": "~2.5.0", - "rc-select": "^8.6.7", + "rc-select": "~8.8.0", "rc-slider": "~8.6.3", "rc-steps": "~3.3.0", "rc-switch": "~1.9.0", From 27f926fe93d2e0b46baeb0c4401d48c0e7289d0c Mon Sep 17 00:00:00 2001 From: Cheng Date: Fri, 1 Feb 2019 15:55:03 +0800 Subject: [PATCH 02/19] Feat timepicker clearicon (#14556) * :sparkles: custom clearIcon for time-picker * :memo: update readme --- components/time-picker/index.en-US.md | 1 + components/time-picker/index.tsx | 13 ++++++++++--- components/time-picker/index.zh-CN.md | 1 + 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/components/time-picker/index.en-US.md b/components/time-picker/index.en-US.md index 304d9d9ff3..8bbabe24c8 100644 --- a/components/time-picker/index.en-US.md +++ b/components/time-picker/index.en-US.md @@ -46,6 +46,7 @@ import moment from 'moment'; | popupStyle | style of panel | object | - | | secondStep | interval between seconds in picker | number | 1 | | suffixIcon | The custom suffix icon | ReactNode | - | +| clearIcon | The custom clear icon | ReactNode | - | | use12Hours | display as 12 hours format, with default format `h:mm:ss a` | boolean | false | | value | to set time | [moment](http://momentjs.com/) | - | | onChange | a callback function, can be executed when the selected time is changing | function(time: moment, timeString: string): void | - | diff --git a/components/time-picker/index.tsx b/components/time-picker/index.tsx index 6148ec0435..da9b8a6d7b 100644 --- a/components/time-picker/index.tsx +++ b/components/time-picker/index.tsx @@ -53,6 +53,7 @@ export interface TimePickerProps { popupClassName?: string; popupStyle?: React.CSSProperties; suffixIcon?: React.ReactNode; + clearIcon?: React.ReactNode; } export interface TimePickerLocale { @@ -164,11 +165,17 @@ class TimePicker extends React.Component { } renderClearIcon(prefixCls: string) { - const {} = this.props; + const { clearIcon } = this.props; - const clearIcon = ; + const clearIconPrefixCls = `${prefixCls}-clear`; - return clearIcon; + if (clearIcon && React.isValidElement<{ className?: string }>(clearIcon)) { + return React.cloneElement(clearIcon, { + className: classNames(clearIcon.props.className, clearIconPrefixCls), + }); + } + + return ; } renderTimePicker = (locale: TimePickerLocale) => ( diff --git a/components/time-picker/index.zh-CN.md b/components/time-picker/index.zh-CN.md index 5ec41f60b8..9fee313076 100644 --- a/components/time-picker/index.zh-CN.md +++ b/components/time-picker/index.zh-CN.md @@ -47,6 +47,7 @@ import moment from 'moment'; | popupStyle | 弹出层样式对象 | object | - | | secondStep | 秒选项间隔 | number | 1 | | suffixIcon | 自定义的选择框后缀图标 | ReactNode | - | +| clearIcon | 自定义的清除图标 | ReactNode | - | | use12Hours | 使用 12 小时制,为 true 时 `format` 默认为 `h:mm:ss a` | boolean | false | | value | 当前时间 | [moment](http://momentjs.com/) | 无 | | onChange | 时间发生变化的回调 | function(time: moment, timeString: string): void | 无 | From c20acfb9b38384017a57d315c2cb68a841058664 Mon Sep 17 00:00:00 2001 From: "LT246-VINHNPH\\vinhnph" Date: Mon, 11 Feb 2019 13:52:56 +0700 Subject: [PATCH 03/19] Table column filter could be ReactNode --- components/table/interface.tsx | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/components/table/interface.tsx b/components/table/interface.tsx index eda1ff7f0a..477119588c 100644 --- a/components/table/interface.tsx +++ b/components/table/interface.tsx @@ -6,18 +6,17 @@ import { CheckboxChangeEvent } from '../checkbox'; import { PaginationConfig } from '../pagination'; export { PaginationConfig } from '../pagination'; -export type CompareFn = ((a: T, b: T, sortOrder?: SortOrder) => number); -export type ColumnFilterItem = { text: string; value: string; children?: ColumnFilterItem[] }; +export type CompareFn = (a: T, b: T, sortOrder?: SortOrder) => number; +export type ColumnFilterItem = { + text: string | React.ReactNode; + value: string; + children?: ColumnFilterItem[]; +}; export interface ColumnProps { title?: | React.ReactNode - | (( - options: { - filters: TableStateFilters; - sortOrder?: SortOrder; - }, - ) => React.ReactNode); + | ((options: { filters: TableStateFilters; sortOrder?: SortOrder }) => React.ReactNode); key?: React.Key; dataIndex?: string; // Note: We can not use generic type here, since we need to support nested key, see #9393 render?: (text: any, record: T, index: number) => React.ReactNode; From 5ad94694347535d0f61c9596d5cb5cca2ee624ff Mon Sep 17 00:00:00 2001 From: zombieJ Date: Tue, 12 Feb 2019 17:16:49 +0800 Subject: [PATCH 04/19] Countdown support `onFinish` (#14791) * support onFinish * clean up * update test case --- components/statistic/Countdown.tsx | 21 +++++++++--- components/statistic/__tests__/index.test.js | 34 ++++++++++++++++++-- components/statistic/demo/countdown.md | 6 +++- components/statistic/index.en-US.md | 1 + components/statistic/index.zh-CN.md | 1 + 5 files changed, 56 insertions(+), 7 deletions(-) diff --git a/components/statistic/Countdown.tsx b/components/statistic/Countdown.tsx index 8870d37685..4803ef74d6 100644 --- a/components/statistic/Countdown.tsx +++ b/components/statistic/Countdown.tsx @@ -10,6 +10,11 @@ const REFRESH_INTERVAL = 1000 / 30; interface CountdownProps extends StatisticProps { value?: countdownValueType; format?: string; + onFinish?: () => void; +} + +function getTime(value?: countdownValueType) { + return interopDefault(moment)(value).valueOf(); } class Countdown extends React.Component { @@ -34,7 +39,7 @@ class Countdown extends React.Component { syncTimer = () => { const { value } = this.props; - const timestamp = interopDefault(moment)(value).valueOf(); + const timestamp = getTime(value); if (timestamp >= Date.now()) { this.startTimer(); } else { @@ -43,7 +48,7 @@ class Countdown extends React.Component { }; startTimer = () => { - if (this.countdownId !== undefined) return; + if (this.countdownId) return; this.countdownId = window.setInterval(() => { this.forceUpdate(); @@ -51,8 +56,16 @@ class Countdown extends React.Component { }; stopTimer = () => { - clearInterval(this.countdownId); - this.countdownId = undefined; + const { onFinish, value } = this.props; + if (this.countdownId) { + clearInterval(this.countdownId); + this.countdownId = undefined; + + const timestamp = getTime(value); + if (onFinish && timestamp < Date.now()) { + onFinish(); + } + } }; formatCountdown = (value: countdownValueType, config: FormatConfig) => { diff --git a/components/statistic/__tests__/index.test.js b/components/statistic/__tests__/index.test.js index bab5980ed8..05a2d76c96 100644 --- a/components/statistic/__tests__/index.test.js +++ b/components/statistic/__tests__/index.test.js @@ -61,17 +61,47 @@ describe('Statistic', () => { it('time going', async () => { const now = Date.now() + 1000; - const wrapper = mount(); + const onFinish = jest.fn(); + const wrapper = mount(); wrapper.update(); // setInterval should work const instance = wrapper.instance(); expect(instance.countdownId).not.toBe(undefined); - await delay(50); + await delay(10); wrapper.unmount(); expect(instance.countdownId).toBe(undefined); + expect(onFinish).not.toBeCalled(); + }); + + describe('time finished', () => { + it('not call if time already passed', () => { + const now = Date.now() - 1000; + + const onFinish = jest.fn(); + const wrapper = mount(); + wrapper.update(); + + const instance = wrapper.instance(); + expect(instance.countdownId).toBe(undefined); + expect(onFinish).not.toBeCalled(); + }); + + it('called if finished', async () => { + jest.useFakeTimers(); + const now = Date.now() + 10; + const onFinish = jest.fn(); + const wrapper = mount(); + wrapper.update(); + + MockDate.set(moment('2019-11-28 00:00:00')); + jest.runAllTimers(); + + expect(onFinish).toBeCalled(); + jest.useFakeTimers(); + }); }); }); }); diff --git a/components/statistic/demo/countdown.md b/components/statistic/demo/countdown.md index 0bfc1feb12..8fcf2ed571 100644 --- a/components/statistic/demo/countdown.md +++ b/components/statistic/demo/countdown.md @@ -19,10 +19,14 @@ import { Statistic, Row, Col } from 'antd'; const Countdown = Statistic.Countdown; const deadline = Date.now() + 1000 * 60 * 60 * 24 * 2 + 1000 * 30; // Moment is also OK +function onFinish() { + console.log('finished!'); +} + ReactDOM.render( - + diff --git a/components/statistic/index.en-US.md b/components/statistic/index.en-US.md index a9dffd9a74..28b7da33e6 100644 --- a/components/statistic/index.en-US.md +++ b/components/statistic/index.en-US.md @@ -32,6 +32,7 @@ Display statistic number. | Property | Description | Type | Default | | -------- | ----------- | ---- | ------- | | format | Format as [moment](http://momentjs.com/) | string | 'HH:mm:ss' | +| onFinish | Trigger when time's up | () => void | - | | prefix | prefix node of value | string \| ReactNode | - | | suffix | suffix node of value | string \| ReactNode | - | | title | Display title | string \| ReactNode | - | diff --git a/components/statistic/index.zh-CN.md b/components/statistic/index.zh-CN.md index 186dba7e83..7ac9b78850 100644 --- a/components/statistic/index.zh-CN.md +++ b/components/statistic/index.zh-CN.md @@ -33,6 +33,7 @@ title: Statistic | 参数 | 说明 | 类型 | 默认值 | | -------- | ----------- | ---- | ------- | | format | 格式化倒计时展示,参考 [moment](http://momentjs.com/) | string | 'HH:mm:ss' | +| onFinish | 倒计时完成时触发 | () => void | - | | prefix | 设置数值的前缀 | string \| ReactNode | - | | suffix | 设置数值的后缀 | string \| ReactNode | - | | title | 数值的标题 | string \| ReactNode | - | From 62e65d955065b1862240f9f30d84de44349a0cf9 Mon Sep 17 00:00:00 2001 From: afc163 Date: Wed, 13 Feb 2019 19:32:49 +0800 Subject: [PATCH 05/19] =?UTF-8?q?=F0=9F=8C=9F=20support=20extra=20for=20Co?= =?UTF-8?q?llapse.Panel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit close #11626 --- components/collapse/Collapse.tsx | 1 + components/collapse/CollapsePanel.tsx | 1 + .../__snapshots__/index.test.js.snap | 85 +++++++++++++++++++ components/collapse/__tests__/index.test.js | 10 +++ components/collapse/index.en-US.md | 1 + components/collapse/index.zh-CN.md | 1 + package.json | 2 +- 7 files changed, 100 insertions(+), 1 deletion(-) diff --git a/components/collapse/Collapse.tsx b/components/collapse/Collapse.tsx index a1336fe6ea..d6dd3cfd6e 100644 --- a/components/collapse/Collapse.tsx +++ b/components/collapse/Collapse.tsx @@ -28,6 +28,7 @@ interface PanelProps { showArrow?: boolean; forceRender?: boolean; disabled?: boolean; + extra?: React.ReactNode; } export default class Collapse extends React.Component { diff --git a/components/collapse/CollapsePanel.tsx b/components/collapse/CollapsePanel.tsx index fd96e10bfc..8a8c98f33e 100644 --- a/components/collapse/CollapsePanel.tsx +++ b/components/collapse/CollapsePanel.tsx @@ -13,6 +13,7 @@ export interface CollapsePanelProps { prefixCls?: string; forceRender?: boolean; id?: string; + extra?: React.ReactNode; } export default class CollapsePanel extends React.Component { diff --git a/components/collapse/__tests__/__snapshots__/index.test.js.snap b/components/collapse/__tests__/__snapshots__/index.test.js.snap index 64ce6fbb74..f07a4baaff 100644 --- a/components/collapse/__tests__/__snapshots__/index.test.js.snap +++ b/components/collapse/__tests__/__snapshots__/index.test.js.snap @@ -1,5 +1,90 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Collapse should render extra node of panel 1`] = ` +
+
+ +
+
+ +
+
+`; + exports[`Collapse should support remove expandIcon 1`] = `
{ ); expect(wrapper.render()).toMatchSnapshot(); }); + + it('should render extra node of panel', () => { + const wrapper = mount( + + action} /> + action} /> + + ); + expect(wrapper.render()).toMatchSnapshot(); + }); }); diff --git a/components/collapse/index.en-US.md b/components/collapse/index.en-US.md index c8d6cb0b8f..05c30d41fb 100644 --- a/components/collapse/index.en-US.md +++ b/components/collapse/index.en-US.md @@ -35,6 +35,7 @@ A content area which can be collapsed and expanded. | header | Title of the panel | string\|ReactNode | - | | key | Unique key identifying the panel from among its siblings | string | - | | showArrow | If `false`, panel will not show arrow icon | boolean | `true` | +| extra | extra element in the corner | ReactNode | - | ## FAQ diff --git a/components/collapse/index.zh-CN.md b/components/collapse/index.zh-CN.md index 6616282e21..deb21a4f7a 100644 --- a/components/collapse/index.zh-CN.md +++ b/components/collapse/index.zh-CN.md @@ -36,6 +36,7 @@ cols: 1 | header | 面板头内容 | string\|ReactNode | 无 | | key | 对应 activeKey | string | 无 | | showArrow | 是否展示当前面板上的箭头 | boolean | `true` | +| extra | 自定义渲染每个面板右上角的内容 | ReactNode | - | ## FAQ diff --git a/package.json b/package.json index 98e8d2ae99..d36a397fb7 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "rc-calendar": "~9.10.3", "rc-cascader": "~0.17.0", "rc-checkbox": "~2.1.5", - "rc-collapse": "~1.10.2", + "rc-collapse": "~1.11.1", "rc-dialog": "~7.3.0", "rc-drawer": "~1.7.6", "rc-dropdown": "~2.4.1", From 2bacd0614c1f45eb0563257a3b4a3d9e8917e7f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=81=8F=E5=8F=B3?= Date: Thu, 14 Feb 2019 17:51:52 +0800 Subject: [PATCH 06/19] :zap: Use semantic tag names in Layout (#14806) close #14801 --- .../__snapshots__/components.test.js.snap | 54 ++-- components/layout/Sider.tsx | 4 +- .../__tests__/__snapshots__/demo.test.js.snap | 258 +++++++++--------- .../__snapshots__/index.test.js.snap | 4 +- components/layout/layout.tsx | 26 +- 5 files changed, 176 insertions(+), 170 deletions(-) diff --git a/components/config-provider/__tests__/__snapshots__/components.test.js.snap b/components/config-provider/__tests__/__snapshots__/components.test.js.snap index ab0a4045b4..cf816f87ea 100644 --- a/components/config-provider/__tests__/__snapshots__/components.test.js.snap +++ b/components/config-provider/__tests__/__snapshots__/components.test.js.snap @@ -7525,87 +7525,87 @@ exports[`ConfigProvider components InputNumber prefixCls 1`] = ` `; exports[`ConfigProvider components Layout configProvider 1`] = ` -
-
-
-
+
-
-
- -
+
+ `; exports[`ConfigProvider components Layout normal 1`] = ` -
-
-
-
+
-
-
- -
+
+ `; exports[`ConfigProvider components Layout prefixCls 1`] = ` -
-
-
-
+
-
-
- -
+
+ `; exports[`ConfigProvider components List configProvider 1`] = ` diff --git a/components/layout/Sider.tsx b/components/layout/Sider.tsx index b169b1af8a..466a5f8c1d 100644 --- a/components/layout/Sider.tsx +++ b/components/layout/Sider.tsx @@ -249,10 +249,10 @@ class Sider extends React.Component { [`${prefixCls}-zero-width`]: parseFloat(siderWidth) === 0, }); return ( -
+
+ ); }; diff --git a/components/layout/__tests__/__snapshots__/demo.test.js.snap b/components/layout/__tests__/__snapshots__/demo.test.js.snap index 4af2299bbe..f466a10e6d 100644 --- a/components/layout/__tests__/__snapshots__/demo.test.js.snap +++ b/components/layout/__tests__/__snapshots__/demo.test.js.snap @@ -2,37 +2,37 @@ exports[`renders ./components/layout/demo/basic.md correctly 1`] = `
-
-
Header -
-
+
Content -
-
+
Footer -
-
-
+ +
-
Header -
-
+
-
@@ -41,36 +41,36 @@ exports[`renders ./components/layout/demo/basic.md correctly 1`] = ` > Sider
-
-
+
Content -
-
-
+ +
Footer -
-
-
+ +
-
Header -
-
+
-
Content -
-
+
-
-
-
+ +
Footer -
-
-
+ +
-
@@ -99,35 +99,35 @@ exports[`renders ./components/layout/demo/basic.md correctly 1`] = ` > Sider
-
-
+
-
Header -
-
+
Content -
-
+
Footer -
-
-
+ + +
`; exports[`renders ./components/layout/demo/custom-trigger.md correctly 1`] = ` -
-
@@ -224,11 +224,11 @@ exports[`renders ./components/layout/demo/custom-trigger.md correctly 1`] = `
-
-
+
-
@@ -251,22 +251,22 @@ exports[`renders ./components/layout/demo/custom-trigger.md correctly 1`] = ` /> -
-
+
Content -
-
-
+ + + `; exports[`renders ./components/layout/demo/fixed.md correctly 1`] = ` -
-
@@ -369,8 +369,8 @@ exports[`renders ./components/layout/demo/fixed.md correctly 1`] = `
-
-
+
@@ -420,21 +420,21 @@ exports[`renders ./components/layout/demo/fixed.md correctly 1`] = ` > Content
-
-
+
Ant Design ©2018 Created by Ant UED -
-
+ + `; exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = ` -
-
@@ -682,16 +682,16 @@ exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = `
-
-
+
-
-
@@ -794,22 +794,22 @@ exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = `
content
-
-
+
Ant Design ©2018 Created by Ant UED -
-
-
+ + + `; exports[`renders ./components/layout/demo/responsive.md correctly 1`] = ` -
-
@@ -941,15 +941,15 @@ exports[`renders ./components/layout/demo/responsive.md correctly 1`] = `
-
-
+
-
-
@@ -958,23 +958,23 @@ exports[`renders ./components/layout/demo/responsive.md correctly 1`] = ` > content
-
-
+
Ant Design ©2018 Created by Ant UED -
-
-
+ + + `; exports[`renders ./components/layout/demo/side.md correctly 1`] = ` -
-
@@ -1172,15 +1172,15 @@ exports[`renders ./components/layout/demo/side.md correctly 1`] = `
-
-
+
-
-
@@ -1218,22 +1218,22 @@ exports[`renders ./components/layout/demo/side.md correctly 1`] = ` > Bill is a cat.
-
-
+
Ant Design ©2018 Created by Ant UED -
-
-
+ + + `; exports[`renders ./components/layout/demo/top.md correctly 1`] = ` -
-
-
-
+
@@ -1386,21 +1386,21 @@ exports[`renders ./components/layout/demo/top.md correctly 1`] = ` > Content
-
-
+
Ant Design ©2018 Created by Ant UED -
-
+ + `; exports[`renders ./components/layout/demo/top-side.md correctly 1`] = ` -
-
-
-
+
@@ -1548,11 +1548,11 @@ exports[`renders ./components/layout/demo/top-side.md correctly 1`] = `
-
-
@@ -1711,29 +1711,29 @@ exports[`renders ./components/layout/demo/top-side.md correctly 1`] = `
-
-
+
Content -
-
-
-
+ + +
Ant Design ©2018 Created by Ant UED -
-
+ + `; exports[`renders ./components/layout/demo/top-side-2.md correctly 1`] = ` -
-
-
-
+
-
@@ -1998,8 +1998,8 @@ exports[`renders ./components/layout/demo/top-side-2.md correctly 1`] = `
-
-
+
@@ -2044,13 +2044,13 @@ exports[`renders ./components/layout/demo/top-side-2.md correctly 1`] = `
-
Content -
-
-
- + + + + `; diff --git a/components/layout/__tests__/__snapshots__/index.test.js.snap b/components/layout/__tests__/__snapshots__/index.test.js.snap index 1d87628e5a..73bd74c620 100644 --- a/components/layout/__tests__/__snapshots__/index.test.js.snap +++ b/components/layout/__tests__/__snapshots__/index.test.js.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Layout renders string width correctly 1`] = ` -
@@ -10,5 +10,5 @@ exports[`Layout renders string width correctly 1`] = ` > Sider
- + `; diff --git a/components/layout/layout.tsx b/components/layout/layout.tsx index f4a2aa1822..52240605ce 100644 --- a/components/layout/layout.tsx +++ b/components/layout/layout.tsx @@ -6,13 +6,15 @@ import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; export interface GeneratorProps { suffixCls: string; + tagName: 'header' | 'footer' | 'main' | 'section'; } export interface BasicProps extends React.HTMLAttributes { prefixCls?: string; hasSider?: boolean; + tagName: 'header' | 'footer' | 'main' | 'section'; } -function generator({ suffixCls }: GeneratorProps) { +function generator({ suffixCls, tagName }: GeneratorProps) { return (BasicComponent: React.ComponentClass): any => { return class Adapter extends React.Component { static Header: any; @@ -24,7 +26,7 @@ function generator({ suffixCls }: GeneratorProps) { const { prefixCls: customizePrefixCls } = this.props; const prefixCls = getPrefixCls(suffixCls, customizePrefixCls); - return ; + return ; }; render() { @@ -36,12 +38,12 @@ function generator({ suffixCls }: GeneratorProps) { class Basic extends React.Component { render() { - const { prefixCls, className, children, ...others } = this.props; - const divCls = classNames(className, prefixCls); + const { prefixCls, className, children, tagName: CustomElement, ...others } = this.props; + const classString = classNames(className, prefixCls); return ( -
+ {children} -
+ ); } } @@ -74,14 +76,14 @@ class BasicLayout extends React.Component { } render() { - const { prefixCls, className, children, hasSider, ...others } = this.props; - const divCls = classNames(className, prefixCls, { + const { prefixCls, className, children, hasSider, tagName: CustomElement, ...others } = this.props; + const classString = classNames(className, prefixCls, { [`${prefixCls}-has-sider`]: hasSider || this.state.siders.length > 0, }); return ( -
+ {children} -
+ ); } } @@ -93,18 +95,22 @@ const Layout: React.ComponentClass & { Sider: React.ComponentClass; } = generator({ suffixCls: 'layout', + tagName: 'section', })(BasicLayout); const Header = generator({ suffixCls: 'layout-header', + tagName: 'header', })(Basic); const Footer = generator({ suffixCls: 'layout-footer', + tagName: 'footer', })(Basic); const Content = generator({ suffixCls: 'layout-content', + tagName: 'main', })(Basic); Layout.Header = Header; From 2eddc2a1d4ba1de9228e2763e3bb7daeca1952da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=81=8F=E5=8F=B3?= Date: Thu, 14 Feb 2019 22:39:11 +0800 Subject: [PATCH 07/19] =?UTF-8?q?=F0=9F=8C=9F=20support=20goto=20button=20?= =?UTF-8?q?in=20Pagination=20(#14819)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit close #14798 close #14535 close #10201 close #7328 --- components/pagination/Pagination.tsx | 2 +- components/pagination/index.en-US.md | 2 +- components/pagination/index.zh-CN.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/components/pagination/Pagination.tsx b/components/pagination/Pagination.tsx index d86303bdbe..c85e63da3b 100644 --- a/components/pagination/Pagination.tsx +++ b/components/pagination/Pagination.tsx @@ -19,7 +19,7 @@ export interface PaginationProps { showSizeChanger?: boolean; pageSizeOptions?: string[]; onShowSizeChange?: (current: number, size: number) => void; - showQuickJumper?: boolean; + showQuickJumper?: boolean | { goButton?: React.ReactNode }; showTotal?: (total: number, range: [number, number]) => React.ReactNode; size?: string; simple?: boolean; diff --git a/components/pagination/index.en-US.md b/components/pagination/index.en-US.md index dc6d9e8ada..570b2bf36c 100644 --- a/components/pagination/index.en-US.md +++ b/components/pagination/index.en-US.md @@ -27,7 +27,7 @@ A long list can be divided into several pages by `Pagination`, and only one page | itemRender | to customize item innerHTML | (page, type: 'page' \| 'prev' \| 'next', originalElement) => React.ReactNode | - | | pageSize | number of data items per page | number | - | | pageSizeOptions | specify the sizeChanger options | string\[] | \['10', '20', '30', '40'] | -| showQuickJumper | determine whether you can jump to pages directly | boolean | false | +| showQuickJumper | determine whether you can jump to pages directly | boolean \| `{ goButton: ReactNode }` | false | | showSizeChanger | determine whether `pageSize` can be changed | boolean | false | | showTotal | to display the total number and range | Function(total, range) | - | | simple | whether to use simple mode | boolean | - | diff --git a/components/pagination/index.zh-CN.md b/components/pagination/index.zh-CN.md index 31752ced02..d175af3c34 100644 --- a/components/pagination/index.zh-CN.md +++ b/components/pagination/index.zh-CN.md @@ -28,7 +28,7 @@ cols: 1 | itemRender | 用于自定义页码的结构,可用于优化 SEO | (page, type: 'page' \| 'prev' \| 'next', originalElement) => React.ReactNode | - | | pageSize | 每页条数 | number | - | | pageSizeOptions | 指定每页可以显示多少条 | string\[] | \['10', '20', '30', '40'] | -| showQuickJumper | 是否可以快速跳转至某页 | boolean | false | +| showQuickJumper | 是否可以快速跳转至某页 | boolean \| `{ goButton: ReactNode }` | false | | showSizeChanger | 是否可以改变 pageSize | boolean | false | | showTotal | 用于显示数据总量和当前数据顺序 | Function(total, range) | - | | simple | 当添加该属性时,显示为简单分页 | boolean | - | From bf135c1cebd09a60ac9fd22acb1c7898cd7b93ef Mon Sep 17 00:00:00 2001 From: "LT246-VINHNPH\\vinhnph" Date: Fri, 15 Feb 2019 10:15:43 +0700 Subject: [PATCH 08/19] ReactNode has already included string --- components/table/interface.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/table/interface.tsx b/components/table/interface.tsx index 477119588c..45b0a7400e 100644 --- a/components/table/interface.tsx +++ b/components/table/interface.tsx @@ -8,7 +8,7 @@ export { PaginationConfig } from '../pagination'; export type CompareFn = (a: T, b: T, sortOrder?: SortOrder) => number; export type ColumnFilterItem = { - text: string | React.ReactNode; + text: React.ReactNode; value: string; children?: ColumnFilterItem[]; }; From c80136a9a751cf1e4146d3a478acb54fde6ff717 Mon Sep 17 00:00:00 2001 From: zombieJ Date: Tue, 19 Feb 2019 11:42:05 +0800 Subject: [PATCH 09/19] New Component: Typography (#14250) * text with prefix * add edit style * support editable * enhance accessibility & type experience * optimize IME case * support copy * add locale * add secondary & disabled * add ellipsis shadow text * split to 3 components * update snapshot * update desc * change lines also need update ellipsis * skip aria when is in ellipsis * add ResizeObserver in _util * update snapshot * move TestBase into test file * update test case * update doc * fix typo * important => level * use rows * update demo cols to 1 * fix cssText not work in firefox * update doc * add miss point * support extendable * update snapshot * fix doc * copyable support string * update snapshot * update doc * update doc desc * adjust style * full test * reset after test * rename * update snapshot * fix compile * adjust style * update desc * update prefixCls * update margin * adjust * nest wrap of tag content * adjust style * update comment * rm % * one more thing * tmp of measure * merge string as children * update snapshot * update testcase * remove comment * use internal variable for configProvider passing * update snapshot * use expandable instead of extendable * less variable it * update demo * update less * adjust code & mark style * remove mark padding * update measure logic * support nest element style * use childNode.textContent to fix react 15 error * update css * popout Typography * add link style * adjust doc * use ellipsis instead of rows & expandable * update doc * update doc * update doc & style * fix typo * add css ellipsis support * client render * update snapshot * enhance copyable * support onExpand * update test case * add test of css ellipsis * fix logic in react 15 * rename onChange -> onSave * use tagName of article * fix lint --- .../__snapshots__/index.test.js.snap | 1 + components/_util/raf.ts | 4 +- components/_util/resizeObserver.tsx | 61 ++ components/_util/transButton.tsx | 68 ++ components/_util/type.ts | 4 +- components/config-provider/index.tsx | 24 +- components/icon/index.tsx | 1 + components/index.tsx | 2 + components/input/TextArea.tsx | 44 +- .../__snapshots__/index.test.js.snap | 36 +- components/locale-provider/default.tsx | 6 + components/locale-provider/zh_CN.tsx | 6 + components/modal/__tests__/confirm.test.js | 8 +- components/style/themes/default.less | 14 +- components/typography/Base.tsx | 481 +++++++++++++ components/typography/Editable.tsx | 133 ++++ components/typography/Paragraph.tsx | 8 + components/typography/Text.tsx | 17 + components/typography/Title.tsx | 24 + components/typography/Typography.tsx | 47 ++ .../__tests__/__snapshots__/demo.test.js.snap | 638 ++++++++++++++++++ components/typography/__tests__/demo.test.js | 3 + components/typography/__tests__/index.test.js | 223 ++++++ components/typography/demo/basic.md | 67 ++ components/typography/demo/ellipsis-debug.md | 67 ++ components/typography/demo/ellipsis.md | 42 ++ components/typography/demo/interactive.md | 43 ++ components/typography/demo/paragraph-debug.md | 66 ++ components/typography/demo/text.md | 45 ++ components/typography/demo/title.md | 30 + components/typography/index.en-US.md | 63 ++ components/typography/index.tsx | 17 + components/typography/index.zh-CN.md | 63 ++ components/typography/style/index.less | 241 +++++++ components/typography/style/index.tsx | 7 + components/typography/util.tsx | 226 +++++++ docs/spec/lightweight.en-US.md | 16 - docs/spec/lightweight.zh-CN.md | 16 - package.json | 1 + tests/__mocks__/copy-to-clipboard.js | 5 + tests/__snapshots__/index.test.js.snap | 1 + typings/custom-typings.d.ts | 2 + 42 files changed, 2782 insertions(+), 89 deletions(-) create mode 100644 components/_util/resizeObserver.tsx create mode 100644 components/_util/transButton.tsx create mode 100644 components/typography/Base.tsx create mode 100644 components/typography/Editable.tsx create mode 100644 components/typography/Paragraph.tsx create mode 100644 components/typography/Text.tsx create mode 100644 components/typography/Title.tsx create mode 100644 components/typography/Typography.tsx create mode 100644 components/typography/__tests__/__snapshots__/demo.test.js.snap create mode 100644 components/typography/__tests__/demo.test.js create mode 100644 components/typography/__tests__/index.test.js create mode 100644 components/typography/demo/basic.md create mode 100644 components/typography/demo/ellipsis-debug.md create mode 100644 components/typography/demo/ellipsis.md create mode 100644 components/typography/demo/interactive.md create mode 100644 components/typography/demo/paragraph-debug.md create mode 100644 components/typography/demo/text.md create mode 100644 components/typography/demo/title.md create mode 100644 components/typography/index.en-US.md create mode 100644 components/typography/index.tsx create mode 100644 components/typography/index.zh-CN.md create mode 100644 components/typography/style/index.less create mode 100644 components/typography/style/index.tsx create mode 100644 components/typography/util.tsx create mode 100644 tests/__mocks__/copy-to-clipboard.js diff --git a/components/__tests__/__snapshots__/index.test.js.snap b/components/__tests__/__snapshots__/index.test.js.snap index 211cf437e4..25f6f64167 100644 --- a/components/__tests__/__snapshots__/index.test.js.snap +++ b/components/__tests__/__snapshots__/index.test.js.snap @@ -59,6 +59,7 @@ Array [ "TimePicker", "Timeline", "Tooltip", + "Typography", "Mention", "Upload", "version", diff --git a/components/_util/raf.ts b/components/_util/raf.ts index a0138e4239..93075502fc 100644 --- a/components/_util/raf.ts +++ b/components/_util/raf.ts @@ -28,7 +28,9 @@ export default function wrapperRaf(callback: () => void, delayFrames: number = 1 return myId; } -wrapperRaf.cancel = function(pid: number) { +wrapperRaf.cancel = function(pid?: number) { + if (pid === undefined) return; + raf.cancel(ids[pid]); delete ids[pid]; }; diff --git a/components/_util/resizeObserver.tsx b/components/_util/resizeObserver.tsx new file mode 100644 index 0000000000..de7f4c1f24 --- /dev/null +++ b/components/_util/resizeObserver.tsx @@ -0,0 +1,61 @@ +import * as React from 'react'; +import { findDOMNode } from 'react-dom'; +import ResizeObserver from 'resize-observer-polyfill'; + +type DomElement = Element | null; + +interface ResizeObserverProps { + children?: React.ReactNode; + disabled?: boolean; + onResize?: () => void; +} + +class ReactResizeObserver extends React.Component { + resizeObserver: ResizeObserver | null = null; + + componentDidMount() { + this.onComponentUpdated(); + } + + componentDidUpdate() { + this.onComponentUpdated(); + } + + componentWillUnmount() { + this.destroyObserver(); + } + + onComponentUpdated() { + const { disabled } = this.props; + const element = findDOMNode(this) as DomElement; + if (!this.resizeObserver && !disabled && element) { + // Add resize observer + this.resizeObserver = new ResizeObserver(this.onResize); + this.resizeObserver.observe(element); + } else if (disabled) { + // Remove resize observer + this.destroyObserver(); + } + } + + onResize = () => { + const { onResize } = this.props; + if (onResize) { + onResize(); + } + }; + + destroyObserver() { + if (this.resizeObserver) { + this.resizeObserver.disconnect(); + this.resizeObserver = null; + } + } + + render() { + const { children } = this.props; + return children; + } +} + +export default ReactResizeObserver; diff --git a/components/_util/transButton.tsx b/components/_util/transButton.tsx new file mode 100644 index 0000000000..f7aca9865a --- /dev/null +++ b/components/_util/transButton.tsx @@ -0,0 +1,68 @@ +/** + * Wrap of sub component which need use as Button capacity (like Icon component). + * This helps accessibility reader to tread as a interactive button to operation. + */ +import * as React from 'react'; +import KeyCode from 'rc-util/lib/KeyCode'; + +interface TransButtonProps extends React.HTMLAttributes { + onClick?: () => void; +} + +const inlineStyle: React.CSSProperties = { + border: 0, + background: 'transparent', + padding: 0, + lineHeight: 'inherit', +}; + +class TransButton extends React.Component { + button?: HTMLButtonElement; + lastKeyCode?: number; + + onKeyDown: React.KeyboardEventHandler = event => { + const { keyCode } = event; + if (keyCode === KeyCode.ENTER) { + event.preventDefault(); + } + }; + + onKeyUp: React.KeyboardEventHandler = event => { + const { keyCode } = event; + const { onClick } = this.props; + if (keyCode === KeyCode.ENTER && onClick) { + onClick(); + } + }; + + setRef = (btn: HTMLButtonElement) => { + this.button = btn; + }; + + focus() { + if (this.button) { + this.button.focus(); + } + } + + blur() { + if (this.button) { + this.button.blur(); + } + } + + render() { + const { style } = this.props; + return ( +