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.

296 lines (271 loc) 11.4 kB
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;