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.

145 lines (143 loc) 7.54 kB
"use strict"; "use client"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default; exports.__esModule = true; exports.default = void 0; var React = _interopRequireWildcard(require("react")); var _clsx = _interopRequireDefault(require("clsx")); var _FormLabel = _interopRequireDefault(require("../FormLabel")); var _ErrorFormTooltip = _interopRequireDefault(require("../ErrorFormTooltip")); var _useRandomId = _interopRequireWildcard(require("../hooks/useRandomId")); var _getFieldDataState = _interopRequireDefault(require("../common/getFieldDataState")); var _tailwind = require("../common/tailwind"); 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); const InputGroup = ({ children, label, flex, help, id, error, disabled, dataTest, spaceAfter, onFocus, onBlur, onChange, onBlurGroup, ariaLabel, ariaLabelledby, required, ref }) => { const [active, setActive] = 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 = findPropInChild("error", children); const foundHelp = findPropInChild("help", children); const errorReal = error || foundErrors.length > 0 && foundErrors[0]; const helpReal = help || foundHelp.length > 0 && foundHelp[0]; const randomId = (0, _useRandomId.useRandomIdSeed)(); const feedbackId = (0, _useRandomId.default)(); const hasTooltip = errorReal || helpReal; const shown = tooltipShown || tooltipShownHover; const handleFocus = callBack => ev => { setActive(true); setTooltipShown(true); if (onFocus) onFocus(ev); if (callBack) callBack(ev); }; const handleBlur = callBack => ev => { setActive(false); if (onBlur) onBlur(ev); if (callBack) callBack(ev); }; const handleChange = callBack => ev => { 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("div", { className: (0, _clsx.default)("relative flex w-full flex-col", spaceAfter != null && (0, _tailwind.getSpaceAfterClasses)(spaceAfter)) }, /*#__PURE__*/React.createElement("fieldset", { ref: ref, id: id, "data-test": dataTest, "data-state": (0, _getFieldDataState.default)(!!errorReal), "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, "aria-required": required }, label && /*#__PURE__*/React.createElement("legend", null, /*#__PURE__*/React.createElement(_FormLabel.default, { id: inputID, labelRef: labelRef, error: !!errorReal, help: !!helpReal, iconRef: iconRef, onMouseEnter: () => hasTooltip ? setTooltipShownHover(true) : undefined, onMouseLeave: () => hasTooltip ? setTooltipShownHover(false) : undefined, required: required }, label)), /*#__PURE__*/React.createElement("div", { className: (0, _clsx.default)("text-normal h-form-box-normal duration-fast rounded-200 z-default w-full transition-shadow ease-in-out", disabled ? "bg-form-element-disabled-background" : "bg-form-element-background", !errorReal && "shadow-form-element", !errorReal && !disabled && "hover:shadow-form-element-hover", Boolean(errorReal) && "shadow-form-element-error", Boolean(errorReal) && !disabled && "hover:shadow-form-element-error-hover") }, /*#__PURE__*/React.createElement("div", { className: "relative flex", onBlur: handleBlurGroup }, React.Children.toArray(children).map((child, key) => { // TODO: next cleanup iteration just remove this whole `flex` prop thing // and cloning elements, and make children take care of their sizing themselves const childrenCount = React.Children.count(children); const isLastChild = key === childrenCount - 1; const flexArray = Array.isArray(flex) ? flex : [flex]; let childFlex = flex ? flexArray[key] || flexArray[0] : undefined; if (isLastChild && flexArray.length !== childrenCount) { childFlex = "1 1 100%"; } const item = child; return /*#__PURE__*/React.createElement("div", { key: randomId(String(key)), className: (0, _clsx.default)("orbit-input-group-child [&_.orbit-input-field-fake-input]:hidden [&_.orbit-input-field-fake-input]:bg-transparent [&_.orbit-input-field-input~.orbit-input-field-fake-input]:shadow-none [&_.orbit-select-container_select]:bg-transparent [&_.orbit-select-container_select]:shadow-none [&_.orbit-select-container_select]:focus:outline-none", // InputField:after "[&_.orbit-input-field-input-container]:after:duration-fast [&_.orbit-input-field-input-container]:after:z-default [&_.orbit-input-field-input-container]:after:h-600 [&_.orbit-input-field-input-container]:after:absolute [&_.orbit-input-field-input-container]:after:end-0 [&_.orbit-input-field-input-container]:after:top-1/2 [&_.orbit-input-field-input-container]:after:block [&_.orbit-input-field-input-container]:after:-translate-y-1/2 [&_.orbit-input-field-input-container]:after:border-r [&_.orbit-input-field-input-container]:after:transition-colors [&_.orbit-input-field-input-container]:after:ease-in-out [&_.orbit-input-field-input-container]:last-of-type:after:content-none", // Select:after "[&_.orbit-select-container]:after:duration-fast [&_.orbit-select-container]:after:h-600 [&_.orbit-select-container]:bg-transparent [&_.orbit-select-container]:after:absolute [&_.orbit-select-container]:after:end-0 [&_.orbit-select-container]:after:top-1/2 [&_.orbit-select-container]:after:z-[2] [&_.orbit-select-container]:after:block [&_.orbit-select-container]:after:-translate-y-1/2 [&_.orbit-select-container]:after:border-r [&_.orbit-select-container]:after:transition-colors [&_.orbit-select-container]:after:ease-in-out [&_.orbit-select-container]:last-of-type:after:content-none", Boolean(errorReal) && !active ? "[&_.orbit-select-container]:after:border-form-element-error [&_.orbit-input-field-input-container]:after:border-form-element-error" : "[&_.orbit-select-container]:after:border-form-element [&_.orbit-input-field-input-container]:after:border-form-element", label != null && "[&_.orbit-form-label]:hidden"), style: { flex: childFlex } }, /*#__PURE__*/React.cloneElement(item, { disabled: item.props.disabled || disabled, label: undefined, onChange: handleChange(item.props.onChange), onBlur: handleBlur(item.props.onBlur), onFocus: handleFocus(item.props.onFocus), ariaLabel: item.props.label, insideInputGroup: true, ariaDescribedby: (error || help || item.props.error || item.props.help) && shown ? feedbackId : undefined })); })))), /*#__PURE__*/React.createElement(_ErrorFormTooltip.default, { id: feedbackId, help: helpReal, error: errorReal, onShown: setTooltipShown, shown: shown, referenceElement: labelRef })); }; var _default = exports.default = InputGroup;