@wordpress/components
Version:
UI components for WordPress.
307 lines (262 loc) • 10.5 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _element = require("@wordpress/element");
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _reactNative = require("react-native");
var _lodash = require("lodash");
var _components = require("@wordpress/components");
var _icons = require("@wordpress/icons");
var _i18n = require("@wordpress/i18n");
var _compose = require("@wordpress/compose");
var _styles = _interopRequireDefault(require("./styles.scss"));
var _cellStyles = _interopRequireDefault(require("./cellStyles.scss"));
var _ripple = _interopRequireDefault(require("./ripple"));
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
class BottomSheetCell extends _element.Component {
constructor(props) {
super(...arguments);
this.state = {
isEditingValue: props.autoFocus || false,
isScreenReaderEnabled: false
};
this.handleScreenReaderToggled = this.handleScreenReaderToggled.bind(this);
this.isCurrent = false;
}
componentDidUpdate(prevProps, prevState) {
if (!prevState.isEditingValue && this.state.isEditingValue) {
this._valueTextInput.focus();
}
}
componentDidMount() {
this.isCurrent = true;
_reactNative.AccessibilityInfo.addEventListener('screenReaderChanged', this.handleScreenReaderToggled);
_reactNative.AccessibilityInfo.isScreenReaderEnabled().then(isScreenReaderEnabled => {
if (this.isCurrent) {
this.setState({
isScreenReaderEnabled
});
}
});
}
componentWillUnmount() {
this.isCurrent = false;
_reactNative.AccessibilityInfo.removeEventListener('screenReaderChanged', this.handleScreenReaderToggled);
}
handleScreenReaderToggled(isScreenReaderEnabled) {
this.setState({
isScreenReaderEnabled
});
}
typeToKeyboardType(type, step) {
let keyboardType = `default`;
if (type === `number`) {
if (step && Math.abs(step) < 1) {
keyboardType = `decimal-pad`;
} else {
keyboardType = `number-pad`;
}
}
return keyboardType;
}
render() {
const {
accessible,
accessibilityLabel,
accessibilityHint,
accessibilityRole,
disabled = false,
activeOpacity,
onPress,
onLongPress,
label,
value,
valuePlaceholder = '',
icon,
leftAlign,
labelStyle = {},
valueStyle = {},
cellContainerStyle = {},
cellRowContainerStyle = {},
onChangeValue,
onSubmit,
children,
editable = true,
isSelected = false,
separatorType,
style = {},
getStylesFromColorScheme,
customActionButton,
type,
step,
borderless,
...valueProps
} = this.props;
const showValue = value !== undefined;
const isValueEditable = editable && onChangeValue !== undefined;
const cellLabelStyle = getStylesFromColorScheme(_styles.default.cellLabel, _styles.default.cellTextDark);
const cellLabelCenteredStyle = getStylesFromColorScheme(_styles.default.cellLabelCentered, _styles.default.cellTextDark);
const cellLabelLeftAlignNoIconStyle = getStylesFromColorScheme(_styles.default.cellLabelLeftAlignNoIcon, _styles.default.cellTextDark);
const defaultMissingIconAndValue = leftAlign ? cellLabelLeftAlignNoIconStyle : cellLabelCenteredStyle;
const defaultLabelStyle = showValue || customActionButton || icon ? cellLabelStyle : defaultMissingIconAndValue;
const drawSeparator = separatorType && separatorType !== 'none' || separatorStyle === undefined;
const drawTopSeparator = drawSeparator && separatorType === 'topFullWidth';
const cellContainerStyles = [_styles.default.cellContainer, cellContainerStyle];
const rowContainerStyles = [_styles.default.cellRowContainer, cellRowContainerStyle];
const isInteractive = isValueEditable || onPress !== undefined || onLongPress !== undefined;
const onCellPress = () => {
if (isValueEditable) {
startEditing();
} else if (onPress !== undefined) {
onPress();
}
};
const finishEditing = () => {
this.setState({
isEditingValue: false
});
};
const startEditing = () => {
if (this.state.isEditingValue === false) {
this.setState({
isEditingValue: true
});
}
};
const separatorStyle = () => {
//eslint-disable-next-line @wordpress/no-unused-vars-before-return
const defaultSeparatorStyle = this.props.getStylesFromColorScheme(_styles.default.separator, _styles.default.separatorDark);
const cellSeparatorStyle = this.props.getStylesFromColorScheme(_styles.default.cellSeparator, _styles.default.cellSeparatorDark);
const leftMarginStyle = { ...cellSeparatorStyle,
..._cellStyles.default.separatorMarginLeft
};
switch (separatorType) {
case 'leftMargin':
return leftMarginStyle;
case 'fullWidth':
case 'topFullWidth':
return defaultSeparatorStyle;
case 'none':
return undefined;
case undefined:
if (showValue && icon) {
return leftMarginStyle;
}
return defaultSeparatorStyle;
}
};
const getValueComponent = () => {
const styleRTL = _reactNative.I18nManager.isRTL && _styles.default.cellValueRTL;
const cellValueStyle = this.props.getStylesFromColorScheme(_styles.default.cellValue, _styles.default.cellTextDark);
const finalStyle = { ...cellValueStyle,
...valueStyle,
...styleRTL
}; // To be able to show the `middle` ellipsizeMode on editable cells
// we show the TextInput just when the user wants to edit the value,
// and the Text component to display it.
// We also show the TextInput to display placeholder.
const shouldShowPlaceholder = isValueEditable && value === '';
return this.state.isEditingValue || shouldShowPlaceholder ? (0, _element.createElement)(_reactNative.TextInput, (0, _extends2.default)({
ref: c => this._valueTextInput = c,
numberOfLines: 1,
style: finalStyle,
value: value,
placeholder: valuePlaceholder,
placeholderTextColor: '#87a6bc',
onChangeText: onChangeValue,
editable: isValueEditable,
pointerEvents: this.state.isEditingValue ? 'auto' : 'none',
onFocus: startEditing,
onBlur: finishEditing,
onSubmitEditing: onSubmit,
keyboardType: this.typeToKeyboardType(type, step)
}, valueProps)) : (0, _element.createElement)(_reactNative.Text, {
style: { ...cellValueStyle,
...valueStyle
},
numberOfLines: 1,
ellipsizeMode: 'middle'
}, value);
};
const getAccessibilityLabel = () => {
if (accessible === false) {
return;
}
if (accessibilityLabel || !showValue) {
return accessibilityLabel || label;
}
return (0, _lodash.isEmpty)(value) ? (0, _i18n.sprintf)(
/* translators: accessibility text. Empty state of a inline textinput cell. %s: The cell's title */
(0, _i18n._x)('%s. Empty', 'inline textinput cell'), label) : // Separating by ',' is necessary to make a pause on urls (non-capitalized text)
(0, _i18n.sprintf)(
/* translators: accessibility text. Inline textinput title and value.%1: Cell title, %2: cell value. */
(0, _i18n._x)('%1$s, %2$s', 'inline textinput cell'), label, value);
};
const iconStyle = getStylesFromColorScheme(_styles.default.icon, _styles.default.iconDark);
const resetButtonStyle = getStylesFromColorScheme(_styles.default.resetButton, _styles.default.resetButtonDark);
const containerPointerEvents = this.state.isScreenReaderEnabled && accessible ? 'none' : 'auto';
const {
title,
handler
} = customActionButton || {};
const opacity = activeOpacity !== undefined ? activeOpacity : (0, _lodash.get)(_cellStyles.default, 'activeOpacity.opacity');
return (0, _element.createElement)(_ripple.default, {
accessible: accessible !== undefined ? accessible : !this.state.isEditingValue,
accessibilityLabel: getAccessibilityLabel(),
accessibilityRole: accessibilityRole || 'button',
accessibilityHint: isValueEditable ?
/* translators: accessibility text */
(0, _i18n.__)('Double tap to edit this value') : accessibilityHint,
disabled: disabled || !isInteractive,
activeOpacity: opacity,
onPress: onCellPress,
onLongPress: onLongPress,
style: [_styles.default.clipToBounds, style],
borderless: borderless
}, drawTopSeparator && (0, _element.createElement)(_reactNative.View, {
style: separatorStyle()
}), (0, _element.createElement)(_reactNative.View, {
style: cellContainerStyles,
pointerEvents: containerPointerEvents
}, (0, _element.createElement)(_reactNative.View, {
style: rowContainerStyles
}, (0, _element.createElement)(_reactNative.View, {
style: _styles.default.cellRowContainer
}, icon && (0, _element.createElement)(_reactNative.View, {
style: _styles.default.cellRowContainer
}, (0, _element.createElement)(_components.Icon, {
icon: icon,
size: 24,
fill: iconStyle.color,
isPressed: false
}), (0, _element.createElement)(_reactNative.View, {
style: _cellStyles.default.labelIconSeparator
})), label && (0, _element.createElement)(_reactNative.Text, {
style: [defaultLabelStyle, labelStyle]
}, label)), customActionButton && (0, _element.createElement)(_reactNative.TouchableOpacity, {
onPress: handler,
accessibilityRole: 'button'
}, (0, _element.createElement)(_reactNative.Text, {
style: resetButtonStyle
}, title))), isSelected && (0, _element.createElement)(_components.Icon, {
icon: _icons.check,
fill: _cellStyles.default.isSelected.color
}), showValue && getValueComponent(), children), !drawTopSeparator && (0, _element.createElement)(_reactNative.View, {
style: separatorStyle()
}));
}
}
var _default = (0, _compose.withPreferredColorScheme)(BottomSheetCell);
exports.default = _default;
//# sourceMappingURL=cell.native.js.map