From 5a8ae68fd04331e7622dcf5ebecd61d87bb066ec Mon Sep 17 00:00:00 2001 From: KgTong Date: Fri, 18 May 2018 15:55:01 +0800 Subject: [PATCH] Fix(inputitem): add wai-aria suppport for the money type InputItem (#2538) * Fix(inputitem): add wai-aria suppport for the money type InputItem The money type InputItem is simulated with the div tag, rather than the origin input tag. To support wai-aria needs a little more work, for the div tag, by adding role of `textbox` make div perform like input in aria mode For the CustomKeyboard, it will lead to wrong focus when not adding aria supoort for backspace and keyboard canceling Fixed: #2419, #2418 * Fix(inputitem): remove extra useless custom keyboard instance In the money type of InputItem, the CustomKeyboard will create as many times as the InputItem is used.The inner variable `customNumberKeyboard` will point to the latest custom keyboard instance which can avoid the repeat appearing animation. But when the InputItem is render async, since the `customNumberKeyboard` points to the latest custom keyboard instance, the operation for previous custom keyboard instance such as add hidden class will be invalid To Solve this problem, remove the useless instances of custom keyboard everytime one InputItem is being blured Fixed: #2475 --- components/input-item/CustomInput.tsx | 73 ++++++++++++++----- components/input-item/CustomKeyboard.tsx | 11 ++- components/input-item/Portal.tsx | 4 - .../__tests__/__snapshots__/demo.test.js.snap | 6 ++ components/input-item/index.tsx | 13 +++- components/input-item/locale/en_US.tsx | 2 + components/input-item/locale/ru_RU.tsx | 2 + components/input-item/locale/sv_SE.tsx | 2 + components/input-item/locale/zh_CN.tsx | 2 + .../__tests__/__snapshots__/demo.test.js.snap | 2 + components/modal/style/Dialog.less | 2 +- 11 files changed, 94 insertions(+), 25 deletions(-) diff --git a/components/input-item/CustomInput.tsx b/components/input-item/CustomInput.tsx index e55eb8dafb..e99a8790a4 100644 --- a/components/input-item/CustomInput.tsx +++ b/components/input-item/CustomInput.tsx @@ -6,8 +6,10 @@ import CustomKeyboard from './CustomKeyboard'; import Portal from './Portal'; import { InputEventHandler } from './PropsType'; -const IS_REACT_16 = !!ReactDOM.createPortal; +let instanceArr: any = []; let customNumberKeyboard: CustomKeyboard | null = null; +const IS_REACT_16 = !!ReactDOM.createPortal; + export interface NumberInputProps { placeholder?: string; disabled?: boolean; @@ -20,6 +22,8 @@ export interface NumberInputProps { onFocus?: InputEventHandler; onBlur?: InputEventHandler; confirmLabel: any; + backspaceLabel: any; + cancelKeyboardLabel: any; maxLength?: number; type?: string; style?: React.CSSProperties; @@ -61,7 +65,7 @@ class NumberInput extends React.Component { } } - componentDidMount() { + componentDidUpdate() { this.renderCustomKeyboard(); } @@ -82,38 +86,58 @@ class NumberInput extends React.Component { } saveRef = (el: CustomKeyboard | null) => { - if (IS_REACT_16) { + if (IS_REACT_16 && el) { customNumberKeyboard = el; + instanceArr.push({ el, container: this.container }); } } getComponent() { - const { keyboardPrefixCls, confirmLabel } = this.props; + const { + confirmLabel, + backspaceLabel, + cancelKeyboardLabel, + keyboardPrefixCls, + } = this.props; + return ( ); } getContainer() { - let container = document.querySelector( - `#${this.props.keyboardPrefixCls}-container`, - ); - if (!container) { - container = document.createElement('div'); - container.setAttribute('id', `${this.props.keyboardPrefixCls}-container`); - document.body.appendChild(container); + const { keyboardPrefixCls } = this.props; + + if (IS_REACT_16) { + if (!this.container) { + const container = document.createElement('div'); + container.setAttribute('id', `${keyboardPrefixCls}-container-${(new Date().getTime())}`); + document.body.appendChild(container); + this.container = container; + } + } else { + let container = document.querySelector( + `#${keyboardPrefixCls}-container`, + ); + if (!container) { + container = document.createElement('div'); + container.setAttribute('id', `${keyboardPrefixCls}-container`); + document.body.appendChild(container); + } + this.container = container; } - this.container = container; - return container; + return this.container; } renderCustomKeyboard() { - if (IS_REACT_16 || customNumberKeyboard) { + if (IS_REACT_16) { return; } customNumberKeyboard = ReactDOM.unstable_renderSubtreeIntoContainer( @@ -130,6 +154,16 @@ class NumberInput extends React.Component { } } + removeCurrentExtraKeyboard = () => { + instanceArr = instanceArr.filter((item: any) => { + const { el, container } = item; + if (el && container && el !== customNumberKeyboard) { + (container as any).parentNode.removeChild(container); + } + return el === customNumberKeyboard; + }); + } + unLinkInput = () => { if ( customNumberKeyboard && @@ -145,6 +179,10 @@ class NumberInput extends React.Component { } // for unmount this.removeBlurListener(); + + if (IS_REACT_16) { + this.removeCurrentExtraKeyboard(); + } } onInputBlur = (value: string) => { @@ -267,12 +305,11 @@ class NumberInput extends React.Component { return null; } - const portal = ( + return ( this.getContainer()}> {this.getComponent()} ); - return portal; } render() { @@ -294,6 +331,8 @@ class NumberInput extends React.Component {
{placeholder}
)}
(this.inputRef = el)} onClick={preventKeyboard ? () => {} : this.onFakeInputClick} diff --git a/components/input-item/CustomKeyboard.tsx b/components/input-item/CustomKeyboard.tsx index 9f91f3a30d..7959b37335 100644 --- a/components/input-item/CustomKeyboard.tsx +++ b/components/input-item/CustomKeyboard.tsx @@ -96,7 +96,12 @@ class CustomKeyboard extends React.Component { ); } render() { - const { prefixCls, confirmLabel } = this.props; + const { + prefixCls, + confirmLabel, + backspaceLabel, + cancelKeyboardLabel, + } = this.props; const wrapperCls = classnames( `${prefixCls}-wrapper`, @@ -113,6 +118,8 @@ class CustomKeyboard extends React.Component { this.renderKeyboardItem(item, index), )} { this.renderKeyboardItem(item, index), )} diff --git a/components/input-item/Portal.tsx b/components/input-item/Portal.tsx index fa040bcfb4..ec8c6ab563 100644 --- a/components/input-item/Portal.tsx +++ b/components/input-item/Portal.tsx @@ -13,10 +13,6 @@ export default class Portal extends React.Component { this.container = this.props.getContainer(); } - shouldComponentUpdate() { - return false; - } - render() { if (this.props.children) { return createPortal(this.props.children, this.container); diff --git a/components/input-item/__tests__/__snapshots__/demo.test.js.snap b/components/input-item/__tests__/__snapshots__/demo.test.js.snap index a2f45c46f9..6f0714d654 100644 --- a/components/input-item/__tests__/__snapshots__/demo.test.js.snap +++ b/components/input-item/__tests__/__snapshots__/demo.test.js.snap @@ -610,7 +610,9 @@ exports[`renders ./components/input-item/demo/money.md correctly 1`] = ` class="fake-input-container fake-input-container-left" >
100
@@ -644,7 +646,9 @@ exports[`renders ./components/input-item/demo/money.md correctly 1`] = ` start from right
@@ -673,7 +677,9 @@ exports[`renders ./components/input-item/demo/money.md correctly 1`] = ` money format
diff --git a/components/input-item/index.tsx b/components/input-item/index.tsx index 5d9d2bdc10..342e9d4233 100644 --- a/components/input-item/index.tsx +++ b/components/input-item/index.tsx @@ -224,9 +224,16 @@ class InputItem extends React.Component { () => require('./locale/zh_CN'), ); - const { confirmLabel } = _locale; + const { + confirmLabel, + backspaceLabel, + cancelKeyboardLabel, + } = _locale; - const { placeholder, focus } = this.state; + const { + focus, + placeholder, + } = this.state; const wrapCls = classnames( `${prefixListCls}-item`, @@ -297,6 +304,8 @@ class InputItem extends React.Component { prefixCls={prefixCls} style={style} confirmLabel={confirmLabel} + backspaceLabel={backspaceLabel} + cancelKeyboardLabel={cancelKeyboardLabel} moneyKeyboardAlign={moneyKeyboardAlign} /> ) : ( diff --git a/components/input-item/locale/en_US.tsx b/components/input-item/locale/en_US.tsx index 3481600007..d965453cb5 100644 --- a/components/input-item/locale/en_US.tsx +++ b/components/input-item/locale/en_US.tsx @@ -1,3 +1,5 @@ export default { confirmLabel: 'Done', + backspaceLabel: 'Backspace', + cancelKeyboardLabel: 'CancelKeyboard', }; diff --git a/components/input-item/locale/ru_RU.tsx b/components/input-item/locale/ru_RU.tsx index e0bd313076..0c28656482 100644 --- a/components/input-item/locale/ru_RU.tsx +++ b/components/input-item/locale/ru_RU.tsx @@ -1,3 +1,5 @@ export default { confirmLabel: 'Ок', + backspaceLabel: 'возврат на одну позицию', + cancelKeyboardLabel: 'Отменить клавиатуру', }; diff --git a/components/input-item/locale/sv_SE.tsx b/components/input-item/locale/sv_SE.tsx index 500952517d..7ea5435632 100644 --- a/components/input-item/locale/sv_SE.tsx +++ b/components/input-item/locale/sv_SE.tsx @@ -1,3 +1,5 @@ export default { confirmLabel: 'Ok', + backspaceLabel: 'Backspace', + cancelKeyboardLabel: 'CancelKeyboard', }; diff --git a/components/input-item/locale/zh_CN.tsx b/components/input-item/locale/zh_CN.tsx index 2fe615734f..4d064e8bf4 100644 --- a/components/input-item/locale/zh_CN.tsx +++ b/components/input-item/locale/zh_CN.tsx @@ -1,3 +1,5 @@ export default { confirmLabel: '确定', + backspaceLabel: '退格', + cancelKeyboardLabel: '撤销键盘', }; diff --git a/components/locale-provider/__tests__/__snapshots__/demo.test.js.snap b/components/locale-provider/__tests__/__snapshots__/demo.test.js.snap index 894a9677a3..a4c17982d9 100644 --- a/components/locale-provider/__tests__/__snapshots__/demo.test.js.snap +++ b/components/locale-provider/__tests__/__snapshots__/demo.test.js.snap @@ -174,7 +174,9 @@ exports[`renders ./components/locale-provider/demo/basic.md correctly 1`] = ` money input
diff --git a/components/modal/style/Dialog.less b/components/modal/style/Dialog.less index 1821f4f1e7..134b1b44f9 100644 --- a/components/modal/style/Dialog.less +++ b/components/modal/style/Dialog.less @@ -34,7 +34,7 @@ display: flex; align-items: center; justify-content: center; - // fixed a layer issue with animated Tabs in the x5 kernel browser + // fixed a layer issue with animated Tabs in the x5 kernel browser transform: translateZ(1px); &-popup { display: block;