@prosperitainova/dumbo-react-native
Version:
Dumbo for React Native Library
447 lines (444 loc) • 14.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getTextInputStyle = exports.BaseTextInput = void 0;
var _react = _interopRequireDefault(require("react"));
var _reactNative = require("react-native");
var _helpers = require("../../helpers");
var _colors = require("../../styles/colors");
var _Button = require("../Button");
var _Text = require("../Text");
var _ = _interopRequireDefault(require("@carbon/icons/es/view/20"));
var _2 = _interopRequireDefault(require("@carbon/icons/es/view--off/20"));
var _3 = _interopRequireDefault(require("@carbon/icons/es/subtract/20"));
var _4 = _interopRequireDefault(require("@carbon/icons/es/calendar/20"));
var _5 = _interopRequireDefault(require("@carbon/icons/es/warning--alt--filled/20"));
var _6 = _interopRequireDefault(require("@carbon/icons/es/warning--filled/20"));
var _7 = _interopRequireDefault(require("@carbon/icons/es/add/20"));
var _defaultText = require("../../constants/defaultText");
var _typography = require("../../styles/typography");
var _Link = require("../Link");
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** Props for the internal base text input */
/**
* Get the base styling for text inputs
*
* @param light - Indicate that light variant should be used
* @param hasLabelLink - Indicates that item has label with link
* @param fullBleed - Indicates that it should be full bleed style
*
* @returns React style item
*/
const getTextInputStyle = (light, hasLabelLink, fullBleed) => {
// React Native on iOS
const baseTextBox = {
...(0, _typography.BodyCompact02)(),
height: 48,
backgroundColor: (0, _colors.getColor)('field01'),
borderColor: (0, _colors.getColor)('field01'),
color: (0, _colors.getColor)('textPrimary'),
borderBottomColor: (0, _colors.getColor)('borderStrong02'),
borderWidth: 2,
borderBottomWidth: 1,
paddingRight: 16,
paddingLeft: 18
};
if (light) {
baseTextBox.backgroundColor = (0, _colors.getColor)('field02');
baseTextBox.borderColor = (0, _colors.getColor)('field02');
}
if (_reactNative.Platform.OS === 'ios') {
// https://github.com/facebook/react-native/issues/29068
// This seems to hide it but very hacky.
baseTextBox.paddingBottom = 2;
}
if (fullBleed) {
baseTextBox.backgroundColor = 'transparent';
baseTextBox.borderColor = undefined;
baseTextBox.borderWidth = undefined;
baseTextBox.borderBottomWidth = undefined;
baseTextBox.paddingLeft = 0;
baseTextBox.paddingRight = 0;
}
return {
wrapper: {
paddingTop: hasLabelLink ? undefined : 22
},
labelWrapper: {
flexDirection: 'row',
flexWrap: 'wrap'
},
label: {
color: (0, _colors.getColor)('textSecondary'),
flex: 1,
paddingTop: hasLabelLink ? 30 : undefined,
marginBottom: fullBleed ? 5 : 8
},
helperText: {
color: (0, _colors.getColor)('textHelper'),
marginTop: 8,
marginBottom: fullBleed ? 20 : undefined
},
errorText: {
color: (0, _colors.getColor)('textError'),
marginTop: 8,
marginBottom: fullBleed ? 20 : undefined
},
warningText: {
marginTop: 8,
marginBottom: fullBleed ? 20 : undefined
},
textBox: baseTextBox,
textBoxDisabled: {
...baseTextBox,
color: (0, _colors.getColor)('textDisabled'),
borderBottomColor: 'transparent'
},
textBoxActive: {
...baseTextBox,
borderStyle: 'solid',
borderColor: (0, _colors.getColor)('focus'),
borderBottomColor: (0, _colors.getColor)('focus'),
paddingRight: 14,
borderBottomWidth: 2
},
textBoxError: {
...baseTextBox,
borderStyle: 'solid',
borderColor: (0, _colors.getColor)('supportError'),
borderBottomColor: (0, _colors.getColor)('supportError'),
paddingRight: 14,
borderBottomWidth: 2
},
textBoxWrapper: {
position: 'relative'
},
passwordRevealButton: {
position: 'absolute',
top: 0,
right: 0
},
dateIcon: {
position: 'absolute',
padding: 13,
top: 0,
right: 0
},
errorIcon: {
position: 'absolute',
padding: 13,
top: fullBleed ? '100%' : 0,
right: 0
},
numberActions: {
position: 'absolute',
top: 0,
right: 0,
flexDirection: 'row'
},
numberActionsDivider: {
backgroundColor: (0, _colors.getColor)('layer02'),
width: 1,
height: 20,
marginTop: 14
},
numberActionsButton: {
padding: 14
},
labelLink: {
paddingBottom: 0,
paddingTop: 30
}
};
};
/**
* @ignore
* This is the base system for text input.
* This allows a shared code base for all text input systems and validation rules
* This component is not exported. It is used by `TextInput`, `TextArea` and `PasswordInput`.
*/
exports.getTextInputStyle = getTextInputStyle;
class BaseTextInput extends _react.default.Component {
state = {
dirty: false,
hasFocus: false,
revealPassword: false
};
get styles() {
const {
light,
labelLink,
fullBleedCallback
} = this.props;
return getTextInputStyle(light, !!labelLink, !!fullBleedCallback);
}
onFocus = event => {
const {
onFocus
} = this.props;
if (typeof onFocus === 'function') {
onFocus(event);
}
this.setState({
hasFocus: true
});
};
onBlur = event => {
const {
onBlur
} = this.props;
if (typeof onBlur === 'function') {
onBlur(event);
}
this.setState({
hasFocus: false
});
};
onChange = value => {
const {
onChangeText,
type,
numberRules
} = this.props;
if (type === 'number' && value) {
if (Number.isNaN(Number(value))) {
value = String(numberRules?.min || 0);
}
const invalidMin = typeof numberRules?.min === 'number' ? numberRules.min >= Number(value) : false;
const invalidMax = typeof numberRules?.max === 'number' ? numberRules.max <= Number(value) : false;
if (invalidMin) {
value = String(numberRules?.min || 0);
}
if (invalidMax) {
value = String(numberRules?.max || 0);
}
}
if (typeof onChangeText === 'function') {
onChangeText(value);
}
this.setState({
dirty: true
});
};
get passwordReveal() {
const {
revealPassword
} = this.state;
const {
togglePasswordText,
disabled
} = this.props;
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button.Button, {
overrideColor: disabled ? (0, _colors.getColor)('iconDisabled') : (0, _colors.getColor)('iconSecondary'),
disabled: disabled,
style: this.styles.passwordRevealButton,
iconOnlyMode: true,
kind: "ghost",
icon: revealPassword ? _2.default : _.default,
text: togglePasswordText || _defaultText.defaultText.passwordRevealButton,
onPress: () => this.setState({
revealPassword: !revealPassword
})
});
}
get dateIcon() {
const {
disabled
} = this.props;
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
style: this.styles.dateIcon,
children: (0, _helpers.createIcon)(_4.default, 20, 20, disabled ? (0, _colors.getColor)('iconDisabled') : (0, _colors.getColor)('iconSecondary'))
});
}
get baseErrorWarningStyle() {
const {
type
} = this.props;
const errorIconStyle = (0, _helpers.styleReferenceBreaker)(this.styles.errorIcon);
if (type === 'password' || type === 'date') {
errorIconStyle.right = 48;
errorIconStyle.paddingRight = 0;
errorIconStyle.paddingLeft = 0;
} else if (type === 'number') {
errorIconStyle.right = 97;
errorIconStyle.paddingRight = 0;
errorIconStyle.paddingLeft = 0;
}
return errorIconStyle;
}
get errorIndicator() {
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
style: this.baseErrorWarningStyle,
children: (0, _helpers.createIcon)(_6.default, 20, 20, (0, _colors.getColor)('supportError'))
});
}
get warningIndicator() {
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
style: this.baseErrorWarningStyle,
children: (0, _helpers.createIcon)(_5.default, 20, 20, (0, _colors.getColor)('supportWarning'))
});
}
incrementNumber = () => {
const {
value
} = this.props;
const valueNumber = Number.isNaN(Number(value)) ? 0 : Number(value);
this.onChange(String(valueNumber + 1));
};
decrementNumber = () => {
const {
value
} = this.props;
const valueNumber = Number.isNaN(Number(value)) ? 0 : Number(value);
this.onChange(String(valueNumber - 1));
};
get numberActions() {
const {
numberRules,
value,
disabled,
incrementNumberText,
decrementNumberText
} = this.props;
const valueNumber = Number.isNaN(Number(value)) ? 0 : Number(value);
const disableMin = typeof numberRules?.min === 'number' ? numberRules.min >= valueNumber : false;
const disableMax = typeof numberRules?.max === 'number' ? numberRules.max <= valueNumber : false;
const getStateStyle = state => {
return state.pressed ? {
backgroundColor: (0, _colors.getColor)('layerActive01')
} : undefined;
};
const getPressable = (onPress, pressableDisabled, icon, text) => {
const finalDisabled = pressableDisabled || disabled || false;
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
style: state => (0, _helpers.pressableFeedbackStyle)(state, this.styles.numberActionsButton, getStateStyle),
onPress: onPress,
disabled: finalDisabled,
accessibilityLabel: text,
accessibilityHint: value,
children: (0, _helpers.createIcon)(icon, 20, 20, finalDisabled ? (0, _colors.getColor)('iconDisabled') : (0, _colors.getColor)('iconPrimary'))
});
};
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
style: this.styles.numberActions,
children: [getPressable(this.decrementNumber, disableMin, _3.default, decrementNumberText || _defaultText.defaultText.decrementNumber), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
style: this.styles.numberActionsDivider
}), getPressable(this.incrementNumber, disableMax, _7.default, incrementNumberText || _defaultText.defaultText.incrementNumber)]
});
}
render() {
const {
label,
helperText,
getErrorText,
value,
autoCorrect,
autoCapitalize,
placeholder,
maxLength,
onSubmitEditing,
componentProps,
style,
required,
disabled,
isInvalid,
type,
textAreaMinHeight,
labelBreakMode,
labelLink,
fullBleedCallback,
warningText
} = this.props;
const {
hasFocus,
dirty,
revealPassword
} = this.state;
const password = type === 'password';
const textArea = type === 'text-area';
const date = type === 'date';
const number = type === 'number';
let textBoxStyle = (0, _helpers.styleReferenceBreaker)(this.styles.textBox);
const error = !!(required && dirty && !value) || dirty && typeof isInvalid === 'function' && isInvalid(value);
const fullBleedMode = typeof fullBleedCallback === 'function';
if (fullBleedMode) {
setTimeout(() => {
fullBleedCallback(hasFocus, error);
});
}
if (disabled) {
textBoxStyle = (0, _helpers.styleReferenceBreaker)(this.styles.textBoxDisabled);
} else if (error && !fullBleedMode) {
textBoxStyle = (0, _helpers.styleReferenceBreaker)(this.styles.textBoxError);
} else if (hasFocus && !fullBleedMode) {
textBoxStyle = (0, _helpers.styleReferenceBreaker)(this.styles.textBoxActive);
}
if (textArea) {
textBoxStyle.height = textAreaMinHeight || 144;
textBoxStyle.paddingTop = 12;
textBoxStyle.paddingBottom = 12;
textBoxStyle = (0, _helpers.styleReferenceBreaker)(textBoxStyle, (0, _typography.Body02)());
} else if (password || date) {
textBoxStyle.paddingRight = 50;
} else if (number) {
textBoxStyle.paddingRight = 100;
}
if (error) {
textBoxStyle.paddingRight = (Number(textBoxStyle.paddingRight) || 0) + 25;
}
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
style: (0, _helpers.styleReferenceBreaker)(this.styles.wrapper, style),
children: [!!(label || labelLink) && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
style: this.styles.labelWrapper,
children: [!!label && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Text.Text, {
style: this.styles.label,
type: "label-02",
text: label,
breakMode: labelBreakMode
}), !!labelLink && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Link.Link, {
...labelLink,
style: this.styles.labelLink,
textType: "label-02"
})]
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
style: this.styles.textBoxWrapper,
accessible: password,
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
editable: !disabled,
accessibilityLabel: helperText ? `${label} - ${helperText}` : label,
secureTextEntry: revealPassword ? false : password,
autoCapitalize: autoCapitalize,
style: textBoxStyle,
value: value,
onSubmitEditing: onSubmitEditing,
onChangeText: this.onChange,
autoCorrect: autoCorrect,
placeholder: placeholder,
placeholderTextColor: (0, _colors.getColor)('textPlaceholder'),
onBlur: this.onBlur,
onFocus: this.onFocus,
maxLength: maxLength,
textAlignVertical: "top",
multiline: textArea,
...(componentProps || {})
}), error && this.errorIndicator, !!(warningText && !error) && this.warningIndicator, password && this.passwordReveal, date && this.dateIcon, number && this.numberActions]
}), !!(helperText && !error && !warningText) && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Text.Text, {
style: this.styles.helperText,
type: "helper-text-02",
text: helperText
}), !!(typeof getErrorText === 'function' && error) && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Text.Text, {
style: this.styles.errorText,
type: "helper-text-02",
text: getErrorText(value)
}), !!(warningText && !error) && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Text.Text, {
style: this.styles.warningText,
type: "helper-text-02",
text: warningText
})]
});
}
}
exports.BaseTextInput = BaseTextInput;
//# sourceMappingURL=index.js.map