Merge pull request #27477 from ant-design/feature-merge-master

chore: Feature merge master
This commit is contained in:
二货机器人 2020-10-30 21:17:03 +08:00 committed by GitHub
commit f6f3166108
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 182 additions and 141 deletions

View File

@ -1,6 +1,6 @@
name: test
on: [push]
on: [push, pull_request]
jobs:
setup:

28
.github/workflows/ui.yml vendored Normal file
View File

@ -0,0 +1,28 @@
name: UI
on:
pull_request_target:
push:
branches:
- master
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@master
- name: install
run: npm install
- name: test
run: npm run test-image
- name: argos-ci
if: github.event_name == 'pull_request_target'
run: npm run argos -- --token ${{ secrets.ARGOS_TOKEN }} --branch pull/${{ github.event.pull_request.number }}/merge --commit ${{ github.event.pull_request.head.sha }}
- name: argos-ci
if: github.event_name == 'push'
run: npm run argos -- --token ${{ secrets.ARGOS_TOKEN }} --branch ${GITHUB_REF##*/} --commit ${{ github.sha }}

View File

@ -1,11 +1,7 @@
name: Ant Design
trigger:
branches:
exclude:
- gh-pages
trigger: none
# https://developercommunity.visualstudio.com/comments/949241/view.html
pr:
autoCancel: true
branches:
@ -64,32 +60,3 @@ stages:
- script: |
node ./scripts/azure-github-comment.js "[<img width="534" src="https://user-images.githubusercontent.com/5378891/75333447-1e63a280-58c1-11ea-975d-235367fd1522.png">](https://dev.azure.com/ant-design/ant-design/_build/results?buildId=$(Build.BuildId))"
displayName: 'Comment on github'
- stage: ui
variables:
${{ if startsWith(variables['Build.SourceBranch'], 'refs/heads/') }}:
branchName: $[ replace(variables['Build.SourceBranch'], 'refs/heads/', '') ]
commitId: $(Build.SourceVersion)
${{ if startsWith(variables['Build.SourceBranch'], 'refs/pull/') }}:
branchName: $[ replace(variables['Build.SourceBranch'], 'refs/', '') ]
commitId: $(System.PullRequest.SourceCommitId)
dependsOn: []
jobs:
- job: UI_Test
steps:
- script: |
echo $(commitId)
- checkout: self
displayName: 'Checkout'
clean: true
fetchDepth: 1
- task: NodeTool@0
displayName: 'Install Node.js'
inputs:
versionSpec: '14.7.0'
- script: npm install
displayName: 'Install modules'
- script: npm run test-image
displayName: 'UI Test'
- script: npm run argos -- --token $ARGOS_TOKEN --branch $(branchName) --commit $(commitId)
displayName: 'Upload to argos-ci'

View File

@ -239,6 +239,8 @@
&-in-view&-range-hover-start:not(&-in-range):not(&-range-start):not(&-range-end),
&-in-view&-range-hover-end:not(&-in-range):not(&-range-start):not(&-range-end),
&-in-view&-range-hover-start&-range-start-single,
&-in-view&-range-hover-start&-range-start&-range-end&-range-end-near-hover,
&-in-view&-range-hover-end&-range-start&-range-end&-range-start-near-hover,
&-in-view&-range-hover-end&-range-end-single,
&-in-view&-range-hover:not(&-in-range) {
&::after {

View File

@ -7623,7 +7623,7 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
class="ant-form-item-control-input-content"
>
<span
class="ant-input-affix-wrapper"
class="ant-input-affix-wrapper ant-input-password"
>
<input
action="click"

View File

@ -12,6 +12,10 @@ export function hasPrefixSuffix(props: InputProps | ClearableInputProps) {
return !!(props.prefix || props.suffix || props.allowClear);
}
function hasAddon(props: InputProps | ClearableInputProps) {
return !!(props.addonBefore || props.addonAfter);
}
/**
* This basic props required for input and textarea.
*/
@ -121,8 +125,8 @@ class ClearableLabeledInput extends React.Component<ClearableInputProps> {
[`${prefixCls}-affix-wrapper-rtl`]: direction === 'rtl',
[`${prefixCls}-affix-wrapper-readonly`]: readOnly,
[`${prefixCls}-affix-wrapper-borderless`]: !bordered,
// https://github.com/ant-design/ant-design/issues/27258
[`${className}`]: !allowClear && className,
// className will go to addon wrapper
[`${className}`]: !hasAddon(this.props) && className,
});
return (
<span
@ -145,7 +149,7 @@ class ClearableLabeledInput extends React.Component<ClearableInputProps> {
renderInputWithLabel(prefixCls: string, labeledElement: React.ReactElement) {
const { addonBefore, addonAfter, style, size, className, direction } = this.props;
// Not wrap when there is not addons
if (!addonBefore && !addonAfter) {
if (!hasAddon(this.props)) {
return labeledElement;
}
@ -156,8 +160,7 @@ class ClearableLabeledInput extends React.Component<ClearableInputProps> {
) : null;
const addonAfterNode = addonAfter ? <span className={addonClassName}>{addonAfter}</span> : null;
const mergedWrapperClassName = classNames(`${prefixCls}-wrapper`, {
[wrapperClassName]: addonBefore || addonAfter,
const mergedWrapperClassName = classNames(`${prefixCls}-wrapper`, wrapperClassName, {
[`${wrapperClassName}-rtl`]: direction === 'rtl',
});
@ -197,8 +200,9 @@ class ClearableLabeledInput extends React.Component<ClearableInputProps> {
{
[`${prefixCls}-affix-wrapper-rtl`]: direction === 'rtl',
[`${prefixCls}-affix-wrapper-borderless`]: !bordered,
// className will go to addon wrapper
[`${className}`]: !hasAddon(this.props) && className,
},
className,
);
return (
<span className={affixWrapperCls} style={style}>

View File

@ -22,10 +22,8 @@ describe('Input.Search', () => {
});
it('should support ReactNode suffix without error', () => {
const fn = () => {
mount(<Search suffix={<div>ok</div>} />);
};
expect(fn).not.toThrow();
const wrapper = mount(<Search suffix={<div>ok</div>} />);
expect(wrapper.render()).toMatchSnapshot();
});
it('should disable enter button when disabled prop is true', () => {

View File

@ -45,6 +45,62 @@ exports[`Input.Search rtl render component should be rendered correctly in RTL d
</span>
`;
exports[`Input.Search should support ReactNode suffix without error 1`] = `
<span
class="ant-input-group-wrapper ant-input-search"
>
<span
class="ant-input-wrapper ant-input-group"
>
<span
class="ant-input-affix-wrapper"
>
<input
class="ant-input"
type="text"
value=""
/>
<span
class="ant-input-suffix"
>
<div>
ok
</div>
</span>
</span>
<span
class="ant-input-group-addon"
>
<button
class="ant-btn ant-btn-icon-only ant-input-search-button"
type="button"
>
<span
aria-label="search"
class="anticon anticon-search"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="search"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
/>
</svg>
</span>
</button>
</span>
</span>
</span>
`;
exports[`Input.Search should support addonAfter 1`] = `
<span
class="ant-input-group-wrapper ant-input-search"
@ -149,7 +205,7 @@ exports[`Input.Search should support addonAfter and suffix for loading 1`] = `
class="ant-input-wrapper ant-input-group"
>
<span
class="ant-input-affix-wrapper ant-input-search"
class="ant-input-affix-wrapper"
>
<input
class="ant-input"
@ -208,7 +264,7 @@ exports[`Input.Search should support addonAfter and suffix for loading 2`] = `
class="ant-input-wrapper ant-input-group"
>
<span
class="ant-input-affix-wrapper ant-input-search ant-input-search-with-button"
class="ant-input-affix-wrapper"
>
<input
class="ant-input"
@ -365,7 +421,7 @@ exports[`Input.Search should support invalid suffix 1`] = `
class="ant-input-wrapper ant-input-group"
>
<span
class="ant-input-affix-wrapper ant-input-search"
class="ant-input-affix-wrapper"
>
<input
class="ant-input"

View File

@ -2737,7 +2737,7 @@ Array [
class="ant-input-wrapper ant-input-group"
>
<span
class="ant-input-affix-wrapper ant-input-affix-wrapper-lg ant-input-search ant-input-search-large ant-input-search-with-button"
class="ant-input-affix-wrapper ant-input-affix-wrapper-lg"
>
<input
class="ant-input ant-input-lg"

View File

@ -354,57 +354,3 @@ exports[`Input should support size in form 1`] = `
</div>
</form>
`;
exports[`Input.Search should support suffix 1`] = `
<span
class="ant-input-group-wrapper ant-input-search"
>
<span
class="ant-input-wrapper ant-input-group"
>
<span
class="ant-input-affix-wrapper ant-input-search"
>
<input
class="ant-input"
type="text"
value=""
/>
<span
class="ant-input-suffix"
>
suffix
</span>
</span>
<span
class="ant-input-group-addon"
>
<button
class="ant-btn ant-btn-icon-only ant-input-search-button"
type="button"
>
<span
aria-label="search"
class="anticon anticon-search"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="search"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
/>
</svg>
</span>
</button>
</span>
</span>
</span>
`;

View File

@ -76,6 +76,20 @@ describe('Input', () => {
});
});
describe('prefix and suffix', () => {
it('should support className when has suffix', () => {
const wrapper = mount(<Input suffix="suffix" className="my-class-name" />);
expect(wrapper.getDOMNode().className.includes('my-class-name')).toBe(true);
expect(wrapper.find('input').getDOMNode().className.includes('my-class-name')).toBe(false);
});
it('should support className when has prefix', () => {
const wrapper = mount(<Input prefix="prefix" className="my-class-name" />);
expect(wrapper.getDOMNode().className.includes('my-class-name')).toBe(true);
expect(wrapper.find('input').getDOMNode().className.includes('my-class-name')).toBe(false);
});
});
describe('As Form Control', () => {
it('should be reset when wrapped in form.getFieldDecorator without initialValue', () => {
const Demo = () => {
@ -110,13 +124,6 @@ describe('As Form Control', () => {
});
});
describe('Input.Search', () => {
it('should support suffix', () => {
const wrapper = mount(<Input.Search suffix="suffix" />);
expect(wrapper.render()).toMatchSnapshot();
});
});
describe('Input allowClear', () => {
it('should change type when click', () => {
const wrapper = mount(<Input allowClear />);
@ -189,4 +196,11 @@ describe('Input allowClear', () => {
expect(wrapper.find('.ant-input-clear-icon-hidden').exists()).toBeTruthy();
});
});
// https://github.com/ant-design/ant-design/issues/27444
it('should support className', () => {
const wrapper = mount(<Input allowClear className="my-class-name" />);
expect(wrapper.getDOMNode().className.includes('my-class-name')).toBe(true);
expect(wrapper.find('input').getDOMNode().className.includes('my-class-name')).toBe(false);
});
});

View File

@ -33,6 +33,7 @@ const ConfirmDialog = (props: ConfirmDialogProps) => {
prefixCls,
rootPrefixCls,
bodyStyle,
modalRender,
} = props;
devWarning(
@ -95,6 +96,7 @@ const ConfirmDialog = (props: ConfirmDialogProps) => {
keyboard={keyboard}
centered={centered}
getContainer={getContainer}
modalRender={modalRender}
>
<div className={`${contentPrefixCls}-body-wrapper`}>
<ConfigProvider prefixCls={rootPrefixCls}>

View File

@ -80,6 +80,7 @@ export interface ModalProps {
wrapProps?: any;
prefixCls?: string;
closeIcon?: React.ReactNode;
modalRender?: (node: React.ReactNode) => React.ReactNode;
}
type getContainerFunc = () => HTMLElement;
@ -115,6 +116,7 @@ export interface ModalFuncProps {
maskTransitionName?: string;
direction?: string;
bodyStyle?: React.CSSProperties;
modalRender?: (node: React.ReactNode) => React.ReactNode;
}
export interface ModalLocale {

View File

@ -4,4 +4,4 @@ title: 组件总览
type: 组件总览
---
`antd` 为 Web 应用提供了丰富的基础 UI 组件,我们还将持续探索企业级应用的最佳 UI 实践。除了官方组件,我们也提供了[社区精选组件](/docs/react/recommendation)作为必要的补充。
`antd` 为 Web 应用提供了丰富的基础 UI 组件,我们还将持续探索企业级应用的最佳 UI 实践。除了官方组件,我们也提供了[社区精选组件](/docs/react/recommendation)作为必要的补充,另外如果您是内网用户,欢迎尝试使用 [TechUI](https://techui.alipay.com)

View File

@ -49,7 +49,7 @@ Select component to select value from options.
| mode | Set mode of Select | `multiple` \| `tags` | - | |
| notFoundContent | Specify content to show when no result matches | ReactNode | `Not Found` | |
| open | Controlled open state of dropdown | boolean | - | |
| optionFilterProp | Which prop value of option will be used for filter if filterOption is true | string | `value` | |
| optionFilterProp | Which prop value of option will be used for filter if filterOption is true. If `options` is set, it should be set to `label` | string | `value` | |
| optionLabelProp | Which prop value of option will render as content of select. [Example](https://codesandbox.io/s/antd-reproduction-template-tk678) | string | `children` | |
| options | Select options. Will get better perf than jsx definition | { label, value }\[] | - | |
| placeholder | Placeholder of select | ReactNode | - | |

View File

@ -50,8 +50,8 @@ cover: https://gw.alipayobjects.com/zos/alicdn/_0XzgOis7/Select.svg
| mode | 设置 Select 的模式为多选或标签 | `multiple` \| `tags` | - | |
| notFoundContent | 当下拉列表为空时显示的内容 | ReactNode | `Not Found` | |
| open | 是否展开下拉菜单 | boolean | - | |
| optionFilterProp | 搜索时过滤对应的 option 属性,如设置为 children 表示对内嵌内容进行搜索。[示例](https://codesandbox.io/s/antd-reproduction-template-tk678) | string | `value` | |
| optionLabelProp | 回填到选择框的 Option 的属性值,默认是 Option 的子元素。比如在子元素需要高亮效果时,此值可以设为 `value` | string | `children` | |
| optionFilterProp | 搜索时过滤对应的 `option` 属性,如设置为 `children` 表示对内嵌内容进行搜索。若通过 `options` 属性配置选项内容,建议设置 `optionFilterProp="label"` 来对内容进行搜索。 | string | `value` | |
| optionLabelProp | 回填到选择框的 Option 的属性值,默认是 Option 的子元素。比如在子元素需要高亮效果时,此值可以设为 `value`。[示例](https://codesandbox.io/s/antd-reproduction-template-tk678) | string | `children` | |
| options | 数据化配置选项内容,相比 jsx 定义会获得更好的渲染性能 | { label, value }\[] | - | |
| placeholder | 选择框默认文字 | string | - | |
| removeIcon | 自定义的多选框清除图标 | ReactNode | - | |

View File

@ -132,7 +132,7 @@ toc: false
### UI/UE 设计师
简历和作品集请投递lindong.lld#alipay.com
简历和作品集请投递lindong.lld#antgroup.com
> 注明简历来自 ant.design 官网
@ -146,13 +146,13 @@ toc: false
- 有数据驱动的增长设计实践,加分;
- 深度理解 SAP、Salesforce、Google 等设计体系,能提出自己独到见解并落实到实践中,加加加分。
- 岗位职责:
- 参与[蚂蚁金融科技](https://tech.antfin.com/)、[区块链](https://tech.antfin.com/blockchain)、人工智能等企业级产品的设计工作;
- 参与[蚂蚁链](https://blockchain.antgroup.com/)、人工智能、数据平台等企业级产品的设计工作;
- 参与[语雀](https://www.yuque.com/)、[云凤蝶](https://www.yunfengdie.com/)等创新产品的设计工作;
- 参与 Ant Design 的打磨,将其建设成全球卓越的设计体系。
- 参与 AntV 的打磨,将其建设成全球一流的数据可视化体系。
- One More Thing ❤️
- 你们总是为世界带去美好,但总是忘却你们也需要美好。我们正在努力打造 [🍳 Kitchen一款为设计师提效的 Sketch 工具集](https://kitchen.alipay.com/)、[语雀画板](https://yuque.com/) 等专属设计师的产品,让设计真正变成财富。期待志同道合的你,一道给设计行业带来「微小而美好的改变」。
- 你们总是为世界带去美好,但总是忘却你们也需要美好。我们正在努力打造 [🍳 Kitchen一款为设计师提效的 Sketch 工具集](https://kitchen.alipay.com/)等专属设计师的产品,让设计真正变成财富。期待志同道合的你,一道给设计行业带来「微小而美好的改变」。
### 前端工程师

View File

@ -218,7 +218,7 @@
"http-server": "^0.12.0",
"husky": "^4.0.3",
"identity-obj-proxy": "^3.0.0",
"ignore-emit-webpack-plugin": "^2.0.2",
"ignore-emit-webpack-plugin": "2.0.3",
"immutability-helper": "^3.0.0",
"inquirer": "^7.1.0",
"intersection-observer": "^0.11.0",

View File

@ -16,42 +16,40 @@ interface Recommend {
const LIST_CN: Recommend[] = [
{
title: '这几个 Ant Design 色彩的小知识,我猜你不知道',
description: '今天不说大道理,就给大家科普几个 Ant Design 色彩的小知识——',
img: 'https://pic4.zhimg.com/v2-254eebfe6b092b0b9c1f8d17f3c64d3d_1440w.jpg?source=172ae18b',
href: 'https://zhuanlan.zhihu.com/p/268168773',
title: '新一代 Ant Design未来已来邀你共建',
description: '欢迎加入Ant Designers',
img: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*yGcPRroihLQAAAAAAAAAAAAAARQnAQ',
href: 'https://zhuanlan.zhihu.com/p/269789439',
popularize: true,
},
{
title: '在Ant Design 4.0里,我们如何追求快乐的工作?',
description: '蚂蚁集团高级体验设计专家林外在上海外滩大会上分享 Ant Design4.0 背后的设计理念',
img: 'https://gw.alipayobjects.com/mdn/rms_b56775/afts/img/A*psuyRqopCIEAAAAAAAAAAAAAARQnAQ',
href: 'https://mp.weixin.qq.com/s/QUqy1-g0FElqOs9cQFFWHA',
},
{
title: '第十五届 D2 前端技术论坛 - 无界',
description: '前端热爱,技术无界,第十五届 D2 前端技术论坛,我们云端相聚!',
img: 'https://img.alicdn.com/tfs/TB1R39KnSR26e4jSZFEXXbwuXXa-1960-768.png',
href: 'http://d2forum.alibaba-inc.com/',
},
{
title: 'Ant Design 4.0 的一些杂事儿 - VirtualList 篇',
description:
'在 React 中,我们常说不太需要关注性能问题。然而作为组件库,这些事你就不得不考虑一下。',
img: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*ULOBQroFRMQAAAAAAAAAAAAAARQnAQ',
href: 'https://zhuanlan.zhihu.com/p/237996796',
},
];
const LIST_EN: Recommend[] = [
{
title: 'These a few color knowledge of Ant Design, I guess you do not know!',
description:
'🎨 This time, we do not talk about theoretical knowledge, just a few color design skills of Ant Design',
img: 'https://pic4.zhimg.com/v2-254eebfe6b092b0b9c1f8d17f3c64d3d_1440w.jpg?source=172ae18b',
href: 'https://zhuanlan.zhihu.com/p/268168773',
title: 'New generation of Ant Design, the future is coming, let us create it together!',
description: 'Welcome to join usAnt Designers',
img: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*yGcPRroihLQAAAAAAAAAAAAAARQnAQ',
href: 'https://zhuanlan.zhihu.com/p/269789439',
popularize: true,
},
{
title: 'Next Generation of Component Library?',
title: 'How do we pursue happy work in Ant Design 4.0?',
description:
'😎 With the launch of React hooks and Vue composition API, perhaps we have met a new breakthrough point of component libraries.',
img: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*SU6hQ5jHVEsAAAAAAAAAAAAAARQnAQ',
href: 'https://zhuanlan.zhihu.com/p/252824872',
'Ant group senior experience design expert Lin Wai shares the design concept behind Ant Design 4.0',
img: 'https://gw.alipayobjects.com/mdn/rms_b56775/afts/img/A*psuyRqopCIEAAAAAAAAAAAAAARQnAQ',
href: 'https://mp.weixin.qq.com/s/QUqy1-g0FElqOs9cQFFWHA',
},
{
title: 'Stories about Ant Design 4.0: VirtualList',

View File

@ -77,7 +77,7 @@ const Home = (props: { location: any }) => {
<BlockContent
title={<FormattedMessage id="app.home.more" />}
extra={
<Link to={getLink()}>
<Link to={getLink()} target="_blank">
<FormattedMessage id="app.home.view-more" />
</Link>
}

View File

@ -17,6 +17,7 @@ export interface NavigationProps extends SharedProps {
responsive: null | 'narrow' | 'crowded';
location: { pathname: string; query: any };
directionText: string;
showTechUIButton: boolean;
onLangChange: () => void;
onDirectionChange: () => void;
}
@ -29,6 +30,7 @@ export default ({
responsive,
location,
directionText,
showTechUIButton,
onLangChange,
onDirectionChange,
}: NavigationProps) => {
@ -100,6 +102,13 @@ export default ({
<FormattedMessage id="app.header.menu.resource" />
</Link>
</Menu.Item>
{showTechUIButton && (
<Menu.Item key="tech-ui">
<a href="https://techui.alipay.com" target="__blank" rel="noopener noreferrer">
TechUI
</a>
</Menu.Item>
)}
{isZhCN && !isGitee && (
<Menu.Item key="mirror">
<a href="https://ant-design.gitee.io"></a>

View File

@ -12,6 +12,7 @@ import More from './More';
import Navigation from './Navigation';
import Github from './Github';
import SiteContext from '../SiteContext';
import { ping } from '../../utils';
import './index.less';
@ -61,15 +62,19 @@ interface HeaderState {
menuVisible: boolean;
windowWidth: number;
searching: boolean;
showTechUIButton: boolean;
}
class Header extends React.Component<HeaderProps, HeaderState> {
static contextType = SiteContext;
pingTimer: NodeJS.Timeout;
state = {
menuVisible: false,
windowWidth: 1400,
searching: false,
showTechUIButton: false,
};
componentDidMount() {
@ -79,10 +84,19 @@ class Header extends React.Component<HeaderProps, HeaderState> {
window.addEventListener('resize', this.onWindowResize);
this.onWindowResize();
this.pingTimer = ping(status => {
if (status !== 'timeout' && status !== 'error') {
this.setState({
showTechUIButton: true,
});
}
});
}
componentWillUnmount() {
window.removeEventListener('resize', this.onWindowResize);
clearTimeout(this.pingTimer);
}
onWindowResize = () => {
@ -179,7 +193,7 @@ class Header extends React.Component<HeaderProps, HeaderState> {
return (
<SiteContext.Consumer>
{({ isMobile }) => {
const { menuVisible, windowWidth, searching } = this.state;
const { menuVisible, windowWidth, searching, showTechUIButton } = this.state;
const { direction } = this.context;
const {
location,
@ -232,6 +246,7 @@ class Header extends React.Component<HeaderProps, HeaderState> {
location={location}
responsive={responsive}
isMobile={isMobile}
showTechUIButton={showTechUIButton}
pathname={pathname}
directionText={this.getNextDirectionText()}
onLangChange={this.onLangChange}