@dotconnor/grommet
Version:
focus on the essential experience
345 lines (286 loc) • 14.1 kB
JavaScript
exports.__esModule = true;
exports.FormField = void 0;
var _react = _interopRequireWildcard(require("react"));
var _styledComponents = _interopRequireWildcard(require("styled-components"));
var _defaultProps = require("../../default-props");
var _utils = require("../../utils");
var _Box = require("../Box");
var _CheckBox = require("../CheckBox");
var _CheckBoxGroup = require("../CheckBoxGroup");
var _RadioButtonGroup = require("../RadioButtonGroup");
var _Text = require("../Text");
var _TextInput = require("../TextInput");
var _FormContext = require("../Form/FormContext");
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
var grommetInputNames = ['TextInput', 'Select', 'MaskedInput', 'TextArea', 'DateInput'];
var grommetInputPadNames = ['CheckBox', 'CheckBoxGroup', 'RadioButtonGroup', 'RangeInput'];
var isGrommetInput = function isGrommetInput(comp) {
return comp && (grommetInputNames.indexOf(comp.displayName) !== -1 || grommetInputPadNames.indexOf(comp.displayName) !== -1);
};
var FormFieldBox = (0, _styledComponents["default"])(_Box.Box).withConfig({
displayName: "FormField__FormFieldBox",
componentId: "m9hood-0"
})(["", " ", ""], function (props) {
return props.focus && (0, _utils.focusStyle)({
justBorder: true
});
}, function (props) {
return props.theme.formField && props.theme.formField.extend;
});
var FormFieldContentBox = (0, _styledComponents["default"])(_Box.Box).withConfig({
displayName: "FormField__FormFieldContentBox",
componentId: "m9hood-1"
})(["", ""], function (props) {
return props.focus && (0, _utils.focusStyle)({
justBorder: true
});
});
var StyledMessageContainer = (0, _styledComponents["default"])(_Box.Box).withConfig({
displayName: "FormField__StyledMessageContainer",
componentId: "m9hood-2"
})(["", ""], function (props) {
return props.messageType && props.theme.formField[props.messageType].container && props.theme.formField[props.messageType].container.extend;
});
var Message = function Message(_ref) {
var error = _ref.error,
info = _ref.info,
message = _ref.message,
type = _ref.type,
rest = _objectWithoutPropertiesLoose(_ref, ["error", "info", "message", "type"]);
var theme = (0, _react.useContext)(_styledComponents.ThemeContext) || _defaultProps.defaultProps.theme;
if (message) {
var icon;
var containerProps;
if (type) {
icon = theme.formField[type] && theme.formField[type].icon;
containerProps = theme.formField[type] && theme.formField[type].container;
}
var messageContent;
if (typeof message === 'string') messageContent = /*#__PURE__*/_react["default"].createElement(_Text.Text, rest, message);else messageContent = /*#__PURE__*/_react["default"].createElement(_Box.Box, rest, message);
return icon || containerProps ? /*#__PURE__*/_react["default"].createElement(StyledMessageContainer, _extends({
direction: "row",
messageType: type
}, containerProps), icon && /*#__PURE__*/_react["default"].createElement(_Box.Box, {
flex: false
}, icon), messageContent) : messageContent;
}
return null;
};
var Input = function Input(_ref2) {
var component = _ref2.component,
disabled = _ref2.disabled,
invalid = _ref2.invalid,
name = _ref2.name,
_onChange = _ref2.onChange,
rest = _objectWithoutPropertiesLoose(_ref2, ["component", "disabled", "invalid", "name", "onChange"]);
var formContext = (0, _react.useContext)(_FormContext.FormContext);
var _formContext$useFormI = formContext.useFormInput(name, rest.value),
value = _formContext$useFormI[0],
setValue = _formContext$useFormI[1];
var InputComponent = component || _TextInput.TextInput; // Grommet input components already check for FormContext
// and, using their `name`, end up calling the useFormInput.setValue()
// already. For custom components, we expect they will call
// this onChange() and we'll call setValue() here, primarily
// for backwards compatibility.
var extraProps = isGrommetInput(InputComponent) ? {
focusIndicator: false,
onChange: _onChange,
plain: true
} : {
value: value,
onChange: function onChange(event) {
setValue(event.value !== undefined ? event.value : event.target.value);
if (_onChange) _onChange(event);
}
};
return /*#__PURE__*/_react["default"].createElement(InputComponent, _extends({
name: name,
disabled: disabled,
"aria-invalid": invalid || undefined
}, rest, extraProps));
};
var FormField = /*#__PURE__*/(0, _react.forwardRef)(function (_ref3, ref) {
var children = _ref3.children,
className = _ref3.className,
component = _ref3.component,
contentProps = _ref3.contentProps,
disabled = _ref3.disabled,
errorProp = _ref3.error,
help = _ref3.help,
htmlFor = _ref3.htmlFor,
infoProp = _ref3.info,
label = _ref3.label,
margin = _ref3.margin,
name = _ref3.name,
_onBlur = _ref3.onBlur,
_onFocus = _ref3.onFocus,
pad = _ref3.pad,
required = _ref3.required,
style = _ref3.style,
validate = _ref3.validate,
rest = _objectWithoutPropertiesLoose(_ref3, ["children", "className", "component", "contentProps", "disabled", "error", "help", "htmlFor", "info", "label", "margin", "name", "onBlur", "onFocus", "pad", "required", "style", "validate"]);
var theme = (0, _react.useContext)(_styledComponents.ThemeContext) || _defaultProps.defaultProps.theme;
var formContext = (0, _react.useContext)(_FormContext.FormContext);
var _formContext$useFormF = formContext.useFormField({
error: errorProp,
info: infoProp,
name: name,
required: required,
validate: validate
}),
error = _formContext$useFormF.error,
info = _formContext$useFormF.info,
inForm = _formContext$useFormF.inForm,
contextOnBlur = _formContext$useFormF.onBlur;
var _useState = (0, _react.useState)(),
focus = _useState[0],
setFocus = _useState[1];
var formFieldTheme = theme.formField;
var themeBorder = formFieldTheme.border; // This is here for backwards compatibility. In case the child is a grommet
// input component, set plain and focusIndicator props, if they aren't
// already set.
var wantContentPad = component && (component === _CheckBox.CheckBox || component === _CheckBoxGroup.CheckBoxGroup || component === _RadioButtonGroup.RadioButtonGroup);
var contents = themeBorder && children && _react.Children.map(children, function (child) {
if (child && child.type && grommetInputPadNames.indexOf(child.type.displayName) !== -1) {
wantContentPad = true;
}
if (child && child.type && grommetInputNames.indexOf(child.type.displayName) !== -1 && child.props.plain === undefined && child.props.focusIndicator === undefined) {
return /*#__PURE__*/(0, _react.cloneElement)(child, {
plain: true,
focusIndicator: false
});
}
return child;
}) || children; // put rest on container, unless we use internal Input
var containerRest = rest;
if (inForm) {
if (!contents) containerRest = {};
contents = contents || /*#__PURE__*/_react["default"].createElement(Input, _extends({
component: component,
disabled: disabled,
invalid: !!error,
name: name,
label: component === _CheckBox.CheckBox ? label : undefined
}, rest));
}
var themeContentProps = _extends({}, formFieldTheme.content);
if (!pad && !wantContentPad) {
themeContentProps.pad = undefined;
}
if (themeBorder && themeBorder.position === 'inner') {
if (error && formFieldTheme.error) {
themeContentProps.background = formFieldTheme.error.background;
} else if (disabled && formFieldTheme.disabled) {
themeContentProps.background = formFieldTheme.disabled.background;
}
}
if (!themeBorder) {
contents = /*#__PURE__*/_react["default"].createElement(_Box.Box, _extends({}, themeContentProps, contentProps), contents);
}
var borderColor;
if (disabled && formFieldTheme.disabled.border && formFieldTheme.disabled.border.color) {
borderColor = formFieldTheme.disabled.border.color;
} else if (error && themeBorder && themeBorder.error.color) {
borderColor = themeBorder.error.color || 'status-critical';
} else if (focus && formFieldTheme.focus && formFieldTheme.focus.border && formFieldTheme.focus.border.color) {
borderColor = formFieldTheme.focus.border.color;
} else {
borderColor = themeBorder && themeBorder.color || 'border';
}
var labelStyle = _extends({}, formFieldTheme.label);
if (disabled) {
labelStyle.color = formFieldTheme.disabled && formFieldTheme.disabled.label ? formFieldTheme.disabled.label.color : labelStyle.color;
}
var abut;
var abutMargin;
var outerStyle = style;
if (themeBorder) {
var innerProps = themeBorder.position === 'inner' ? {
border: _extends({}, themeBorder, {
side: themeBorder.side || 'bottom',
color: borderColor
}),
round: formFieldTheme.round,
focus: focus
} : {};
contents = /*#__PURE__*/_react["default"].createElement(FormFieldContentBox, _extends({}, themeContentProps, innerProps, contentProps), contents);
var mergedMargin = margin || formFieldTheme.margin;
abut = themeBorder.position === 'outer' && (themeBorder.side === 'all' || themeBorder.side === 'horizontal' || !themeBorder.side) && !(mergedMargin && (typeof mergedMargin === 'string' && mergedMargin !== 'none' || mergedMargin.bottom && mergedMargin.bottom !== 'none' || mergedMargin.horizontal && mergedMargin.horizontal !== 'none'));
if (abut) {
// marginBottom is set to overlap adjacent fields
abutMargin = {
bottom: '-1px'
};
if (margin) {
abutMargin = margin;
} else if (themeBorder.size) {
// if the user defines a margin,
// then the default margin below will be overridden
abutMargin = {
bottom: "-" + (0, _utils.parseMetricToNum)(theme.global.borderSize[themeBorder.size] || themeBorder.size) + "px"
};
}
outerStyle = _extends({
position: focus ? 'relative' : undefined,
zIndex: focus ? 10 : undefined
}, style);
}
}
var outerBackground;
if (themeBorder && themeBorder.position === 'outer') {
if (error && formFieldTheme.error && formFieldTheme.error.background) {
outerBackground = formFieldTheme.error.background;
} else if (focus && formFieldTheme.focus && formFieldTheme.focus.background && formFieldTheme.focus.background.color) {
outerBackground = formFieldTheme.focus.background.color;
} else if (disabled && formFieldTheme.disabled && formFieldTheme.disabled.background) {
outerBackground = formFieldTheme.disabled.background;
}
}
var outerProps = themeBorder && themeBorder.position === 'outer' ? {
border: _extends({}, themeBorder, {
color: borderColor
}),
round: formFieldTheme.round,
focus: focus
} : {};
return /*#__PURE__*/_react["default"].createElement(FormFieldBox, _extends({
ref: ref,
className: className,
background: outerBackground,
margin: abut ? abutMargin : margin || _extends({}, formFieldTheme.margin)
}, outerProps, {
style: outerStyle,
onFocus: function onFocus(event) {
setFocus(true);
if (_onFocus) _onFocus(event);
},
onBlur: function onBlur(event) {
setFocus(false);
if (contextOnBlur) contextOnBlur(event);
if (_onBlur) _onBlur(event);
}
}, containerRest), label && component !== _CheckBox.CheckBox || help ? /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, label && component !== _CheckBox.CheckBox && /*#__PURE__*/_react["default"].createElement(_Text.Text, _extends({
as: "label",
htmlFor: htmlFor
}, labelStyle), label), /*#__PURE__*/_react["default"].createElement(Message, _extends({
message: help
}, formFieldTheme.help))) : undefined, contents, /*#__PURE__*/_react["default"].createElement(Message, _extends({
type: "error",
message: error
}, formFieldTheme.error)), /*#__PURE__*/_react["default"].createElement(Message, _extends({
type: "info",
message: info
}, formFieldTheme.info)));
});
FormField.displayName = 'FormField';
var FormFieldDoc;
if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line global-require
FormFieldDoc = require('./doc').doc(FormField);
}
var FormFieldWrapper = FormFieldDoc || FormField;
exports.FormField = FormFieldWrapper;
;