wix-style-react
Version:
wix-style-react
407 lines (405 loc) • 15.2 kB
JavaScript
"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