UNPKG

wix-style-react

Version:
407 lines (405 loc) • 15.2 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.default = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _propTypes = _interopRequireDefault(require("prop-types")); var _react = _interopRequireDefault(require("react")); var _InfoIcon = _interopRequireDefault(require("../InfoIcon")); var _uniqueId = _interopRequireDefault(require("lodash/uniqueId")); var _Text = _interopRequireWildcard(require("../Text")); var _constants = require("./constants"); var _FormFieldSt = require("./FormField.st.css"); var _TooltipCommon = require("../common/PropTypes/TooltipCommon"); var _wixUiIconsCommon = require("@wix/wix-ui-icons-common"); var _StatusContext = require("./StatusContext"); var _jsxFileName = "/home/builduser/work/a9c1ac8876d5057c/packages/wix-style-react/dist/cjs/FormField/FormField.js"; function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } var PLACEMENT = { top: 'top', right: 'right', left: 'left' }; var ALIGN = { middle: 'middle', top: 'top' }; var LABEL_STYLE = { display: 'block' // allows the label to middle vertically }; var STATUS = { error: 'error', warning: 'warning', loading: 'loading' }; var asterisk = /*#__PURE__*/_react.default.createElement("div", { "data-hook": _constants.dataHooks.asterisk, className: _FormFieldSt.classes.asterisk, children: "*", __self: void 0, __source: { fileName: _jsxFileName, lineNumber: 37, columnNumber: 3 } }); class FormField extends _react.default.Component { constructor(props) { super(props); this.state = { lengthLeft: undefined }; this.childrenRenderPropInterface = { setCharactersLeft: lengthLeft => this.setState({ lengthLeft }) }; this._hasCharCounter = () => this.props.charCount !== undefined || typeof this.state.lengthLeft === 'number'; this.charactersLeft = lengthLeft => { var { labelSize } = this.props; var colorProps = lengthLeft >= 0 ? { light: true, secondary: true } : { skin: _Text.SKINS.error }; return /*#__PURE__*/_react.default.createElement(_Text.default, (0, _extends2.default)({ className: (0, _FormFieldSt.st)(_FormFieldSt.classes.charCount, { labelSize }), size: _Text.SIZES.small, weight: _Text.WEIGHTS.normal }, colorProps, { dataHook: _constants.dataHooks.counter, children: lengthLeft, __self: this, __source: { fileName: _jsxFileName, lineNumber: 163, columnNumber: 7 } })); }; this._renderCharCounter = () => { if (!this._hasCharCounter()) { return; } var { charCount } = this.props; return this.charactersLeft(charCount !== undefined ? charCount : this.state.lengthLeft); }; this._renderInfoIcon = () => { var { infoContent, infoTooltipProps } = this.props; return infoContent && /*#__PURE__*/_react.default.createElement(_InfoIcon.default, { dataHook: _constants.dataHooks.infoIcon, className: _FormFieldSt.classes.infoIcon, content: infoContent, tooltipProps: infoTooltipProps, size: "small", __self: this, __source: { fileName: _jsxFileName, lineNumber: 189, columnNumber: 9 } }); }; this._renderLabelWithIndicators = _ref => { var { labelSize } = _ref; var { required, suffix } = this.props; return /*#__PURE__*/_react.default.createElement("div", { "data-hook": _constants.dataHooks.labelIndicators, className: (0, _FormFieldSt.st)(_FormFieldSt.classes.labelIndicators, { inlineWithSuffix: Boolean(suffix || this._hasCharCounter()) }), __self: this, __source: { fileName: _jsxFileName, lineNumber: 204, columnNumber: 7 } }, this._renderLabel({ trimLongText: false, labelSize }), required && asterisk, this._renderInfoIcon()); }; this._renderSuffix = () => { var { suffix } = this.props; return (suffix || this._hasCharCounter()) && /*#__PURE__*/_react.default.createElement("div", { "data-hook": _constants.dataHooks.suffix, className: (0, _FormFieldSt.st)(_FormFieldSt.classes.suffix, { noLabel: !this.props.label || this.props.labelPlacement !== PLACEMENT.top }), __self: this, __source: { fileName: _jsxFileName, lineNumber: 222, columnNumber: 9 } }, suffix ? suffix : this._renderCharCounter()); }; this._hasInlineElements = (label, labelPlacement) => { var hasInlineLabel = label && (labelPlacement === PLACEMENT.left || labelPlacement === PLACEMENT.right); var hasInlineIndicator = !label && (this.props.required || !!this.props.infoContent); return hasInlineLabel || hasInlineIndicator; }; this._renderLabel = _ref2 => { var { trimLongText, labelSize } = _ref2; var { label, id } = this.props; var weight = labelSize === 'tiny' ? 'normal' : undefined; return /*#__PURE__*/_react.default.createElement(_Text.default, { size: labelSize, weight: weight, htmlFor: id, id: this.labelId, tagName: "label", dataHook: _constants.dataHooks.label, ellipsis: trimLongText, style: LABEL_STYLE, secondary: true, className: (0, _FormFieldSt.st)(_FormFieldSt.classes.label, { labelSize }), __self: this, __source: { fileName: _jsxFileName, lineNumber: 249, columnNumber: 7 } }, label); }; this._renderStatusIcon = () => { var iconByStatus = { [STATUS.error]: _wixUiIconsCommon.StatusAlertFilledSmall, [STATUS.warning]: _wixUiIconsCommon.StatusWarningFilledSmall }; var Icon = iconByStatus[this.props.status]; return /*#__PURE__*/_react.default.createElement("div", { className: _FormFieldSt.classes.statusIcon, __self: this, __source: { fileName: _jsxFileName, lineNumber: 276, columnNumber: 7 } }, /*#__PURE__*/_react.default.createElement(Icon, { __self: this, __source: { fileName: _jsxFileName, lineNumber: 277, columnNumber: 9 } })); }; this._renderStatusMessage = () => { var { statusMessage, status, labelSize } = this.props; return /*#__PURE__*/_react.default.createElement("div", { className: (0, _FormFieldSt.st)(_FormFieldSt.classes.statusMessage, { status, labelSize }), __self: this, __source: { fileName: _jsxFileName, lineNumber: 286, columnNumber: 7 } }, (status === STATUS.error || status === STATUS.warning) && this._renderStatusIcon(), /*#__PURE__*/_react.default.createElement(_Text.default, { id: this.statusId, dataHook: _constants.dataHooks.statusMessage, skin: status === STATUS.error ? 'error' : 'standard', secondary: status !== STATUS.error, size: labelSize, __self: this, __source: { fileName: _jsxFileName, lineNumber: 294, columnNumber: 9 } }, statusMessage)); }; this.labelId = props.labelId || (0, _uniqueId.default)('formfield-'); this.statusId = props.labelId ? "".concat(props.labelId, "-status") : (0, _uniqueId.default)('formfield-status-'); } _renderChildren() { var { children } = this.props; if (typeof children === 'function') { return children(this.childrenRenderPropInterface); } return children; } render() { var { label, labelPlacement, labelAlignment, labelSize, required, dataHook, children, classNames, stretchContent, statusMessage, status } = this.props; var rootStyles = label ? { labelPlacement, labelAlignment, stretchContent, required, minLabelHeight: !children } : { stretchContent, required, minLabelHeight: !children }; var hasInlineElements = this._hasInlineElements(label, labelPlacement); return /*#__PURE__*/_react.default.createElement("div", { "data-hook": dataHook, "data-status": status, className: (0, _FormFieldSt.st)(_FormFieldSt.classes.root, _objectSpread(_objectSpread(_objectSpread({}, rootStyles), label ? { labelSize } : {}), {}, { hasInlineElements }), classNames), __self: this, __source: { fileName: _jsxFileName, lineNumber: 339, columnNumber: 7 } }, label && labelPlacement === PLACEMENT.top && /*#__PURE__*/_react.default.createElement("div", { className: _FormFieldSt.classes.labelRow, __self: this, __source: { fileName: _jsxFileName, lineNumber: 349, columnNumber: 11 } }, /*#__PURE__*/_react.default.createElement("div", { className: _FormFieldSt.classes.labelRowMain, __self: this, __source: { fileName: _jsxFileName, lineNumber: 350, columnNumber: 13 } }, this._renderLabel({ trimLongText: true, labelSize }), required && asterisk, this._renderInfoIcon()), this._renderSuffix()), children && /*#__PURE__*/_react.default.createElement("div", { "data-hook": _constants.dataHooks.children, className: (0, _FormFieldSt.st)(_FormFieldSt.classes.children, { childrenWithInlineLabel: hasInlineElements }), __self: this, __source: { fileName: _jsxFileName, lineNumber: 360, columnNumber: 11 } }, (!label || labelPlacement !== PLACEMENT.top) && this._renderSuffix(), /*#__PURE__*/_react.default.createElement(_StatusContext.StatusContext.Provider, { value: { status, ariaLabelledBy: this.labelId, ariaDescribedBy: this.statusId }, __self: this, __source: { fileName: _jsxFileName, lineNumber: 369, columnNumber: 13 } }, this._renderChildren())), hasInlineElements && this._renderLabelWithIndicators({ labelSize }), statusMessage && this._renderStatusMessage()); } } FormField.displayName = 'FormField'; FormField.propTypes = { /** when function, it receives object with: * * `setCharactersLeft` - function accepts a number and will display it on top right of `FormField` component * * Note that alternatively you can also use `charCount` prop to display character count * instead of using the render function method. */ /** Accept any kind of component as a child element. A child should be a form element like an Input, InputArea, Dropdown or RichTextArea. */ children: _propTypes.default.oneOfType([_propTypes.default.node, _propTypes.default.func]), /** Applies a data-hook HTML attribute that can be used in tests. */ dataHook: _propTypes.default.string, /** Input id used for connecting label to the input element using native ```for``` attribute * * ```js * <FormField id="myFormField" label="Hello"> * <Input id="myFormField"/> * </FormField> * ``` */ id: _propTypes.default.string, /** Displays a passed info message in a tooltip. Default value is a text string, but it can also be overridden with any other component. */ infoContent: _propTypes.default.node, /** Allows control over the tooltip style and behaviour by passed tooltip properties. * @linkTypeTo components-overlays--tooltip * @setTypeName TooltipCommonProps */ infoTooltipProps: _propTypes.default.shape(_TooltipCommon.TooltipCommonProps), /** Sets a field label. It’s default value is a text string, but it can be overridden with any other component. */ label: _propTypes.default.node, /** Controls the label alignment */ labelAlignment: _propTypes.default.oneOf([ALIGN.middle, ALIGN.top]), /** Controls the label placement */ labelPlacement: _propTypes.default.oneOf([PLACEMENT.top, PLACEMENT.right, PLACEMENT.left]), /** Controls the size of label */ labelSize: _propTypes.default.oneOf(['tiny', 'small']), /** Marks a field as mandatory with an asterisk (*) at the end of a label. */ required: _propTypes.default.bool, /** Defines whether or not the content (children container) grows when there's space available. Otherwise, it only uses the necessary space. */ stretchContent: _propTypes.default.bool, /** Adds a custom element at the end of the label row (it overrides the charCount in case it's provided). */ suffix: _propTypes.default.node, /** Sets the maximum length for the field value. Character count is displayed in the top right corner of a component. */ charCount: _propTypes.default.number, /** Sets the id of the label */ labelId: _propTypes.default.string, /** Sets the status message. It is displayed bellow the child component*/ statusMessage: _propTypes.default.node, /** Sets the type of status message, to give it appropriate colors and icons */ status: _propTypes.default.oneOf([STATUS.error, STATUS.warning, STATUS.loading]) }; FormField.defaultProps = { required: false, stretchContent: true, labelSize: 'small', labelPlacement: PLACEMENT.top, labelAlignment: ALIGN.middle }; var _default = exports.default = FormField; //# sourceMappingURL=FormField.js.map