Merge pull request #20812 from ant-design/master

chore: master merge into feature
This commit is contained in:
二货机器人 2020-01-10 11:16:50 +08:00 committed by GitHub
commit 29316b4e9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
50 changed files with 413 additions and 324 deletions

View File

@ -4,9 +4,13 @@ components/**/*.jsx
!components/*/demo/*
!.*.js
# Docs templates
site/theme/template/Color/ColorPicker.jsx
site/theme/template/IconDisplay/*.js
site/theme/template/IconDisplay/*.jsx
site/theme/template/IconDisplay/fields.js
site/theme/template/Home/**/*.jsx
site/theme/template/utils.jsx
site/theme/template/Layout/Footer.jsx
typings
es/**/*
lib/**/*

View File

@ -1,30 +0,0 @@
name: Deploy website
on:
release:
types: [published]
branches:
- master
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@master
- name: install
run: npm install
- name: build
run: npm run predeploy
- name: deploy
uses: peaceiris/actions-gh-pages@v2
env:
ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
# PERSONAL_TOKEN: ${{ secrets.PERSONAL_TOKEN }}
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PUBLISH_BRANCH: gh-pages
PUBLISH_DIR: ./_site
with:
emptyCommits: false

5
.gitignore vendored
View File

@ -41,9 +41,10 @@ components/**/*.jsx
*.tmp
# Docs templates
site/theme/template/Color/ColorPicker.jsx
site/theme/template/IconDisplay/*.js
site/theme/template/IconDisplay/*.jsx
site/theme/template/IconDisplay/fields.js
site/theme/template/Home/**/*.jsx
site/theme/template/utils.jsx
site/theme/template/Layout/Footer.jsx

View File

@ -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)

View File

@ -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)

View File

@ -1,5 +1,6 @@
export type Breakpoint = 'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs';
export type BreakpointMap = Partial<Record<Breakpoint, string>>;
export type ScreenMap = Partial<Record<Breakpoint, boolean>>;
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;

View File

@ -52,7 +52,7 @@ It accepts all props which native buttons support.
Following the Ant Design specification, we will add one space between if Button contains two Chinese characters only. If you don't need that, you can use [ConfigProvider](/components/config-provider/#API) to set `autoInsertSpaceInButton` as `false`.
<img src="http://alipay-rmsdeploy-image.cn-hangzhou.alipay.aliyun-inc.com/antfincdn/NstpRYFrCr/f29f170d-b78d-4d2b-aa71-0da6a9ead4d9.png" style="box-shadow: none" alt="Button with two Chinese characters" />
<img src="https://gw.alipayobjects.com/zos/antfincdn/MY%26THAPZrW/38f06cb9-293a-4b42-b183-9f443e79ffea.png" style="box-shadow: none" alt="Button with two Chinese characters" />
<style>
[id^=components-button-demo-] .ant-btn {

View File

@ -55,7 +55,7 @@ subtitle: 按钮
根据 Ant Design 设计规范要求,我们会在按钮内只有两个汉字时自动添加空格,如果你不需要这个特性,可以设置 [ConfigProvider](/components/config-provider/#API) 的 `autoInsertSpaceInButton``false`
<img src="http://alipay-rmsdeploy-image.cn-hangzhou.alipay.aliyun-inc.com/antfincdn/NstpRYFrCr/f29f170d-b78d-4d2b-aa71-0da6a9ead4d9.png" style="box-shadow: none" alt="移除两个汉字之间的空格" />
<img src="https://gw.alipayobjects.com/zos/antfincdn/MY%26THAPZrW/38f06cb9-293a-4b42-b183-9f443e79ffea.png" style="box-shadow: none" alt="移除两个汉字之间的空格" />
<style>
[id^="components-button-demo-"] .ant-btn {

View File

@ -120,7 +120,6 @@ function MonthSelect<DateType>(props: SharedProps<DateType>) {
return (
<Select
size={fullscreen ? undefined : 'small'}
dropdownMatchSelectWidth={100}
className={`${prefixCls}-month-select`}
value={month}
options={options}

View File

@ -15,11 +15,11 @@
padding: 11px 16px 11px 0;
.@{calendar-prefix-cls}-year-select {
width: 85px;
min-width: 85px;
}
.@{calendar-prefix-cls}-month-select {
width: 70px;
min-width: 70px;
margin-left: @padding-xs;
}
@ -150,6 +150,7 @@
height: 86px;
overflow-y: auto;
line-height: @line-height-base;
text-align: left;
}
&-today {

View File

@ -58,7 +58,7 @@ exports[`Carousel should works for dotPosition left 1`] = `
class="ant-carousel ant-carousel-vertical"
>
<div
class="slick-slider slick-initialized"
class="slick-slider slick-vertical slick-initialized"
>
<div
class="slick-list"
@ -92,7 +92,7 @@ exports[`Carousel should works for dotPosition right 1`] = `
class="ant-carousel ant-carousel-vertical"
>
<div
class="slick-slider slick-initialized"
class="slick-slider slick-vertical slick-initialized"
>
<div
class="slick-list"

View File

@ -105,11 +105,12 @@ export default class Carousel extends React.Component<CarouselProps, {}> {
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 (

View File

@ -217,7 +217,7 @@
position: relative;
&::before {
background: @picker-basic-cell-hover-color;
background: @picker-basic-cell-active-with-range-color;
}
}
@ -232,7 +232,7 @@
&-in-view&-range-start:not(&-range-start-single),
&-in-view&-range-end:not(&-range-end-single) {
&::before {
background: @picker-basic-cell-hover-color;
background: @picker-basic-cell-active-with-range-color;
}
}
@ -291,7 +291,16 @@
.@{picker-prefix-cls}-panel
> :not(.@{picker-prefix-cls}-date-panel)
&-in-view&-in-range&-range-hover-end::before {
background: @picker-basic-cell-hover-with-range-color;
background: @picker-date-hover-range-color;
}
// range start border-radius
&-in-view&-range-start:not(&-range-start-single):not(&-range-end) .@{cellClassName} {
border-radius: @border-radius-base 0 0 @border-radius-base;
}
// range end border-radius
&-in-view&-range-end:not(&-range-end-single):not(&-range-start) .@{cellClassName} {
border-radius: 0 @border-radius-base @border-radius-base 0;
}
// DatePanel only
@ -302,7 +311,7 @@
top: 0;
bottom: 0;
z-index: -1;
background: @picker-basic-cell-hover-with-range-color;
background: @picker-date-hover-range-color;
content: '';
}
}

View File

@ -89,7 +89,7 @@ describe('Descriptions', () => {
</Descriptions>,
);
expect(errorSpy).toHaveBeenCalledWith(
'Warning: [antd: Descriptions] Sum of column `span` in a line exceeds `column` of Descriptions.',
'Warning: [antd: Descriptions] Sum of column `span` in a line not match `column` of Descriptions.',
);
});

View File

@ -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';
@ -92,7 +92,7 @@ const generateChildrenRows = (
warning(
leftSpans === 0 && lastSpanSame,
'Descriptions',
'Sum of column `span` in a line exceeds `column` of Descriptions.',
'Sum of column `span` in a line not match `column` of Descriptions.',
);
}
});
@ -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: {},
};

View File

@ -753,7 +753,7 @@ exports[`renders ./components/empty/demo/customize.md correctly 1`] = `
>
<img
alt="empty"
src="https://alipay-rmsdeploy-image.cn-hangzhou.alipay.aliyun-inc.com/antfincdn/ncyfsLONGK/empty.svg"
src="https://gw.alipayobjects.com/zos/antfincdn/ZHrcdLPrvN/empty.svg"
/>
</div>
<p

View File

@ -18,7 +18,7 @@ import { Empty, Button } from 'antd';
ReactDOM.render(
<Empty
image="https://alipay-rmsdeploy-image.cn-hangzhou.alipay.aliyun-inc.com/antfincdn/ncyfsLONGK/empty.svg"
image="https://gw.alipayobjects.com/zos/antfincdn/ZHrcdLPrvN/empty.svg"
imageStyle={{
height: 60,
}}

View File

@ -52,7 +52,7 @@ Empty state placeholder.
background-image: url("https://user-images.githubusercontent.com/507615/54591670-ac0a0180-4a65-11e9-846c-e55ffce0fe7b.png");
}
[data-theme="dark"] .site-empty-buildIn-simple {
background-image: url("https://alipay-rmsdeploy-image.cn-hangzhou.alipay.aliyun-inc.com/antfincdn/oQFqhkmNPw/a38d2cdb-a33d-407c-8f8e-e3429699175d.png");
background-image: url("https://gw.alipayobjects.com/zos/antfincdn/ldFsHUh3Xh/ea62c5fe-07bb-4fcd-9d35-19220cef372e.png");
}
[data-theme="dark"] .site-empty-buildIn-default {
background-image: url("https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*gfq-SoT3wF0AAAAAAAAAAABkARQnAQ");

View File

@ -53,7 +53,7 @@ cols: 1
background-image: url("https://user-images.githubusercontent.com/507615/54591670-ac0a0180-4a65-11e9-846c-e55ffce0fe7b.png");
}
[data-theme="dark"] .site-empty-buildIn-simple {
background-image: url("https://alipay-rmsdeploy-image.cn-hangzhou.alipay.aliyun-inc.com/antfincdn/oQFqhkmNPw/a38d2cdb-a33d-407c-8f8e-e3429699175d.png");
background-image: url("https://gw.alipayobjects.com/zos/antfincdn/ldFsHUh3Xh/ea62c5fe-07bb-4fcd-9d35-19220cef372e.png");
}
[data-theme="dark"] .site-empty-buildIn-default {
background-image: url("https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*gfq-SoT3wF0AAAAAAAAAAABkARQnAQ");

View File

@ -487,11 +487,11 @@ exports[`renders ./components/grid/demo/gutter.md correctly 1`] = `
</div>
<div
class="ant-row"
style="margin-top:-10px;margin-bottom:10px"
style="margin-left:-16px;margin-right:-16px;margin-top:-10px;margin-bottom:10px"
>
<div
class="ant-col ant-col-6 gutter-row"
style="padding-top:10px;padding-bottom:10px"
style="padding-left:16px;padding-right:16px;padding-top:10px;padding-bottom:10px"
>
<div
class="gutter-box"
@ -501,7 +501,7 @@ exports[`renders ./components/grid/demo/gutter.md correctly 1`] = `
</div>
<div
class="ant-col ant-col-6 gutter-row"
style="padding-top:10px;padding-bottom:10px"
style="padding-left:16px;padding-right:16px;padding-top:10px;padding-bottom:10px"
>
<div
class="gutter-box"
@ -511,7 +511,7 @@ exports[`renders ./components/grid/demo/gutter.md correctly 1`] = `
</div>
<div
class="ant-col ant-col-6 gutter-row"
style="padding-top:10px;padding-bottom:10px"
style="padding-left:16px;padding-right:16px;padding-top:10px;padding-bottom:10px"
>
<div
class="gutter-box"
@ -521,7 +521,7 @@ exports[`renders ./components/grid/demo/gutter.md correctly 1`] = `
</div>
<div
class="ant-col ant-col-6 gutter-row"
style="padding-top:10px;padding-bottom:10px"
style="padding-left:16px;padding-right:16px;padding-top:10px;padding-bottom:10px"
>
<div
class="gutter-box"

View File

@ -5,7 +5,7 @@ import RowContext from './RowContext';
import { tuple } from '../_util/type';
import ResponsiveObserve, {
Breakpoint,
BreakpointMap,
ScreenMap,
responsiveArray,
} from '../_util/responsiveObserve';
@ -21,7 +21,7 @@ export interface RowProps extends React.HTMLAttributes<HTMLDivElement> {
}
export interface RowState {
screens: BreakpointMap;
screens: ScreenMap;
}
export default class Row extends React.Component<RowProps, RowState> {
@ -30,7 +30,14 @@ export default class Row extends React.Component<RowProps, RowState> {
};
state: RowState = {
screens: {},
screens: {
xs: true,
sm: true,
md: true,
lg: true,
xl: true,
xxl: true,
},
};
token: string;

View File

@ -18,7 +18,6 @@ interface BasicProps {
prefixCls: string;
inputType: typeof ClearableInputType[number];
value?: any;
defaultValue?: any;
allowClear?: boolean;
element: React.ReactElement<any>;
handleReset: (event: React.MouseEvent<HTMLElement, MouseEvent>) => void;

View File

@ -72,6 +72,8 @@ export function getInputClassName(
export interface InputState {
value: any;
/** `value` from prev props */
prevValue: any;
}
class Input extends React.Component<InputProps, InputState> {
@ -100,16 +102,17 @@ class Input extends React.Component<InputProps, InputState> {
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<InputState> = { 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<InputProps, InputState> {
};
setValue(value: string, callback?: () => void) {
if (!('value' in this.props)) {
if (this.props.value === undefined) {
this.setState({ value }, callback);
}
}

View File

@ -442,4 +442,15 @@ describe('TextArea allowClear', () => {
const wrapper = mount(<TextArea allowClear defaultValue="111" disabled />);
expect(wrapper.find('.ant-input-textarea-clear-icon').length).toBe(0);
});
it('not block input when `value` is undefined', () => {
const wrapper = mount(<Input value={undefined} />);
wrapper.find('input').simulate('change', { target: { value: 'Bamboo' } });
expect(wrapper.find('input').props().value).toEqual('Bamboo');
// Controlled
wrapper.setProps({ value: 'Light' });
wrapper.find('input').simulate('change', { target: { value: 'Bamboo' } });
expect(wrapper.find('input').props().value).toEqual('Light');
});
});

View File

@ -5320,9 +5320,6 @@ exports[`Locale Provider should display the text as ar 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -10407,9 +10404,6 @@ exports[`Locale Provider should display the text as bg 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -15494,9 +15488,6 @@ exports[`Locale Provider should display the text as ca 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -20581,9 +20572,6 @@ exports[`Locale Provider should display the text as cs 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -25668,9 +25656,6 @@ exports[`Locale Provider should display the text as da 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -30755,9 +30740,6 @@ exports[`Locale Provider should display the text as de 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -35842,9 +35824,6 @@ exports[`Locale Provider should display the text as el 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -40929,9 +40908,6 @@ exports[`Locale Provider should display the text as en 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -46016,9 +45992,6 @@ exports[`Locale Provider should display the text as en-gb 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -51103,9 +51076,6 @@ exports[`Locale Provider should display the text as es 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -56190,9 +56160,6 @@ exports[`Locale Provider should display the text as et 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -61277,9 +61244,6 @@ exports[`Locale Provider should display the text as fa 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -66364,9 +66328,6 @@ exports[`Locale Provider should display the text as fi 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -71451,9 +71412,6 @@ exports[`Locale Provider should display the text as fr 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -76538,9 +76496,6 @@ exports[`Locale Provider should display the text as fr 2`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -81625,9 +81580,6 @@ exports[`Locale Provider should display the text as he 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -86712,9 +86664,6 @@ exports[`Locale Provider should display the text as hi 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -91799,9 +91748,6 @@ exports[`Locale Provider should display the text as hr 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -96886,9 +96832,6 @@ exports[`Locale Provider should display the text as hu 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -101973,9 +101916,6 @@ exports[`Locale Provider should display the text as hy-am 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -107060,9 +107000,6 @@ exports[`Locale Provider should display the text as id 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -112147,9 +112084,6 @@ exports[`Locale Provider should display the text as is 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -117234,9 +117168,6 @@ exports[`Locale Provider should display the text as it 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -122321,9 +122252,6 @@ exports[`Locale Provider should display the text as ja 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -127408,9 +127336,6 @@ exports[`Locale Provider should display the text as kn 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -132495,9 +132420,6 @@ exports[`Locale Provider should display the text as ko 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -137582,9 +137504,6 @@ exports[`Locale Provider should display the text as ku-iq 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -142669,9 +142588,6 @@ exports[`Locale Provider should display the text as lv 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -147756,9 +147672,6 @@ exports[`Locale Provider should display the text as mk 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -152843,9 +152756,6 @@ exports[`Locale Provider should display the text as mn-mn 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -157930,9 +157840,6 @@ exports[`Locale Provider should display the text as ms-my 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -163017,9 +162924,6 @@ exports[`Locale Provider should display the text as nb 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -168104,9 +168008,6 @@ exports[`Locale Provider should display the text as ne-np 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -173191,9 +173092,6 @@ exports[`Locale Provider should display the text as nl 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -178278,9 +178176,6 @@ exports[`Locale Provider should display the text as nl-be 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -183365,9 +183260,6 @@ exports[`Locale Provider should display the text as pl 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -188452,9 +188344,6 @@ exports[`Locale Provider should display the text as pt 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -193539,9 +193428,6 @@ exports[`Locale Provider should display the text as pt-br 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -198626,9 +198512,6 @@ exports[`Locale Provider should display the text as ro 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -203713,9 +203596,6 @@ exports[`Locale Provider should display the text as ru 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -208800,9 +208680,6 @@ exports[`Locale Provider should display the text as sk 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -213887,9 +213764,6 @@ exports[`Locale Provider should display the text as sl 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -218974,9 +218848,6 @@ exports[`Locale Provider should display the text as sr 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -224061,9 +223932,6 @@ exports[`Locale Provider should display the text as sv 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -229148,9 +229016,6 @@ exports[`Locale Provider should display the text as ta 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -234235,9 +234100,6 @@ exports[`Locale Provider should display the text as th 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -239322,9 +239184,6 @@ exports[`Locale Provider should display the text as tr 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -244409,9 +244268,6 @@ exports[`Locale Provider should display the text as uk 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -249496,9 +249352,6 @@ exports[`Locale Provider should display the text as vi 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -254583,9 +254436,6 @@ exports[`Locale Provider should display the text as zh-cn 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>
@ -259670,9 +259520,6 @@ exports[`Locale Provider should display the text as zh-tw 1`] = `
</div>
</div>
</div>
<div
class="ant-picker-footer"
/>
</div>
</div>
</div>

View File

@ -691,7 +691,7 @@ exports[`renders ./components/page-header/demo/content.md correctly 1`] = `
>
<img
alt="content"
src="https://alipay-rmsdeploy-image.cn-hangzhou.alipay.aliyun-inc.com/antfincdn/YZUAr4NUNC/pageHeader.svg"
src="https://gw.alipayobjects.com/zos/antfincdn/K%24NnlsB%26hz/pageHeader.svg"
/>
</div>
</div>

View File

@ -160,7 +160,7 @@ ReactDOM.render(
<Content
extraContent={
<img
src="https://alipay-rmsdeploy-image.cn-hangzhou.alipay.aliyun-inc.com/antfincdn/YZUAr4NUNC/pageHeader.svg"
src="https://gw.alipayobjects.com/zos/antfincdn/K%24NnlsB%26hz/pageHeader.svg"
alt="content"
/>
}

View File

@ -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;

View File

@ -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;
}

View File

@ -308,7 +308,7 @@
// TimePicker
// ---
@picker-basic-cell-hover-with-range-color: #303030;
@picker-basic-cell-hover-with-range-color: darken(@primary-color, 35%);
@picker-basic-cell-disabled-bg: #303030;
@picker-border-color: @border-color-split;
@picker-bg: transparent;

View File

@ -523,10 +523,12 @@
// ---
@picker-bg: @component-background;
@picker-basic-cell-hover-color: @item-hover-bg;
@picker-basic-cell-active-with-range-color: @primary-1;
@picker-basic-cell-hover-with-range-color: lighten(@primary-color, 35%);
@picker-basic-cell-disabled-bg: @disabled-bg;
@picker-border-color: @border-color-split;
@picker-date-hover-range-border-color: lighten(@primary-color, 20%);
@picker-date-hover-range-color: @picker-basic-cell-hover-with-range-color;
// Calendar
// ---

View File

@ -23,7 +23,10 @@ function renderExpandIcon(locale: TableLocale) {
return (
<button
type="button"
onClick={e => onExpand(record, e!)}
onClick={e => {
onExpand(record, e!);
e.stopPropagation();
}}
className={classNames(iconPrefix, {
[`${iconPrefix}-spaced`]: !expandable,
[`${iconPrefix}-expanded`]: expandable && expanded,

View File

@ -11,19 +11,27 @@ const columns = [
},
];
const John = {
key: '1',
firstName: 'John',
lastName: 'Brown',
age: 32,
};
const Jim = {
key: '2',
firstName: 'Jim',
lastName: 'Green',
age: 42,
};
const data = [
{
key: '1',
firstName: 'John',
lastName: 'Brown',
age: 32,
...John,
children: [
{
key: '2',
firstName: 'Jim',
lastName: 'Green',
age: 42,
...Jim,
},
],
},
@ -43,4 +51,39 @@ describe('Table.expand', () => {
const wrapper = mount(<Table columns={[]} dataSource={data} expandIconColumnIndex={1} />);
expect(wrapper.render()).toMatchSnapshot();
});
it('expandRowByClick should not block click icon', () => {
const wrapper = mount(
<Table
columns={columns}
dataSource={[John, Jim]}
expandable={{
expandRowByClick: true,
expandedRowRender: () => '',
}}
/>,
);
wrapper
.find('.ant-table-row-expand-icon')
.first()
.simulate('click');
expect(
wrapper
.find('.ant-table-row-expand-icon')
.first()
.hasClass('ant-table-row-expand-icon-expanded'),
).toBeTruthy();
wrapper
.find('.ant-table-row-expand-icon')
.first()
.simulate('click');
expect(
wrapper
.find('.ant-table-row-expand-icon')
.first()
.hasClass('ant-table-row-expand-icon-collapsed'),
).toBeTruthy();
});
});

View File

@ -1,3 +1,6 @@
import Table from './Table';
import Table, { TableProps, TablePaginationConfig } from './Table';
export { ColumnsType, ColumnType, ColumnGroupType } from './interface';
export { TableProps, TablePaginationConfig };
export default Table;

View File

@ -53,10 +53,12 @@
}
}
tr.@{table-prefix-cls}-expanded-row,
tr.@{table-prefix-cls}-placeholder {
> td {
border-right: 0;
&.@{table-prefix-cls}-fixed-column {
tr.@{table-prefix-cls}-expanded-row,
tr.@{table-prefix-cls}-placeholder {
> td {
border-right: 0;
}
}
}

View File

@ -24,6 +24,7 @@
position: relative;
z-index: 0;
clear: both;
background: @table-bg;
// https://github.com/ant-design/ant-design/issues/17611
table {
@ -48,11 +49,6 @@
overflow-wrap: break-word;
}
// weak priority
td {
background: @table-bg;
}
&-cell-ellipsis {
overflow: hidden;
white-space: nowrap;
@ -248,7 +244,7 @@
}
&-up + &-down {
margin-top: -0.42em;
margin-top: -0.3em;
}
}
@ -520,6 +516,7 @@
&-cell-fix-left,
&-cell-fix-right {
z-index: 2;
background: @table-bg;
}
&-cell-fix-left-last::after {

View File

@ -580,7 +580,7 @@ exports[`renders ./components/typography/demo/suffix.md correctly 1`] = `
<div
class="ant-typography ant-typography-ellipsis"
>
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
</div>
</div>
`;

View File

@ -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 (
<div>
<Slider value={rows} min={1} max={10} onChange={this.onChange} />

View File

@ -115,6 +115,7 @@ const Demo = () => (
- `dropdownMatchSelectWidth` no longer automatically adapts to the content width, please set the dropdown width with numbers.
- The Grid component uses flex layout.
- Button's `danger` is now treated as a property instead of a button type.
- Input, Select set `value` to `undefined` is uncontrolled mode now.
## Start upgrading

View File

@ -115,6 +115,7 @@ const Demo = () => (
- `dropdownMatchSelectWidth` 不再自动适应内容宽度,请用数字设置下拉宽度。
- Grid 组件使用 flex 布局。
- Button 的 `danger` 现在作为一个属性而不是按钮类型。
- Input、Select 的 `value``undefined` 时改为非受控状态。
## 开始升级

View File

@ -121,7 +121,7 @@
"rc-slider": "~9.0.0-alpha.0",
"rc-steps": "~3.5.0",
"rc-switch": "~1.9.0",
"rc-table": "~7.0.0-alpha.20",
"rc-table": "~7.0.0-rc.3",
"rc-tabs": "~10.0.0-alpha.1",
"rc-tooltip": "~4.0.0-alpha.3",
"rc-tree": "~3.0.0-alpha.37",
@ -152,6 +152,7 @@
"@types/prop-types": "^15.7.1",
"@types/raf": "^3.4.0",
"@types/react": "^16.9.0",
"@types/react-color": "^3.0.1",
"@types/react-dom": "^16.8.4",
"@types/shallowequal": "^1.1.1",
"@types/warning": "^3.0.0",
@ -191,11 +192,12 @@
"full-icu": "^1.3.0",
"glob": "^7.1.4",
"http-server": "^0.12.0",
"husky": "^4.0.0",
"husky": "^4.0.3",
"ignore-emit-webpack-plugin": "^2.0.2",
"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",

165
scripts/print-changelog.js Normal file
View File

@ -0,0 +1,165 @@
/* eslint-disable no-await-in-loop */
/* eslint-disable no-console */
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 || chinese || prTitle,
chinese: chinese || english || 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 */

View File

@ -83,19 +83,19 @@
&-codepen {
background: transparent
url('https://alipay-rmsdeploy-image.cn-hangzhou.alipay.aliyun-inc.com/antfincdn/R5sDUSunb1/OtZslpOjYXijshDERXwc.svg')
url('https://gw.alipayobjects.com/zos/antfincdn/1B3MOCiI5F/OtZslpOjYXijshDERXwc.svg')
center / 14px no-repeat;
}
&-riddle {
background: transparent
url('https://alipay-rmsdeploy-image.cn-hangzhou.alipay.aliyun-inc.com/antfincdn/sXMM9YD8lG/DlHbxMCyeuyOrqOdbgik.svg')
url('https://gw.alipayobjects.com/zos/antfincdn/NByOhhT9rO/DlHbxMCyeuyOrqOdbgik.svg')
center / 14px no-repeat;
}
&-codesandbox {
background: transparent
url('https://alipay-rmsdeploy-image.cn-hangzhou.alipay.aliyun-inc.com/antfincdn/7EZvNsaBkr/aaYmtdDyHSCkXyLZVgGK.svg')
url('https://gw.alipayobjects.com/zos/antfincdn/hNEf2p1ZnS/aaYmtdDyHSCkXyLZVgGK.svg')
center / 14px no-repeat;
}
}

View File

@ -1,21 +1,25 @@
import React, { Component } from 'react';
import { ChromePicker, SketchPicker } from 'react-color';
import { SketchPicker } from 'react-color';
const noop = () => {};
const pickers = {
chrome: ChromePicker,
sketch: SketchPicker,
};
interface ColorPickerProps {
color?: string;
small: boolean;
position: string;
presetColors?: string[];
onChange: (hex: string, color: { hex: string }) => void;
onChangeComplete: (hex: string) => void;
}
export default class ColorPicker extends Component {
export default class ColorPicker extends Component<ColorPickerProps> {
static defaultProps = {
onChange: noop,
onChangeComplete: noop,
position: 'bottom',
};
static getDerivedStateFromProps(props) {
static getDerivedStateFromProps(props: ColorPickerProps) {
if ('color' in props) {
return {
color: props.color,
@ -26,6 +30,7 @@ export default class ColorPicker extends Component {
state = {
displayColorPicker: false,
color: undefined,
};
handleClick = () => {
@ -37,29 +42,28 @@ export default class ColorPicker extends Component {
this.setState({ displayColorPicker: false });
};
handleChange = color => {
handleChange = (color: { hex: string }) => {
const { onChange } = this.props;
this.setState({ color: color.hex });
onChange(color.hex, color);
};
handleChangeComplete = color => {
handleChangeComplete = (color: { hex: string }) => {
const { onChangeComplete } = this.props;
this.setState({ color: color.hex });
onChangeComplete(color.hex);
};
render() {
const { small, type, position } = this.props;
const { small, position, presetColors } = this.props;
const { color, displayColorPicker } = this.state;
const Picker = pickers[type];
const styles = {
color: {
width: small ? '80px' : '120px',
height: small ? '16px' : '24px',
borderRadius: '2px',
background: color,
},
} as React.CSSProperties,
swatch: {
padding: '4px',
background: '#fff',
@ -67,22 +71,22 @@ export default class ColorPicker extends Component {
boxShadow: '0 0 0 1px rgba(0,0,0,.1)',
display: 'inline-block',
cursor: 'pointer',
},
} as React.CSSProperties,
popover: {
position: 'absolute',
zIndex: '2',
},
zIndex: 2,
} as React.CSSProperties,
cover: {
position: 'fixed',
top: '0px',
right: '0px',
bottom: '0px',
left: '0px',
},
} as React.CSSProperties,
wrapper: {
position: 'inherit',
zIndex: '100',
},
zIndex: 100,
} as React.CSSProperties,
};
if (position === 'top') {
@ -99,8 +103,8 @@ export default class ColorPicker extends Component {
<div style={styles.popover}>
<div style={styles.cover} onClick={this.handleClose} />
<div style={styles.wrapper}>
<Picker
{...this.props}
<SketchPicker
presetColors={presetColors}
color={color}
onChange={this.handleChange}
onChangeComplete={this.handleChangeComplete}

View File

@ -187,7 +187,7 @@ class ComponentDoc extends React.Component {
}
>
{visibleAll ? (
<BugFilled className={expandTriggerClass} onClick={this.handleVisibleToggle} />
<BugFilled style={{ display: 'none' }} className={expandTriggerClass} onClick={this.handleVisibleToggle} />
) : (
<BugOutlined className={expandTriggerClass} onClick={this.handleVisibleToggle} />
)}

View File

@ -346,7 +346,7 @@ ${sourceCode.replace('mountNode', "document.getElementById('container')")}
alt="expand code"
src={
theme === 'dark'
? 'https://alipay-rmsdeploy-image.cn-hangzhou.alipay.aliyun-inc.com/antfincdn/w9%264eQL2pY/wSAkBuJFbdxsosKKpqyq.svg'
? 'https://gw.alipayobjects.com/zos/antfincdn/btT3qDZn1U/wSAkBuJFbdxsosKKpqyq.svg'
: 'https://gw.alipayobjects.com/zos/rmsportal/wSAkBuJFbdxsosKKpqyq.svg'
}
className={codeExpand ? 'code-expand-icon-hide' : 'code-expand-icon-show'}
@ -356,7 +356,7 @@ ${sourceCode.replace('mountNode', "document.getElementById('container')")}
alt="expand code"
src={
theme === 'dark'
? 'https://alipay-rmsdeploy-image.cn-hangzhou.alipay.aliyun-inc.com/antfincdn/9bKgP0%26pT8/OpROPHYqWmrMDBFMZtKF.svg'
? 'https://gw.alipayobjects.com/zos/antfincdn/CjZPwcKUG3/OpROPHYqWmrMDBFMZtKF.svg'
: 'https://gw.alipayobjects.com/zos/rmsportal/OpROPHYqWmrMDBFMZtKF.svg'
}
className={codeExpand ? 'code-expand-icon-show' : 'code-expand-icon-hide'}

View File

@ -1,4 +0,0 @@
import * as React from 'react';
declare function Footer(): JSX.Element;
export default Footer;

View File

@ -1,5 +1,5 @@
import React from 'react';
import { FormattedMessage, injectIntl } from 'react-intl';
import { FormattedMessage, injectIntl, WrappedComponentProps } from 'react-intl';
import { Modal, message } from 'antd';
import { Link } from 'bisheng/router';
import RcFooter from 'rc-footer';
@ -22,7 +22,7 @@ import {
import { isLocalStorageNameSupported, loadScript, getLocalizedPathname } from '../utils';
import ColorPicker from '../Color/ColorPicker';
class Footer extends React.Component {
class Footer extends React.Component<WrappedComponentProps> {
lessLoaded = false;
state = {
@ -47,7 +47,7 @@ class Footer extends React.Component {
}
getColumns() {
const { intl = {} } = this.props;
const { intl } = this.props;
const isZhCN = intl.locale === 'zh-CN';
return [
{
@ -330,19 +330,24 @@ class Footer extends React.Component {
];
}
handleColorChange = color => {
handleColorChange = (color: string) => {
const {
intl: { messages },
} = this.props;
message.loading({
content: messages['app.footer.primary-color-changing'],
key: 'change-primary-color',
});
const changeColor = () => {
const {
intl: { messages },
} = this.props;
const hide = message.loading(messages['app.footer.primary-color-changing']);
window.less
(window as any).less
.modifyVars({
'@primary-color': color,
})
.then(() => {
hide();
message.success(messages['app.footer.primary-color-changed']);
message.success({
content: messages['app.footer.primary-color-changed'],
key: 'change-primary-color',
});
this.setState({ color });
});
};
@ -352,7 +357,7 @@ class Footer extends React.Component {
if (this.lessLoaded) {
changeColor();
} else {
window.less = {
(window as any).less = {
async: true,
javascriptEnabled: true,
};
@ -401,7 +406,6 @@ class Footer extends React.Component {
const colors = Object.keys(presetPalettes).filter(item => item !== 'grey');
return (
<ColorPicker
type="sketch"
small
color={color}
position="top"

View File

@ -1,12 +0,0 @@
export = Util;
export as namespace Util;
declare namespace Util {
function getMenuItems(...args: any[]): string;
function isZhCN(pathname: string): boolean;
function getLocalizedPathname(path: string, isChinese: boolean): string;
function ping(callback: Function): string;
function isLocalStorageNameSupported(): boolean;
function loadScript(src: string): void;
function getMetaDescription(jml: any): any;
}

View File

@ -1,11 +1,28 @@
import flattenDeep from 'lodash/flattenDeep';
import flatten from 'lodash/flatten';
export function getMenuItems(moduleData, locale, categoryOrder, typeOrder) {
interface Meta {
skip?: boolean;
category?: any;
type?: any;
title?: any;
order?: number;
children?: Meta[];
}
interface ModuleDataItem {
meta: Meta;
}
interface Orders {
[key: string]: number;
}
export function getMenuItems(moduleData: ModuleDataItem[], locale: string, categoryOrder: Orders, typeOrder: Orders) {
const menuMeta = moduleData.map(item => item.meta).filter(meta => !meta.skip);
const menuItems = [];
const sortFn = (a, b) => (a.order || 0) - (b.order || 0);
const menuItems: Meta[] = [];
const sortFn = (a: Meta, b: Meta) => (a.order || 0) - (b.order || 0);
menuMeta.sort(sortFn).forEach(meta => {
// Format
if (meta.category) {
@ -35,6 +52,7 @@ export function getMenuItems(moduleData, locale, categoryOrder, typeOrder) {
};
menuItems.push(type);
}
type.children = type.children || [];
type.children.push(meta);
return;
}
@ -51,6 +69,8 @@ export function getMenuItems(moduleData, locale, categoryOrder, typeOrder) {
menuItems.push(group);
}
group.children = group.children || [];
if (meta.type) {
let type = group.children.filter(i => i.title === meta.type)[0];
if (!type) {
@ -62,13 +82,14 @@ export function getMenuItems(moduleData, locale, categoryOrder, typeOrder) {
};
group.children.push(type);
}
type.children = type.children || [];
type.children.push(meta);
} else {
group.children.push(meta);
}
});
function nestSort(list) {
function nestSort(list: Meta[]): Meta[] {
return list.sort(sortFn).map(item => {
if (item.children) {
return {
@ -84,11 +105,11 @@ export function getMenuItems(moduleData, locale, categoryOrder, typeOrder) {
return nestSort(menuItems);
}
export function isZhCN(pathname) {
export function isZhCN(pathname: string) {
return /-cn\/?$/.test(pathname);
}
export function getLocalizedPathname(path, zhCN) {
export function getLocalizedPathname(path: string, zhCN: boolean) {
const pathname = path.startsWith('/') ? path : `/${path}`;
if (!zhCN) {
// to enUS
@ -103,7 +124,7 @@ export function getLocalizedPathname(path, zhCN) {
return `${pathname}-cn`;
}
export function ping(callback) {
export function ping(callback: (status: string) => void) {
// eslint-disable-next-line
const url =
'https://private-a' +
@ -112,8 +133,8 @@ export function ping(callback) {
'ay.com/alip' +
'ay-rmsdeploy-image/rmsportal/RKuAiriJqrUhyqW.png';
const img = new Image();
let done;
const finish = status => {
let done: boolean;
const finish = (status: string) => {
if (!done) {
done = true;
img.src = '';
@ -138,20 +159,22 @@ export function isLocalStorageNameSupported() {
}
}
export function loadScript(src) {
export function loadScript(src: string) {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.type = 'text/javascript';
script.src = src;
script.onload = resolve;
script.onerror = reject;
document.head.appendChild(script);
document.head!.appendChild(script);
});
}
export function getMetaDescription(jml) {
export function getMetaDescription(jml: any[]) {
const COMMON_TAGS = ['h1', 'h2', 'h3', 'p', 'img', 'a', 'code', 'strong'];
if (!Array.isArray(jml)) return '';
if (!Array.isArray(jml)) {
return '';
}
const paragraph = flattenDeep(
jml
.filter(item => {