@kiwicom/orbit-components
Version:
Orbit-components is a React component library which provides developers with the easiest possible way of building Kiwi.com’s products.
296 lines (271 loc) • 11.4 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import * as React from "react";
import styled, { css } from "styled-components";
import defaultTheme from "../defaultTheme";
import FormLabel from "../FormLabel";
import { FakeInput, Input, InputContainer } from "../InputField";
import { SelectContainer } from "../Select";
import ErrorFormTooltip from "../ErrorFormTooltip";
import { SIZE_OPTIONS, TOKENS } from "./consts";
import { right, rtlSpacing } from "../utils/rtl";
import getSpacingToken from "../common/getSpacingToken";
import useRandomId, { useRandomIdSeed } from "../hooks/useRandomId";
import formElementFocus from "../InputField/helpers/formElementFocus";
import getFieldDataState from "../common/getFieldDataState";
import mq from "../utils/mediaQuery";
var getToken = function getToken(name) {
return function (_ref) {
var _TOKENS$height, _TOKENS$heightLine, _tokens;
var theme = _ref.theme,
size = _ref.size;
var tokens = (_tokens = {}, _defineProperty(_tokens, TOKENS.height, (_TOKENS$height = {}, _defineProperty(_TOKENS$height, SIZE_OPTIONS.SMALL, theme.orbit.heightInputSmall), _defineProperty(_TOKENS$height, SIZE_OPTIONS.NORMAL, theme.orbit.heightInputNormal), _TOKENS$height)), _defineProperty(_tokens, TOKENS.heightLine, (_TOKENS$heightLine = {}, _defineProperty(_TOKENS$heightLine, SIZE_OPTIONS.SMALL, "16px"), _defineProperty(_TOKENS$heightLine, SIZE_OPTIONS.NORMAL, "24px"), _TOKENS$heightLine)), _tokens);
return tokens[name][size];
};
};
var getFakeGroupMarginTop = function getFakeGroupMarginTop(_ref2) {
var label = _ref2.label,
theme = _ref2.theme;
if (!label) return false;
return "calc(".concat(theme.orbit.lineHeightTextSmall, " + ").concat(theme.orbit.spaceXXSmall, ")");
};
var FakeGroup = styled(function (_ref3) {
var children = _ref3.children,
className = _ref3.className;
return /*#__PURE__*/React.createElement("span", {
className: className
}, children);
}).withConfig({
displayName: "InputGroup__FakeGroup",
componentId: "cyuwoi-0"
})(["width:100%;display:block;position:absolute;top:0;left:0;z-index:1;box-sizing:border-box;height:", ";box-shadow:", ";box-shadow:", ";", ";background-color:", ";font-size:", ";transition:box-shadow ", " ease-in-out;margin-top:", ";border-radius:6px;", ";&:hover{box-shadow:inset 0 0 0 ", ";}"], getToken(TOKENS.height), function (_ref4) {
var theme = _ref4.theme;
return "inset 0 0 0 ".concat(theme.orbit.borderWidthInput, " ").concat(theme.orbit.borderColorInput);
}, function (_ref5) {
var theme = _ref5.theme,
error = _ref5.error;
return error && "inset 0 0 0 ".concat(theme.orbit.borderWidthInput, " ").concat(theme.orbit.borderColorInputError);
}, function (_ref6) {
var active = _ref6.active;
return active && formElementFocus;
}, function (_ref7) {
var disabled = _ref7.disabled,
theme = _ref7.theme;
return disabled ? theme.orbit.backgroundInputDisabled : theme.orbit.backgroundInput;
}, function (_ref8) {
var theme = _ref8.theme;
return theme.orbit.fontSizeInputNormal;
}, function (_ref9) {
var theme = _ref9.theme;
return theme.orbit.durationFast;
}, getFakeGroupMarginTop, mq.tablet(css(["border-radius:", ";"], function (_ref10) {
var theme = _ref10.theme;
return theme.orbit.borderRadiusNormal;
})), function (_ref11) {
var theme = _ref11.theme,
error = _ref11.error;
return "".concat(theme.orbit.borderWidthInput, " ").concat(error ? theme.orbit.borderColorInputErrorHover : theme.orbit.borderColorInputHover);
}); // $FlowFixMe: https://github.com/flow-typed/flow-typed/issues/3653#issuecomment-568539198
FakeGroup.defaultProps = {
theme: defaultTheme
};
var StyledChildren = styled.div.withConfig({
displayName: "InputGroup__StyledChildren",
componentId: "cyuwoi-1"
})(["display:flex;position:relative;"]);
var StyledChild = styled.div.withConfig({
displayName: "InputGroup__StyledChild",
componentId: "cyuwoi-2"
})(["flex:", ";padding:", ";:last-child{padding:0;}"], function (_ref12) {
var flex = _ref12.flex;
return flex;
}, function (_ref13) {
var theme = _ref13.theme;
return rtlSpacing("0 ".concat(theme.orbit.spaceXSmall, " 0 0"));
}); // $FlowFixMe: https://github.com/flow-typed/flow-typed/issues/3653#issuecomment-568539198
StyledChild.defaultProps = {
theme: defaultTheme
};
var StyledInputGroup = styled(function (_ref14) {
var children = _ref14.children,
className = _ref14.className,
dataTest = _ref14.dataTest,
role = _ref14.role,
ariaLabelledby = _ref14.ariaLabelledby,
labelRef = _ref14.labelRef,
dataState = _ref14.dataState;
return /*#__PURE__*/React.createElement("div", {
"data-state": dataState,
ref: labelRef,
className: className,
"data-test": dataTest,
role: role,
"aria-labelledby": ariaLabelledby
}, children);
}).withConfig({
displayName: "InputGroup__StyledInputGroup",
componentId: "cyuwoi-3"
})(["display:flex;width:100%;flex-direction:column;position:relative;margin-bottom:", ";", "{", "{box-shadow:none;background-color:transparent;display:none;align-items:center;justify-content:flex-end;}", "{background-color:transparent;> select{box-shadow:none;background-color:transparent;&:focus{box-shadow:none;}}}", ":after,", ":after{content:\" \";position:absolute;top:50%;transform:translateY(-50%);", ":0;height:", ";width:1px;background-color:", ";transition:background-color ", " ease-in-out;display:block;z-index:2;}&:last-of-type{", ":after,", ":after{content:none;}}}", " ", "{display:", ";}", ":focus ~ ", "{box-shadow:none;}"], getSpacingToken, StyledChild, FakeInput, SelectContainer, InputContainer, SelectContainer, right, getToken(TOKENS.heightLine), function (_ref15) {
var theme = _ref15.theme,
error = _ref15.error,
active = _ref15.active;
return error && !active ? theme.orbit.borderColorInputError : theme.orbit.borderColorInput;
}, function (_ref16) {
var theme = _ref16.theme;
return theme.orbit.durationFast;
}, InputContainer, SelectContainer, StyledChild, FormLabel, function (_ref17) {
var label = _ref17.label;
return label && "none";
}, Input, FakeInput); // $FlowFixMe: https://github.com/flow-typed/flow-typed/issues/3653#issuecomment-568539198
StyledInputGroup.defaultProps = {
theme: defaultTheme
};
var findPropInChild = function findPropInChild(propToFind, children) {
return React.Children.map(children, function (el) {
if (el.props && el.props[propToFind]) return el.props[propToFind];
return null;
}).filter(function (el) {
return el != null;
});
};
var InputGroup = function InputGroup(_ref18) {
var children = _ref18.children,
label = _ref18.label,
flex = _ref18.flex,
_ref18$size = _ref18.size,
size = _ref18$size === void 0 ? SIZE_OPTIONS.NORMAL : _ref18$size,
help = _ref18.help,
error = _ref18.error,
disabled = _ref18.disabled,
dataTest = _ref18.dataTest,
spaceAfter = _ref18.spaceAfter,
onFocus = _ref18.onFocus,
onBlur = _ref18.onBlur,
onChange = _ref18.onChange,
onBlurGroup = _ref18.onBlurGroup;
var _React$useState = React.useState(false),
_React$useState2 = _slicedToArray(_React$useState, 2),
active = _React$useState2[0],
setActive = _React$useState2[1];
var _React$useState3 = React.useState(false),
_React$useState4 = _slicedToArray(_React$useState3, 2),
filled = _React$useState4[0],
setFilled = _React$useState4[1];
var inputID = useRandomId();
var _React$useState5 = React.useState(false),
_React$useState6 = _slicedToArray(_React$useState5, 2),
tooltipShown = _React$useState6[0],
setTooltipShown = _React$useState6[1];
var _React$useState7 = React.useState(false),
_React$useState8 = _slicedToArray(_React$useState7, 2),
tooltipShownHover = _React$useState8[0],
setTooltipShownHover = _React$useState8[1];
var labelRef = React.useRef(null);
var iconRef = React.useRef(null);
var foundErrors = React.useMemo(function () {
return findPropInChild("error", children);
}, [children]);
var foundHelp = React.useMemo(function () {
return findPropInChild("help", children);
}, [children]);
var errorReal = error || foundErrors.length > 0 && foundErrors[0];
var helpReal = help || foundHelp.length > 0 && foundHelp[0];
var randomId = useRandomIdSeed();
var isFilled = React.useCallback(function () {
return setFilled(findPropInChild("value", children).length > 0);
}, [children]);
React.useEffect(function () {
isFilled();
}, [isFilled]);
var handleFocus = function handleFocus(ev, callBack) {
setActive(true);
setTooltipShown(true);
if (onFocus) onFocus(ev);
if (callBack) callBack(ev);
};
var handleBlur = function handleBlur(ev, callBack) {
isFilled();
setActive(false);
if (onBlur) onBlur(ev);
if (callBack) callBack(ev);
};
var handleChange = function handleChange(ev, callBack) {
isFilled();
if (onChange) {
onChange(ev);
}
if (callBack) callBack(ev);
};
var handleBlurGroup = function handleBlurGroup(ev) {
ev.persist();
if (onBlurGroup) {
setTimeout(function () {
setActive(function (isActive) {
if (!isActive) {
onBlurGroup(ev);
}
return isActive;
});
}, 50);
}
};
return /*#__PURE__*/React.createElement(StyledInputGroup, {
label: label,
error: errorReal,
active: active,
size: size,
dataTest: dataTest,
dataState: getFieldDataState(!!errorReal),
spaceAfter: spaceAfter,
role: "group",
ariaLabelledby: label && inputID,
labelRef: labelRef
}, label && /*#__PURE__*/React.createElement(FormLabel, {
filled: filled,
id: inputID,
error: !!errorReal,
help: !!helpReal,
iconRef: iconRef,
onMouseEnter: function onMouseEnter() {
return setTooltipShownHover(true);
},
onMouseLeave: function onMouseLeave() {
return setTooltipShownHover(false);
}
}, label), /*#__PURE__*/React.createElement(StyledChildren, {
onBlur: handleBlurGroup
}, React.Children.toArray(children).map(function (item, key) {
var childFlex = Array.isArray(flex) && flex.length !== 1 ? flex[key] || flex[0] : flex;
return /*#__PURE__*/React.createElement(StyledChild, {
flex: childFlex || "0 1 auto",
key: randomId(String(key))
}, /*#__PURE__*/React.cloneElement(item, {
disabled: item.props.disabled || disabled,
size: size,
label: undefined,
onChange: function onChange(ev) {
return handleChange(ev, item.props.onChange);
},
onBlur: function onBlur(ev) {
return handleBlur(ev, item.props.onBlur);
},
onFocus: function onFocus(ev) {
return handleFocus(ev, item.props.onFocus);
},
insideInputGroup: true
}));
})), /*#__PURE__*/React.createElement(FakeGroup, {
label: label,
error: errorReal,
active: active,
size: size
}), /*#__PURE__*/React.createElement(ErrorFormTooltip, {
help: helpReal,
error: errorReal,
inputSize: size,
onShown: setTooltipShown,
shown: tooltipShown || tooltipShownHover,
referenceElement: labelRef
}));
};
export default InputGroup;