UNPKG

@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.

266 lines (228 loc) 9.58 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var React = _interopRequireWildcard(require("react")); var _styledComponents = _interopRequireWildcard(require("styled-components")); var _defaultTheme = _interopRequireDefault(require("../defaultTheme")); var _FormLabel = _interopRequireDefault(require("../FormLabel")); var _InputField = require("../InputField"); var _Select = require("../Select"); var _ErrorFormTooltip = _interopRequireDefault(require("../ErrorFormTooltip")); var _consts = require("./consts"); var _rtl = require("../utils/rtl"); var _getSpacingToken = _interopRequireDefault(require("../common/getSpacingToken")); var _useRandomId = _interopRequireWildcard(require("../hooks/useRandomId")); var _formElementFocus = _interopRequireDefault(require("../InputField/helpers/formElementFocus")); var _getFieldDataState = _interopRequireDefault(require("../common/getFieldDataState")); var _mediaQuery = _interopRequireDefault(require("../utils/mediaQuery")); const getToken = name => ({ theme, size }) => { const tokens = { [_consts.TOKENS.height]: { [_consts.SIZE_OPTIONS.SMALL]: theme.orbit.heightInputSmall, [_consts.SIZE_OPTIONS.NORMAL]: theme.orbit.heightInputNormal }, [_consts.TOKENS.heightLine]: { [_consts.SIZE_OPTIONS.SMALL]: "16px", [_consts.SIZE_OPTIONS.NORMAL]: "24px" } }; return tokens[name][size]; }; const getFakeGroupMarginTop = ({ label, theme }) => { if (!label) return false; return `calc(${theme.orbit.lineHeightTextSmall} + ${theme.orbit.spaceXXSmall})`; }; const FakeGroup = (0, _styledComponents.default)(({ children, className }) => /*#__PURE__*/React.createElement("span", { className: className }, children)).withConfig({ displayName: "InputGroup__FakeGroup", componentId: "sc-1ueh2xl-0" })(["", ""], ({ theme, error, disabled }) => (0, _styledComponents.css)(["width:100%;display:block;position:absolute;top:0px;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(_consts.TOKENS.height), `inset 0 0 0 ${theme.orbit.borderWidthInput} ${theme.orbit.borderColorInput}`, error && `inset 0 0 0 ${theme.orbit.borderWidthInput} ${theme.orbit.borderColorInputError}`, ({ active }) => active && _formElementFocus.default, disabled ? theme.orbit.backgroundInputDisabled : theme.orbit.backgroundInput, theme.orbit.fontSizeInputNormal, theme.orbit.durationFast, getFakeGroupMarginTop, _mediaQuery.default.tablet((0, _styledComponents.css)(["border-radius:", ";"], theme.orbit.borderRadiusNormal)), `${theme.orbit.borderWidthInput} ${error ? theme.orbit.borderColorInputErrorHover : theme.orbit.borderColorInputHover}`)); // $FlowFixMe: https://github.com/flow-typed/flow-typed/issues/3653#issuecomment-568539198 FakeGroup.defaultProps = { theme: _defaultTheme.default }; const StyledChildren = _styledComponents.default.div.withConfig({ displayName: "InputGroup__StyledChildren", componentId: "sc-1ueh2xl-1" })(["display:flex;position:relative;"]); const StyledChild = _styledComponents.default.div.withConfig({ displayName: "InputGroup__StyledChild", componentId: "sc-1ueh2xl-2" })(["flex:", ";padding:", ";:last-child{padding:0;}"], ({ flex }) => flex, ({ theme }) => (0, _rtl.rtlSpacing)(`0 ${theme.orbit.spaceXSmall} 0 0`)); // $FlowFixMe: https://github.com/flow-typed/flow-typed/issues/3653#issuecomment-568539198 StyledChild.defaultProps = { theme: _defaultTheme.default }; const StyledInputGroup = (0, _styledComponents.default)(({ children, className, dataTest, role, ariaLabelledby, forwardRef, dataState }) => /*#__PURE__*/React.createElement("div", { "data-state": dataState, ref: forwardRef, className: className, "data-test": dataTest, role: role, "aria-labelledby": ariaLabelledby }, children)).withConfig({ displayName: "InputGroup__StyledInputGroup", componentId: "sc-1ueh2xl-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.default, StyledChild, _InputField.FakeInput, _Select.SelectContainer, _InputField.InputContainer, _Select.SelectContainer, _rtl.right, getToken(_consts.TOKENS.heightLine), ({ theme, error, active }) => error && !active ? theme.orbit.borderColorInputError : theme.orbit.borderColorInput, ({ theme }) => theme.orbit.durationFast, _InputField.InputContainer, _Select.SelectContainer, StyledChild, _FormLabel.default, ({ label }) => label && "none", _InputField.Input, _InputField.FakeInput); // $FlowFixMe: https://github.com/flow-typed/flow-typed/issues/3653#issuecomment-568539198 StyledInputGroup.defaultProps = { theme: _defaultTheme.default }; const findPropInChild = (propToFind, children) => React.Children.map(children, el => { if (el.props && el.props[propToFind]) return el.props[propToFind]; return null; }).filter(el => el != null); // TODO: styled component type const InputGroup = /*#__PURE__*/React.forwardRef(({ children, label, flex, size = _consts.SIZE_OPTIONS.NORMAL, help, error, disabled, dataTest, spaceAfter, helpClosable = true, onFocus, onBlur, onChange, onBlurGroup }, ref) => { const [active, setActive] = React.useState(false); const [filled, setFilled] = React.useState(false); const inputID = (0, _useRandomId.default)(); const [tooltipShown, setTooltipShown] = React.useState(false); const [tooltipShownHover, setTooltipShownHover] = React.useState(false); const labelRef = React.useRef(null); const iconRef = React.useRef(null); const foundErrors = React.useMemo(() => findPropInChild("error", children), [children]); const foundHelp = React.useMemo(() => findPropInChild("help", children), [children]); const errorReal = error || foundErrors.length > 0 && foundErrors[0]; const helpReal = help || foundHelp.length > 0 && foundHelp[0]; const randomId = (0, _useRandomId.useRandomIdSeed)(); const isFilled = React.useCallback(() => setFilled(findPropInChild("value", children).length > 0), [children]); React.useEffect(() => { isFilled(); }, [isFilled, label]); const handleFocus = (ev, callBack) => { setActive(true); setTooltipShown(true); if (onFocus) onFocus(ev); if (callBack) callBack(ev); }; const handleBlur = (ev, callBack) => { isFilled(); setActive(false); if (onBlur) onBlur(ev); if (callBack) callBack(ev); }; const handleChange = (ev, callBack) => { isFilled(); if (onChange) { onChange(ev); } if (callBack) callBack(ev); }; const handleBlurGroup = ev => { ev.persist(); if (onBlurGroup) { setTimeout(() => { setActive(isActive => { if (!isActive) { onBlurGroup(ev); } return isActive; }); }, 50); } }; return /*#__PURE__*/React.createElement(StyledInputGroup, { label: label, error: errorReal, active: active, size: size, forwardRef: ref, dataTest: dataTest, dataState: (0, _getFieldDataState.default)(!!errorReal), spaceAfter: spaceAfter, role: "group", ariaLabelledby: label && inputID }, label && /*#__PURE__*/React.createElement(_FormLabel.default, { filled: filled, id: inputID, labelRef: labelRef, error: !!errorReal, help: !!helpReal, iconRef: iconRef, onMouseEnter: () => setTooltipShownHover(true), onMouseLeave: () => setTooltipShownHover(false) }, label), /*#__PURE__*/React.createElement(StyledChildren, { onBlur: handleBlurGroup }, React.Children.toArray(children).map((item, key) => { const 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, label: undefined, onChange: ev => handleChange(ev, item.props.onChange), onBlur: ev => handleBlur(ev, item.props.onBlur), onFocus: ev => handleFocus(ev, item.props.onFocus), insideInputGroup: true })); })), /*#__PURE__*/React.createElement(FakeGroup, { label: label, error: errorReal, active: active, size: size }), /*#__PURE__*/React.createElement(_ErrorFormTooltip.default, { help: helpReal, error: errorReal, helpClosable: helpClosable, inputSize: size, onShown: setTooltipShown, shown: tooltipShown || tooltipShownHover, referenceElement: labelRef })); }); var _default = InputGroup; exports.default = _default;