UNPKG

@intility/bifrost-react-select

Version:

React select component for Intility's design system, Bifrost.

246 lines (245 loc) 9.79 kB
/* eslint-disable @typescript-eslint/ban-ts-comment */ "use client"; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { forwardRef } from "react"; import ReactSelectDefaultExport, { components as originalComponents } from "react-select"; import AsyncReactSelect from "react-select/async"; import CreatableReactSelect from "react-select/creatable"; import AsyncCreatableReactSelect from "react-select/async-creatable"; import classNames from "classnames"; import Description from "@intility/bifrost-react/Description"; import Feedback from "@intility/bifrost-react/Feedback"; import Label from "@intility/bifrost-react/Label"; import useUniqueId from "@intility/bifrost-react/hooks/useUniqueId"; import useLocale from "@intility/bifrost-react/hooks/useLocale"; import DropdownIndicator from "./overrides/DropdownIndicator.internal.js"; import CustomInput from "./overrides/CustomInput.internal.js"; import CustomMenuList from "./overrides/CustomMenuList.internal.js"; import ClearIndicator from "./overrides/ClearIndicator.internal.js"; import CustomOption from "./overrides/CustomOption.internal.js"; import LoadingIndicator from "./overrides/LoadingIndicator.internal.js"; const ReactSelect = ReactSelectDefaultExport.default ?? ReactSelectDefaultExport; export const selectStyles = { container: (provided)=>({ ...provided, ".bf-label-description + &, .bf-label + &": { marginTop: "var(--bfs4)" } }), control: (provided, state)=>({ ...provided, "&:hover": { borderColor: "var(--bfc-base-c-inverted)", // Change color of dropdown icon when hover on Select ".bf-select__dropdown-indicator": { color: "var(--bfc-base-c)" } }, backgroundColor: state.isDisabled ? "var(--bfc-base-dimmed)" : "var(--bfc-base-3)", borderWidth: "1px", borderStyle: "solid", borderColor: state.isFocused ? "var(--bfc-base-c-inverted)" : state.isDisabled ? "transparent" : "var(--bfc-base-c-wcag)", boxShadow: state.isFocused ? "inset 0 0 0 1px var(--bfc-base-c-inverted)" : "none", borderRadius: "var(--bf-radius-s)", minHeight: undefined, cursor: "text" }), indicatorSeparator: ()=>({ display: "none" }), indicatorsContainer: (provided)=>({ ...provided, alignItems: "flex-start" }), clearIndicator: (provided)=>({ ...provided, "&:hover": { color: "var(--bfc-base-c)" }, color: "var(--bfc-base-c-2)", cursor: "pointer", padding: "var(--bfs4)", margin: "1px 4px 0px 0px" }), dropdownIndicator: (provided, state)=>({ ...provided, color: state.isFocused ? "var(--bfc-base-c)" : "var(--bfc-base-c-2)", cursor: "pointer", padding: "var(--bfs4)", marginRight: 8 }), input: (provided)=>({ ...provided, color: "var(--bfc-base-c)", fontFamily: "inherit", fontSize: "var(--bf-font-size-l)" }), menuPortal: (provided)=>({ ...provided, zIndex: 9999 }), menu: (provided)=>({ ...provided, backgroundColor: "transparent", boxShadow: "none", borderRadius: "none", zIndex: 3 }), menuList: (provided)=>({ ...provided, backgroundColor: "var(--bfc-base-3)", padding: 0, border: "1px solid var(--bfc-base-c-wcag)", borderRadius: "var(--bf-radius-s)" }), placeholder: (provided)=>({ ...provided, color: "var(--bfc-base-c-2)", fontSize: "var(--bf-font-size-l)" }), singleValue: (provided, state)=>({ ...provided, color: state.selectProps.menuIsOpen || state.isDisabled ? "var(--bfc-base-c-2)" : "var(--bfc-base-c)", fontSize: "var(--bf-font-size-l)" }), option: (provided, state)=>({ ...provided, display: "flex", justifyContent: !state.isMulti ? "space-between" : "normal", alignItems: "baseline", padding: "7px 12px", backgroundColor: state.isDisabled ? "var(--bfc-base-dimmed)" : state.isFocused ? "var(--bfc-base)" : "var(--bfc-base-3)", color: state.isDisabled ? "var(--bfc-base-c-2)" : "var(--bfc-base-c)", "& .bf-select-selected-icon": { color: "var(--bfc-base-c)", marginLeft: "var(--bfs4)" }, "&:hover": { backgroundColor: state.isDisabled ? "var(--bfc-base-dimmed)" : "var(--bfc-base)", cursor: state.isDisabled ? "default" : "pointer" }, fontSize: "var(--bf-font-size-l)", fontWeight: state.isSelected ? 600 : 400, wordBreak: "break-word", whiteSpace: "normal" }), multiValue: (provided, state)=>({ ...provided, backgroundColor: "var(--bfc-base)", borderRadius: "var(--bf-radius-xs)", border: state.isDisabled ? "1px solid var(--bfc-base-c-disabled)" : "var(--bf-border)", opacity: state.isDisabled ? 0.5 : 1 }), multiValueLabel: (provided)=>({ ...provided, fontSize: "var(--bf-font-size-m)", padding: "1.5px 4px 1.5px 8px", color: "inherit" }), multiValueRemove: (provided, state)=>({ ...provided, color: "var(--bfc-base-c-2)", paddingLeft: 5, paddingRight: 5, background: state.isFocused && "var(--bfc-theme-2)", "&:hover": { color: "var(--bfc-base-c)", cursor: "pointer", background: "var(--bfc-base-2)" }, "&:active": { background: "var(--bfc-base-3)" }, svg: { marginTop: "1px" } }), group: (provided)=>({ ...provided, padding: "var(--bfs6) 0", "&:first-of-type": { marginTop: "var(--bfs4)" } }), groupHeading: (provided)=>({ ...provided, textTransform: "capitalize", color: "var(--bfc-base-c-2)", fontSize: "var(--bf-font-size-s)", marginBottom: "var(--bfs2)" }) }; export const selectComponents = { ...originalComponents, DropdownIndicator, Input: CustomInput, MenuList: CustomMenuList, ClearIndicator, Option: CustomOption, LoadingIndicator }; /** * Select HOC */ const SelectHOC = (Selector)=>{ // @ts-ignore // eslint-disable-next-line @typescript-eslint/no-explicit-any, react/display-name const GeneratedSelect = /*#__PURE__*/ forwardRef(({ label, hideLabel = false, isDisabled = false, state, feedback, required = false, description, requiredNoLabel = false, optional = false, inputId, className, style, loading = false, components, small = false, ...props }, ref)=>{ const selectId = useUniqueId(inputId); const locale = useLocale(); return /*#__PURE__*/ _jsxs("div", { className: classNames(className, "bf-select-container", "bf-open-sans", { "bf-select-disabled": isDisabled, "bf-select-alert": !isDisabled && state === "alert", "bf-select-small": small }), style: style, "data-testid": "bf-select-container", children: [ !hideLabel && /*#__PURE__*/ _jsx(Label, { htmlFor: selectId, required: !isDisabled && required && !requiredNoLabel, optional: optional, disabled: isDisabled, children: label }), /*#__PURE__*/ _jsx(Description, { children: description }), /*#__PURE__*/ _jsx(Selector, { ref: ref, inputId: selectId, placeholder: "", components: { ...selectComponents, ...components }, styles: selectStyles, isDisabled: isDisabled, classNamePrefix: "bf-select", required: !isDisabled && (required || requiredNoLabel), "aria-label": label, hideSelectedOptions: false, closeMenuOnSelect: props.isMulti ? false : true, isLoading: loading ?? props.isLoading, loadingMessage: ()=>locale.loading + "...", ...props }), /*#__PURE__*/ _jsx(Feedback, { children: feedback }) ] }); }); return GeneratedSelect; }; /** * Select component - dropdown list */ export const Select = SelectHOC(ReactSelect); Select.displayName = "Select"; const AsyncSelect = SelectHOC(AsyncReactSelect); AsyncSelect.displayName = "AsyncSelect"; const CreatableSelect = SelectHOC(CreatableReactSelect); CreatableSelect.displayName = "CreatableSelect"; const AsyncCreatableSelect = SelectHOC(AsyncCreatableReactSelect); AsyncCreatableSelect.displayName = "AsyncCreatableSelect"; export { AsyncSelect, CreatableSelect, AsyncCreatableSelect }; export default Select;