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.

273 lines (272 loc) 10.8 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import * as React from "react"; import styled, { css } from "styled-components"; import defaultTheme from "../defaultTheme"; import FormLabel from "../FormLabel"; import { FakeInput } from "../InputField"; import ChevronDown from "../icons/ChevronDown"; import AlertCircle from "../icons/AlertCircle"; import InformationCircle from "../icons/InformationCircle"; import ErrorFormTooltip from "../ErrorFormTooltip"; import { right, left, rtlSpacing } from "../utils/rtl"; import getSpacingToken from "../common/getSpacingToken"; import getFieldDataState from "../common/getFieldDataState"; import useErrorTooltip from "../ErrorFormTooltip/hooks/useErrorTooltip"; import formElementFocus from "../InputField/helpers/formElementFocus"; import mq from "../utils/mediaQuery"; import useRandomId from "../hooks/useRandomId"; const StyledLabel = styled.label.withConfig({ displayName: "Select__StyledLabel", componentId: "sc-2ijy2y-0" })(["", ""], ({ $width }) => css(["position:relative;display:block;width:", ";margin-bottom:", ";"], $width, getSpacingToken)); StyledLabel.defaultProps = { theme: defaultTheme }; const StyledInlineLabel = styled.div.withConfig({ displayName: "Select__StyledInlineLabel", componentId: "sc-2ijy2y-1" })(["", ""], ({ theme, hasFeedback }) => css(["z-index:3;height:100%;display:flex;align-items:center;pointer-events:none;justify-content:center;padding:", ";", "{display:inline-block;margin-bottom:0;font-size:", ";line-height:", ";text-overflow:ellipsis;white-space:nowrap;overflow:hidden;max-width:20ch;}"], rtlSpacing(`0 0 0 ${hasFeedback ? theme.orbit.spaceXXSmall : theme.orbit.spaceSmall}`), FormLabel, theme.orbit.fontSizeInputNormal, theme.orbit.lineHeightTextNormal)); StyledInlineLabel.defaultProps = { theme: defaultTheme }; const StyledIconWrapper = styled.span.withConfig({ displayName: "Select__StyledIconWrapper", componentId: "sc-2ijy2y-2" })(["display:flex;"]); const StyledSelect = styled( /*#__PURE__*/React.forwardRef(({ className, dataTest, children, value, disabled, name, error, tabIndex, onChange, onFocus, onBlur, id, dataAttrs, readOnly, ariaDescribedby, ariaInvalid }, ref) => /*#__PURE__*/React.createElement("select", _extends({ id: id, "data-test": dataTest, "data-state": getFieldDataState(!!error), value: value, className: className, onChange: onChange, onFocus: onFocus // @ts-expect-error TODO , readOnly: readOnly, onBlur: onBlur, disabled: disabled, name: name, tabIndex: tabIndex ? Number(tabIndex) : undefined, ref: ref, "aria-describedby": ariaDescribedby, "aria-invalid": ariaInvalid }, dataAttrs), children))).withConfig({ displayName: "Select__StyledSelect", componentId: "sc-2ijy2y-3" })(["", ""], ({ theme, filled, customValueText, prefix }) => css(["appearance:none;background:transparent;cursor:pointer;color:", ";font-family:", ";font-size:", ";height:", ";padding:", ";outline:none;flex:1 1 20%;width:100%;height:100%;border:0;color:", ";transition:box-shadow ", " ease-in-out;border-radius:", ";", ";> option{color:", ";}&::-ms-expand{display:none;}&::-ms-value{background:transparent;color:", ";color:", ";}&:focus{outline:none;& ~ ", "{", "}}&:disabled{color:", ";cursor:not-allowed;}", ""], filled ? theme.orbit.colorTextInput : theme.orbit.colorPlaceholderInput, theme.orbit.fontFamily, theme.orbit.fontSizeInputNormal, theme.orbit.heightInputNormal, rtlSpacing(prefix ? `0 ${theme.orbit.spaceXXLarge} 0 ${theme.orbit.paddingLeftSelectPrefix}` : `0 ${theme.orbit.spaceXXLarge} 0 ${theme.orbit.spaceSmall}`), customValueText && "transparent !important", theme.orbit.durationFast, theme.orbit.borderRadiusLarge, mq.tablet(css(["border-radius:", ";"], theme.orbit.borderRadiusNormal)), theme.orbit.colorTextInput, filled ? theme.orbit.colorTextInput : theme.orbit.colorPlaceholderInput, customValueText && "rgba(255, 255, 255, 0)", FakeInput, formElementFocus, theme.orbit.colorTextInputDisabled, customValueText && ` &:-webkit-autofill, &:-internal-autofill-selected { -webkit-text-fill-color: transparent; } `)); StyledSelect.defaultProps = { theme: defaultTheme }; export const SelectContainer = styled.div.withConfig({ displayName: "Select__SelectContainer", componentId: "sc-2ijy2y-4" })(["", ""], ({ theme, disabled, error }) => css(["position:relative;display:flex;align-items:center;flex-direction:row;justify-content:space-between;width:100%;box-sizing:border-box;height:", ";color:", ";cursor:", ";&:hover > ", "{", ";}&:focus-within{outline:none;", "{", "}}"], theme.orbit.heightInputNormal, disabled ? theme.orbit.colorTextInputDisabled : theme.orbit.colorTextInput, disabled ? "not-allowed" : "pointer", FakeInput, !disabled && `box-shadow: inset 0 0 0 ${theme.orbit.borderWidthInput} ${error ? theme.orbit.borderColorInputErrorHover : theme.orbit.borderColorInputHover}`, FakeInput, formElementFocus)); SelectContainer.defaultProps = { theme: defaultTheme }; const SelectPrefix = styled.div.withConfig({ displayName: "Select__SelectPrefix", componentId: "sc-2ijy2y-5" })(["", ";"], ({ theme }) => css(["display:flex;height:100%;align-items:center;position:absolute;padding:0 ", ";pointer-events:none;z-index:3;top:0;"], theme.orbit.spaceSmall)); SelectPrefix.defaultProps = { theme: defaultTheme }; const SelectSuffix = styled.div.withConfig({ displayName: "Select__SelectSuffix", componentId: "sc-2ijy2y-6" })(["", ";"], ({ theme, disabled }) => css(["position:absolute;display:flex;justify-content:center;align-items:center;top:0;", ":", ";color:", ";pointer-events:none;z-index:3;height:100%;"], right, theme.orbit.spaceXSmall, disabled ? theme.orbit.colorTextInputDisabled : theme.orbit.colorTextInput)); SelectSuffix.defaultProps = { theme: defaultTheme }; const StyledCustomValue = styled.div.withConfig({ displayName: "Select__StyledCustomValue", componentId: "sc-2ijy2y-7" })(["", ""], ({ theme, $filled, $disabled, $prefix }) => css(["color:", ";display:flex;align-items:center;font-family:", ";font-size:", ";z-index:3;position:absolute;height:100%;top:0;", ":", ";bottom:0;pointer-events:none;"], $disabled && theme.orbit.paletteInkLight || ($filled ? theme.orbit.colorTextInput : theme.orbit.colorPlaceholderInput), theme.orbit.fontFamily, theme.orbit.fontSizeInputNormal, left, $prefix ? "48px" : theme.orbit.spaceSmall)); StyledCustomValue.defaultProps = { theme: defaultTheme }; const StyledSelectWrapper = styled.div.withConfig({ displayName: "Select__StyledSelectWrapper", componentId: "sc-2ijy2y-8" })(["height:100%;width:100%;position:relative;z-index:3;"]); const Select = /*#__PURE__*/React.forwardRef((props, ref) => { const { label, inlineLabel, placeholder, value, disabled = false, error, help, name, onChange, onBlur, onFocus, width = "100%", options, tabIndex, id, required, helpClosable = true, dataTest, prefix, spaceAfter, customValueText, insideInputGroup, dataAttrs, readOnly } = props; const filled = !(value == null || value === ""); const forID = useRandomId(); const selectId = id || forID; const hasTooltip = Boolean(error || help); const { tooltipShown, tooltipShownHover, setTooltipShownHover, labelRef, iconRef, setTooltipShown, handleFocus } = useErrorTooltip({ onFocus, hasTooltip }); const inputRef = React.useRef(null); const shown = tooltipShown || tooltipShownHover; return /*#__PURE__*/React.createElement(StyledLabel, { spaceAfter: spaceAfter, ref: inputRef, $width: width }, label && !inlineLabel && /*#__PURE__*/React.createElement(FormLabel, { filled: !!filled, error: !!error, help: !!help, disabled: disabled, labelRef: labelRef, iconRef: iconRef, onMouseEnter: () => setTooltipShownHover(true), onMouseLeave: () => setTooltipShownHover(false), required: required }, label), /*#__PURE__*/React.createElement(SelectContainer, { ref: label ? null : labelRef, disabled: disabled, error: !!error }, label && inlineLabel && /*#__PURE__*/React.createElement(StyledInlineLabel, { hasFeedback: !!(error || help), ref: labelRef }, help && !error && /*#__PURE__*/React.createElement(StyledIconWrapper, { ref: iconRef }, /*#__PURE__*/React.createElement(InformationCircle, { color: "info", size: "small" })), error && /*#__PURE__*/React.createElement(StyledIconWrapper, { ref: iconRef }, /*#__PURE__*/React.createElement(AlertCircle, { color: "critical", size: "small" })), /*#__PURE__*/React.createElement(FormLabel, { filled: !!value, required: required, error: !!error, help: !!help, inlineLabel: inlineLabel }, label)), /*#__PURE__*/React.createElement(StyledSelectWrapper, null, prefix && /*#__PURE__*/React.createElement(SelectPrefix, null, prefix), customValueText && /*#__PURE__*/React.createElement(StyledCustomValue, { $disabled: disabled, $filled: filled, $prefix: !!prefix }, customValueText), /*#__PURE__*/React.createElement(StyledSelect, { dataTest: dataTest, disabled: disabled, error: error, value: value == null ? "" : value, prefix: prefix, name: name, onFocus: handleFocus, onBlur: onBlur, onChange: onChange, filled: filled, customValueText: customValueText, tabIndex: tabIndex ? Number(tabIndex) : undefined, id: selectId, readOnly: readOnly, required: required, ref: ref, dataAttrs: dataAttrs, ariaDescribedby: shown ? `${selectId}-feedback` : undefined, ariaInvalid: error ? true : undefined }, placeholder && /*#__PURE__*/React.createElement("option", { label: placeholder.toString(), value: "" }, placeholder), options.map(option => /*#__PURE__*/React.createElement("option", { key: `option-${option.key || option.value}`, value: option.value, disabled: option.disabled }, option.label)))), /*#__PURE__*/React.createElement(SelectSuffix, { disabled: disabled }, /*#__PURE__*/React.createElement(ChevronDown, { color: "secondary" })), /*#__PURE__*/React.createElement(FakeInput, { disabled: disabled, error: error })), !insideInputGroup && hasTooltip && /*#__PURE__*/React.createElement(ErrorFormTooltip, { id: `${selectId}-feedback`, help: help, error: error, helpClosable: helpClosable, shown: shown, onShown: setTooltipShown, inlineLabel: inlineLabel, referenceElement: inlineLabel ? iconRef : inputRef })); }); // otherwise Unknown in storybook Select.displayName = "Select"; export default Select;