UNPKG

vcc-ui

Version:

A React library for building user interfaces at Volvo Cars

212 lines (210 loc) 6.7 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.TextInput = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _propTypes = require("prop-types"); var _react = _interopRequireDefault(require("react")); var _reactFela = require("react-fela"); var _autoId = require("../../utils/auto-id"); var _block = require("../block"); var _flex = require("../flex"); var _message = require("../message"); var _spacer = require("../spacer"); var _spinner = require("../spinner"); const defaultStyles = _ref => { let { theme, disabled, loading, isValid } = _ref; return { appearance: 'none', borderWidth: 1, borderStyle: 'solid', borderRadius: 4, boxSizing: 'border-box', display: 'block', width: '100%', margin: 0, outlineWidth: 0, paddingTop: theme.tokens.inputPaddingVertical * 2, paddingBottom: theme.tokens.inputPaddingVertical / 2, paddingLeft: theme.tokens.inputPaddingHorizontal - 1, paddingRight: theme.tokens.inputPaddingHorizontal - 1, borderColor: theme.tokens.inputBorder, color: theme.tokens.inputForeground, background: theme.tokens.inputBackground, ...theme.typeScale.columbus.standard.styles, '::placeholder': { color: 'transparent' }, '&[type="date"][value=""]:not(:focus)': { color: 'transparent' }, ':focus': { borderColor: theme.tokens.inputBorderFocus, '::placeholder': { color: theme.tokens.inputPlaceholder } }, extend: [{ condition: loading, style: { userSelect: 'none' } }, { condition: disabled, style: { ':disabled': { cursor: 'not-allowed', borderColor: theme.tokens.inputDisabledBorder, backgroundColor: theme.tokens.inputDisabledBackground, color: theme.tokens.inputForeground } } }, { condition: !isValid, style: { ':not(:focus)': { borderWidth: 2, borderColor: theme.color.foreground.alert, paddingTop: theme.tokens.inputPaddingVertical * 2 - 1, paddingBottom: theme.tokens.inputPaddingVertical / 2 - 1, paddingLeft: theme.tokens.inputPaddingHorizontal - 2, paddingRight: theme.tokens.inputPaddingHorizontal - 2 } } }] }; }; const labelStyle = _ref2 => { let { isEmpty, isValid, theme } = _ref2; return { paddingLeft: theme.tokens.inputPaddingHorizontal, paddingRight: theme.tokens.inputPaddingHorizontal, color: isValid ? theme.color.foreground.secondary : theme.color.foreground.alert, transitionProperty: 'font-size, transform', transitionDuration: '60ms', transitionTimingFunction: 'ease-out', transform: 'translateY(' + (isEmpty ? 17 : 8) + 'px)', fontSize: isEmpty ? 16 : 12, letterSpacing: '0.02em', fontFamily: theme.fontTypes.NOVUM, fontWeight: 300, position: 'absolute', pointerEvents: 'none', top: 0 }; }; /** * @deprecated Use `import { TextInput } from '@volvo-cars/react-forms'` instead. See [TextInput](https://developer.volvocars.com/design-system/web/?path=/docs/components-forms-input-textinput--docs) */ const TextInput = exports.TextInput = /*#__PURE__*/_react.default.forwardRef((_ref3, ref) => { let { onChange, type, value = '', isValid = true, label = '', description = '', errorMessage = '', loading = false, disabled = false, ...props } = _ref3; const { theme } = (0, _reactFela.useFela)(); const isEmpty = (value || '').length === 0; const styleProps = { isEmpty, isValid, disabled, loading, theme }; const id = (0, _autoId.useId)('vcc-ui-text-input', props.id); const errorMessageId = (0, _autoId.makeId)(id, 'error'); const descriptionId = (0, _autoId.makeId)(id, 'description'); const describedBy = (0, _autoId.makeIdList)([errorMessage && errorMessageId, description && descriptionId]); const messages = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, errorMessage || description ? /*#__PURE__*/_react.default.createElement(_spacer.Spacer, { size: 0.5 }) : null, errorMessage ? /*#__PURE__*/_react.default.createElement(_message.Message, { type: "error", id: errorMessageId }, errorMessage) : null, description ? /*#__PURE__*/_react.default.createElement(_message.Message, { id: descriptionId }, description) : null); return /*#__PURE__*/_react.default.createElement(_flex.Flex, { extend: { flexDirection: 'column', width: '100%', ':focus-within label': { transform: 'translateY(8px)', fontSize: 12 } } }, /*#__PURE__*/_react.default.createElement(_flex.Flex, { extend: { position: 'relative' } }, loading && /*#__PURE__*/_react.default.createElement(_flex.Flex, { extend: { position: 'absolute', width: '100%', height: '100%', alignItems: 'center', justifyContent: 'center' } }, /*#__PURE__*/_react.default.createElement(_spinner.Spinner, { color: theme.tokens.inputForeground, size: 24 })), !loading ? /*#__PURE__*/_react.default.createElement(_block.Block, { as: "label", htmlFor: id, extend: labelStyle(styleProps) }, label) : null, /*#__PURE__*/_react.default.createElement(_block.Block, (0, _extends2.default)({}, props, { ref: ref, as: "input", value: loading ? '' : value, disabled: disabled || loading, type: type, id: id, onChange: onChange, extend: defaultStyles(styleProps) }, describedBy && { 'aria-describedby': describedBy }))), messages); }); TextInput.displayName = 'TextInput'; TextInput.propTypes = { type: _propTypes.string, id: _propTypes.string, name: _propTypes.string, /** Renders a label inside the input. */ label: _propTypes.string.isRequired, /** Renders a description text underneath the input. */ description: _propTypes.string, /** Renders a red error message for validation underneath the input. */ errorMessage: _propTypes.string, /** onChange handler. Triggers on every keyboard and generally * is here where you change the value of the `value` property. */ onChange: _propTypes.func.isRequired, /** * Value of the textInput. This should be stored in the * state of the parent component. */ value: _propTypes.string.isRequired, /** Renders the input as valid or invalid. */ isValid: _propTypes.bool, loading: _propTypes.bool, disabled: _propTypes.bool };