@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
JavaScript
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;