import PropTypes from 'prop-types';
import React from 'react';
import { TextInput } from 'react-native';
import Prompt from 'react-native-prompt';
import { connect } from 'react-redux';
import { translate } from '../../i18n';
import AbstractDialog from './AbstractDialog';
/**
* Implements AbstractDialog on react-native using Prompt.
*/
class Dialog extends AbstractDialog {
/**
* AbstractDialog's React Component prop types.
*
* @static
*/
static propTypes = {
...AbstractDialog.propTypes,
/**
* I18n key to put as body title.
*/
bodyKey: PropTypes.string
};
/**
* Implements React's {@link Component#render()}.
*
* @inheritdoc
* @returns {ReactElement}
*/
render() {
const {
bodyKey,
cancelDisabled,
cancelTitleKey = 'dialog.Cancel',
children,
okDisabled,
okTitleKey = 'dialog.Ok',
t,
titleKey,
titleString
} = this.props;
/* eslint-disable react/jsx-wrap-multilines */
let element
= ;
/* eslint-enable react/jsx-wrap-multilines */
if (React.Children.count(children)) {
// XXX The following implements a workaround with knowledge of the
// implementation of react-native-prompt.
element
= this._replaceFirstElementOfType(
// eslint-disable-next-line no-extra-parens, new-cap
(new (element.type)(element.props)).render(),
TextInput,
children);
}
return element;
}
/**
* Creates a deep clone of a specific ReactElement with the results
* of calling a specific function on every node of a specific
* ReactElement tree.
*
* @param {ReactElement} element - The ReactElement to clone and
* call the specified f on.
* @param {Function} f - The function to call on every node of the
* ReactElement tree represented by the specified element.
* @private
* @returns {ReactElement}
*/
_mapReactElement(element, f) {
if (!element || !element.props || !element.type) {
return element;
}
let mapped = f(element);
if (mapped === element) {
mapped
= React.cloneElement(
element,
/* props */ undefined,
...React.Children.toArray(React.Children.map(
element.props.children,
function(element) { // eslint-disable-line no-shadow
// eslint-disable-next-line no-invalid-this
return this._mapReactElement(element, f);
},
this)));
}
return mapped;
}
/**
* Replaces the first ReactElement of a specific type found in a
* specific ReactElement tree with a specific replacement
* ReactElement.
*
* @param {ReactElement} element - The ReactElement tree to search
* through and replace in.
* @param {*} type - The type of the ReactElement to be replaced.
* @param {ReactElement} replacement - The ReactElement to replace
* the first ReactElement in element of the specified
* type.
* @private
* @returns {ReactElement}
*/
_replaceFirstElementOfType(element, type, replacement) {
// eslint-disable-next-line no-shadow
return this._mapReactElement(element, element => {
if (replacement && element.type === type) {
/* eslint-disable no-param-reassign */
element = replacement;
replacement = undefined;
/* eslint-enable no-param-reassign */
}
return element;
});
}
}
export default translate(connect()(Dialog));