UNPKG

@prosperitainova/dumbo-react-native

Version:
447 lines (444 loc) 14.9 kB
"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