@bigbinary/neetoui
Version:
neetoUI drives the experience at all neeto products
524 lines (517 loc) • 22.7 kB
JavaScript
import _defineProperty$1 from '@babel/runtime/helpers/defineProperty';
import _objectWithoutProperties$1 from '@babel/runtime/helpers/objectWithoutProperties';
import * as React from 'react';
import { forwardRef, useRef, useState, useEffect, useCallback } from 'react';
import classnames from 'classnames';
import { isPresent, _existsBy } from '@bigbinary/neeto-cist';
import Down from '@bigbinary/neeto-icons/Down';
import Close from '@bigbinary/neeto-icons/Close';
import { isEmpty, prop, mergeDeepRight, assoc, flatten, pluck } from 'ramda';
import { u as useStateManager, S as Select$1, h as handleInputChange, a as useCreatable, c as components, C as CreatableSelect } from './react-select-creatable.esm-opiJTCqo.js';
import _extends from '@babel/runtime/helpers/esm/extends';
import '@babel/runtime/helpers/objectSpread2';
import '@babel/runtime/helpers/slicedToArray';
import '@babel/runtime/helpers/classCallCheck';
import '@babel/runtime/helpers/createClass';
import '@babel/runtime/helpers/inherits';
import '@babel/runtime/helpers/createSuper';
import '@babel/runtime/helpers/toConsumableArray';
import '@babel/runtime/helpers/taggedTemplateLiteral';
import '@babel/runtime/helpers/typeof';
import 'react-dom';
import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
import _objectSpread$1 from '@babel/runtime/helpers/esm/objectSpread2';
import _slicedToArray from '@babel/runtime/helpers/esm/slicedToArray';
import _objectWithoutProperties from '@babel/runtime/helpers/esm/objectWithoutProperties';
import { u as useId } from './useId-Jj9hXm-g.js';
import 'react-router-dom';
import '@bigbinary/neeto-hotkeys';
import './overlayManager.js';
import { h as hyphenize } from './index-DzZtLRHp.js';
import 'qs';
import Label from './Label.js';
import Spinner from './Spinner.js';
import Tooltip from './Tooltip.js';
import { jsxs, jsx } from 'react/jsx-runtime';
import '@babel/runtime/helpers/esm/classCallCheck';
import '@babel/runtime/helpers/esm/createClass';
import '@babel/runtime/helpers/esm/inherits';
import '@babel/runtime/helpers/esm/createSuper';
import '@babel/runtime/helpers/esm/toConsumableArray';
import '@babel/runtime/helpers/extends';
import '@babel/runtime/helpers/esm/taggedTemplateLiteral';
import '@babel/runtime/helpers/esm/typeof';
import './en-DVlE9xuu.js';
import './index-DyUNP5G9.js';
import 'dayjs';
import 'dayjs/plugin/localeData';
import 'dayjs/plugin/utc';
import 'dayjs/plugin/weekday';
import 'dayjs/plugin/weekOfYear';
import 'i18next';
import '@bigbinary/neeto-icons/Help';
import './Button.js';
import '@tippyjs/react';
import 'tippy.js';
import './usePrefersReducedMotion-n4ZJtExQ.js';
import './Popover.js';
import './Typography.js';
var StateManagedSelect = /*#__PURE__*/forwardRef(function (props, ref) {
var baseSelectProps = useStateManager(props);
return /*#__PURE__*/React.createElement(Select$1, _extends({
ref: ref
}, baseSelectProps));
});
var _excluded$1 = ["defaultOptions", "cacheOptions", "loadOptions", "options", "isLoading", "onInputChange", "filterOption"];
function useAsync(_ref) {
var _ref$defaultOptions = _ref.defaultOptions,
propsDefaultOptions = _ref$defaultOptions === void 0 ? false : _ref$defaultOptions,
_ref$cacheOptions = _ref.cacheOptions,
cacheOptions = _ref$cacheOptions === void 0 ? false : _ref$cacheOptions,
propsLoadOptions = _ref.loadOptions;
_ref.options;
var _ref$isLoading = _ref.isLoading,
propsIsLoading = _ref$isLoading === void 0 ? false : _ref$isLoading,
propsOnInputChange = _ref.onInputChange,
_ref$filterOption = _ref.filterOption,
filterOption = _ref$filterOption === void 0 ? null : _ref$filterOption,
restSelectProps = _objectWithoutProperties(_ref, _excluded$1);
var propsInputValue = restSelectProps.inputValue;
var lastRequest = useRef(undefined);
var mounted = useRef(false);
var _useState = useState(Array.isArray(propsDefaultOptions) ? propsDefaultOptions : undefined),
_useState2 = _slicedToArray(_useState, 2),
defaultOptions = _useState2[0],
setDefaultOptions = _useState2[1];
var _useState3 = useState(typeof propsInputValue !== 'undefined' ? propsInputValue : ''),
_useState4 = _slicedToArray(_useState3, 2),
stateInputValue = _useState4[0],
setStateInputValue = _useState4[1];
var _useState5 = useState(propsDefaultOptions === true),
_useState6 = _slicedToArray(_useState5, 2),
isLoading = _useState6[0],
setIsLoading = _useState6[1];
var _useState7 = useState(undefined),
_useState8 = _slicedToArray(_useState7, 2),
loadedInputValue = _useState8[0],
setLoadedInputValue = _useState8[1];
var _useState9 = useState([]),
_useState10 = _slicedToArray(_useState9, 2),
loadedOptions = _useState10[0],
setLoadedOptions = _useState10[1];
var _useState11 = useState(false),
_useState12 = _slicedToArray(_useState11, 2),
passEmptyOptions = _useState12[0],
setPassEmptyOptions = _useState12[1];
var _useState13 = useState({}),
_useState14 = _slicedToArray(_useState13, 2),
optionsCache = _useState14[0],
setOptionsCache = _useState14[1];
var _useState15 = useState(undefined),
_useState16 = _slicedToArray(_useState15, 2),
prevDefaultOptions = _useState16[0],
setPrevDefaultOptions = _useState16[1];
var _useState17 = useState(undefined),
_useState18 = _slicedToArray(_useState17, 2),
prevCacheOptions = _useState18[0],
setPrevCacheOptions = _useState18[1];
if (cacheOptions !== prevCacheOptions) {
setOptionsCache({});
setPrevCacheOptions(cacheOptions);
}
if (propsDefaultOptions !== prevDefaultOptions) {
setDefaultOptions(Array.isArray(propsDefaultOptions) ? propsDefaultOptions : undefined);
setPrevDefaultOptions(propsDefaultOptions);
}
useEffect(function () {
mounted.current = true;
return function () {
mounted.current = false;
};
}, []);
var loadOptions = useCallback(function (inputValue, callback) {
if (!propsLoadOptions) return callback();
var loader = propsLoadOptions(inputValue, callback);
if (loader && typeof loader.then === 'function') {
loader.then(callback, function () {
return callback();
});
}
}, [propsLoadOptions]);
useEffect(function () {
if (propsDefaultOptions === true) {
loadOptions(stateInputValue, function (options) {
if (!mounted.current) return;
setDefaultOptions(options || []);
setIsLoading(!!lastRequest.current);
});
}
// NOTE: this effect is designed to only run when the component mounts,
// so we don't want to include any hook dependencies
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
var onInputChange = useCallback(function (newValue, actionMeta) {
var inputValue = handleInputChange(newValue, actionMeta, propsOnInputChange);
if (!inputValue) {
lastRequest.current = undefined;
setStateInputValue('');
setLoadedInputValue('');
setLoadedOptions([]);
setIsLoading(false);
setPassEmptyOptions(false);
return;
}
if (cacheOptions && optionsCache[inputValue]) {
setStateInputValue(inputValue);
setLoadedInputValue(inputValue);
setLoadedOptions(optionsCache[inputValue]);
setIsLoading(false);
setPassEmptyOptions(false);
} else {
var request = lastRequest.current = {};
setStateInputValue(inputValue);
setIsLoading(true);
setPassEmptyOptions(!loadedInputValue);
loadOptions(inputValue, function (options) {
if (!mounted) return;
if (request !== lastRequest.current) return;
lastRequest.current = undefined;
setIsLoading(false);
setLoadedInputValue(inputValue);
setLoadedOptions(options || []);
setPassEmptyOptions(false);
setOptionsCache(options ? _objectSpread$1(_objectSpread$1({}, optionsCache), {}, _defineProperty({}, inputValue, options)) : optionsCache);
});
}
}, [cacheOptions, loadOptions, loadedInputValue, optionsCache, propsOnInputChange]);
var options = passEmptyOptions ? [] : stateInputValue && loadedInputValue ? loadedOptions : defaultOptions || [];
return _objectSpread$1(_objectSpread$1({}, restSelectProps), {}, {
options: options,
isLoading: isLoading || propsIsLoading,
onInputChange: onInputChange,
filterOption: filterOption
});
}
var AsyncSelect = /*#__PURE__*/forwardRef(function (props, ref) {
var stateManagedProps = useAsync(props);
var selectProps = useStateManager(stateManagedProps);
return /*#__PURE__*/React.createElement(Select$1, _extends({
ref: ref
}, selectProps));
});
var AsyncCreatableSelect = /*#__PURE__*/forwardRef(function (props, ref) {
var stateManagerProps = useAsync(props);
var creatableProps = useStateManager(stateManagerProps);
var selectProps = useCreatable(creatableProps);
return /*#__PURE__*/React.createElement(Select$1, _extends({
ref: ref
}, selectProps));
});
var _excluded = ["children"],
_excluded2 = ["size", "label", "required", "error", "helpText", "className", "innerRef", "isCreateable", "strategy", "id", "labelProps", "value", "defaultValue", "components", "optionRemapping", "onMenuClose", "onMenuOpen", "onKeyDown", "styles", "dataTestid"];
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), true).forEach(function (r) { _defineProperty$1(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
var SIZES = {
small: "small",
medium: "medium",
large: "large"
};
var STRATEGIES = {
"default": "default",
fixed: "fixed"
};
var Control = function Control(_ref) {
var children = _ref.children,
props = _objectWithoutProperties$1(_ref, _excluded);
var selectProps = props.selectProps,
hasValue = props.hasValue;
return /*#__PURE__*/jsxs(components.Control, _objectSpread(_objectSpread({}, props), {}, {
children: [hasValue && selectProps.isMulti && /*#__PURE__*/jsx("span", {
className: "neeto-ui-btn neeto-ui-btn--style-secondary neeto-ui-react-select__add-btn",
children: selectProps.addButtonLabel || "Add"
}), " ", children]
}));
};
var DropdownIndicator = function DropdownIndicator(props) {
return /*#__PURE__*/jsx(components.DropdownIndicator, _objectSpread(_objectSpread({}, props), {}, {
innerProps: _objectSpread(_objectSpread({}, props.innerProps), {}, _defineProperty$1({}, "data-testid", "action-select-indicator")),
children: /*#__PURE__*/jsx(Down, {
size: 16
})
}));
};
var ClearIndicator = function ClearIndicator(props) {
return /*#__PURE__*/jsx(components.ClearIndicator, _objectSpread(_objectSpread({}, props), {}, {
innerProps: _objectSpread(_objectSpread({}, props.innerProps), {}, {
"data-testid": "clear-select-indicator"
}),
children: /*#__PURE__*/jsx(Close, {
size: 16
})
}));
};
var MultiValueRemove = function MultiValueRemove(props) {
return /*#__PURE__*/jsx(components.MultiValueRemove, _objectSpread(_objectSpread({}, props), {}, {
children: /*#__PURE__*/jsx(Close, {
size: 16
})
}));
};
var CustomInput = function CustomInput(props) {
var selectProps = props.selectProps;
return /*#__PURE__*/jsx(components.Input, _objectSpread(_objectSpread({}, props), {}, {
"data-testid": selectProps ? selectProps["data-testid"] : "select-input",
maxLength: selectProps && selectProps.maxLength
}));
};
var CustomOption = function CustomOption(props) {
var ref = useRef();
var innerProps = props.innerProps,
_props$data = props.data,
dataTestid = _props$data.dataTestid,
_props$data$tooltipPr = _props$data.tooltipProps,
tooltipProps = _props$data$tooltipPr === void 0 ? {} : _props$data$tooltipPr;
useEffect(function () {
props.isSelected && ref.current.scrollIntoView();
}, [props.isSelected]);
var optionComponent = /*#__PURE__*/jsx(components.Option, _objectSpread(_objectSpread({}, props), {}, {
innerRef: ref,
innerProps: _objectSpread(_objectSpread({}, innerProps), {}, {
"data-testid": dataTestid || "".concat(hyphenize(props.label), "-select-option")
})
}));
return isPresent(tooltipProps) ? /*#__PURE__*/jsx(Tooltip, _objectSpread(_objectSpread({
position: "bottom-start",
zIndex: 1000001
}, tooltipProps), {}, {
children: /*#__PURE__*/jsx("div", {
children: optionComponent
})
})) : optionComponent;
};
var Placeholder = function Placeholder(props) {
var selectProps = props.selectProps;
return /*#__PURE__*/jsx(components.Placeholder, _objectSpread(_objectSpread({}, props), {}, {
innerProps: _objectSpread(_objectSpread({}, props.innerProps), {}, {
"data-testid": selectProps !== null && selectProps !== void 0 && selectProps.hyphenatedDataTestIdLabel ? "".concat(selectProps.hyphenatedDataTestIdLabel, "-select-placeholder") : "select-placeholder"
})
}));
};
var Menu = function Menu(props) {
var selectProps = props.selectProps;
return /*#__PURE__*/jsx(components.Menu, _objectSpread(_objectSpread({}, props), {}, {
innerProps: _objectSpread(_objectSpread({}, props.innerProps), {}, {
"data-testid": selectProps ? "".concat(selectProps.hyphenatedDataTestIdLabel, "-select-menu") : "select-menu"
})
}));
};
var SingleValue = function SingleValue(props) {
return /*#__PURE__*/jsx(components.SingleValue, _objectSpread(_objectSpread({}, props), {}, {
innerProps: _objectSpread(_objectSpread({}, props.innerProps), {}, {
"data-testid": "select-single-value"
})
}));
};
var ValueContainer = function ValueContainer(props) {
var selectProps = props.selectProps;
return /*#__PURE__*/jsx(components.ValueContainer, _objectSpread(_objectSpread({}, props), {}, {
innerProps: _objectSpread(_objectSpread({}, props.innerProps), {}, {
name: selectProps.name,
"data-testid": selectProps ? "".concat(selectProps.hyphenatedDataTestIdLabel, "-select-value-container") : "select-value-container"
})
}));
};
var MenuList = function MenuList(props) {
var _props$selectProps = props.selectProps,
fetchMore = _props$selectProps.fetchMore,
totalOptionsCount = _props$selectProps.totalOptionsCount,
isAsyncLoadOptionEnabled = _props$selectProps.isAsyncLoadOptionEnabled,
options = _props$selectProps.options,
_props$selectProps$po = _props$selectProps.portalProps,
portalProps = _props$selectProps$po === void 0 ? {} : _props$selectProps$po;
var hasMore = isAsyncLoadOptionEnabled && totalOptionsCount > options.length;
var loaderRef = useRef();
useEffect(function () {
var observer = null;
if (loaderRef.current && isAsyncLoadOptionEnabled) {
observer = new IntersectionObserver(function (entries) {
return entries[0].isIntersecting && fetchMore();
}, {
root: null,
rootMargin: "0px",
threshold: 0.1
});
observer.observe(loaderRef.current);
}
return function () {
var _observer;
if (!(loaderRef.current && isAsyncLoadOptionEnabled)) return;
(_observer = observer) === null || _observer === void 0 ? void 0 : _observer.unobserve(loaderRef.current);
};
}, [hasMore]);
return /*#__PURE__*/jsxs(components.MenuList, _objectSpread(_objectSpread(_objectSpread({}, props), portalProps), {}, {
innerProps: _objectSpread(_objectSpread({}, props.innerProps), {}, _defineProperty$1({}, "data-testid", "menu-list")),
children: [props.children, hasMore && /*#__PURE__*/jsx("div", {
className: "neeto-ui-flex neeto-ui-w-full neeto-ui-items-center neeto-ui-justify-center neeto-ui-py-3",
"data-testid": "loader",
ref: loaderRef,
children: /*#__PURE__*/jsx(Spinner, {})
})]
}));
};
var Select = function Select(_ref2) {
var _ref3, _otherProps$isMenuOpe;
var _ref2$size = _ref2.size,
size = _ref2$size === void 0 ? SIZES.medium : _ref2$size,
_ref2$label = _ref2.label,
label = _ref2$label === void 0 ? "" : _ref2$label,
_ref2$required = _ref2.required,
required = _ref2$required === void 0 ? false : _ref2$required,
_ref2$error = _ref2.error,
error = _ref2$error === void 0 ? "" : _ref2$error,
_ref2$helpText = _ref2.helpText,
helpText = _ref2$helpText === void 0 ? "" : _ref2$helpText,
_ref2$className = _ref2.className,
className = _ref2$className === void 0 ? "" : _ref2$className,
innerRef = _ref2.innerRef,
_ref2$isCreateable = _ref2.isCreateable,
isCreateable = _ref2$isCreateable === void 0 ? false : _ref2$isCreateable,
_ref2$strategy = _ref2.strategy,
strategy = _ref2$strategy === void 0 ? STRATEGIES["default"] : _ref2$strategy,
id = _ref2.id,
labelProps = _ref2.labelProps,
value = _ref2.value,
defaultValue = _ref2.defaultValue,
componentOverrides = _ref2.components,
_ref2$optionRemapping = _ref2.optionRemapping,
optionRemapping = _ref2$optionRemapping === void 0 ? {} : _ref2$optionRemapping,
onMenuClose = _ref2.onMenuClose,
onMenuOpen = _ref2.onMenuOpen,
onKeyDown = _ref2.onKeyDown,
_ref2$styles = _ref2.styles,
styles = _ref2$styles === void 0 ? {} : _ref2$styles,
_ref2$dataTestid = _ref2.dataTestid,
dataTestid = _ref2$dataTestid === void 0 ? "nui" : _ref2$dataTestid,
otherProps = _objectWithoutProperties$1(_ref2, _excluded2);
var inputId = useId(id);
var isMenuOpen = useRef((_ref3 = (_otherProps$isMenuOpe = otherProps.isMenuOpen) !== null && _otherProps$isMenuOpe !== void 0 ? _otherProps$isMenuOpe : otherProps.defaultMenuIsOpen) !== null && _ref3 !== void 0 ? _ref3 : false);
var hyphenatedDataTestIdLabel = isEmpty(label) ? hyphenize(dataTestid) : hyphenize(label);
var Parent = StateManagedSelect;
if (isCreateable) {
Parent = CreatableSelect;
}
if (otherProps.loadOptions) {
Parent = isCreateable ? AsyncCreatableSelect : AsyncSelect;
}
if (optionRemapping.value) {
otherProps.getOptionValue = prop(optionRemapping.value);
}
if (optionRemapping.label) {
otherProps.getOptionLabel = prop(optionRemapping.label);
}
var portalProps = strategy === STRATEGIES.fixed && {
menuPortalTarget: document.body,
styles: mergeDeepRight({
menuPortal: assoc("zIndex", 999999)
}, styles),
menuPosition: "fixed"
};
var options = otherProps.options,
defaultOptions = otherProps.defaultOptions,
getOptionValue = otherProps.getOptionValue;
var getRealOptionValue = function getRealOptionValue(option) {
if (typeof getOptionValue !== "function") {
return option.value;
}
return getOptionValue(option);
};
var findInOptions = function findInOptions(value) {
var _currentOptions;
var fetchMore = otherProps.fetchMore,
isMulti = otherProps.isMulti;
if (!value || isMulti || isPresent(fetchMore)) {
return value;
}
var currentOptions = options || defaultOptions;
if (Array.isArray(value)) value = value[0];
var isGrouped = _existsBy({
options: Array.isArray
}, currentOptions);
if (isGrouped) {
currentOptions = flatten(pluck("options", currentOptions));
}
return (_currentOptions = currentOptions) === null || _currentOptions === void 0 ? void 0 : _currentOptions.filter(function (opt) {
return getRealOptionValue(opt) === getRealOptionValue(value);
});
};
var handleMenuOpen = function handleMenuOpen() {
isMenuOpen.current = true;
onMenuOpen === null || onMenuOpen === void 0 ? void 0 : onMenuOpen();
};
var handleMenuClose = function handleMenuClose() {
isMenuOpen.current = false;
onMenuClose === null || onMenuClose === void 0 ? void 0 : onMenuClose();
};
var handleKeyDown = function handleKeyDown(e) {
if (!isMenuOpen.current) return;
e.stopPropagation();
onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(e);
};
return /*#__PURE__*/jsxs("div", {
className: classnames(["neeto-ui-input__wrapper", className]),
"data-testid": "".concat(hyphenatedDataTestIdLabel, "-select-container-wrapper"),
children: [label && /*#__PURE__*/jsx(Label, _objectSpread(_objectSpread({
required: required,
"data-testid": "".concat(hyphenatedDataTestIdLabel, "-input-label"),
htmlFor: inputId
}, labelProps), {}, {
children: label
})), /*#__PURE__*/jsx(Parent, _objectSpread({
blurInputOnSelect: false,
classNamePrefix: "neeto-ui-react-select",
closeMenuOnSelect: !otherProps.isMulti,
"data-testid": "".concat(hyphenatedDataTestIdLabel, "-select-container"),
defaultValue: findInOptions(defaultValue),
ref: innerRef,
value: findInOptions(value),
className: classnames(["neeto-ui-react-select__container"], {
"neeto-ui-react-select__container--error": !!error,
"neeto-ui-react-select__container--small": size === SIZES.small,
"neeto-ui-react-select__container--medium": size === SIZES.medium,
"neeto-ui-react-select__container--large": size === SIZES.large
}),
components: _objectSpread({
Input: CustomInput,
Option: CustomOption,
DropdownIndicator: DropdownIndicator,
ClearIndicator: ClearIndicator,
MultiValueRemove: MultiValueRemove,
Placeholder: Placeholder,
Menu: Menu,
ValueContainer: ValueContainer,
MenuList: MenuList,
SingleValue: SingleValue,
Control: Control
}, componentOverrides),
onKeyDown: handleKeyDown,
onMenuClose: handleMenuClose,
onMenuOpen: handleMenuOpen
}, _objectSpread(_objectSpread(_objectSpread({
inputId: inputId,
label: label,
styles: styles
}, portalProps), otherProps), {}, {
hyphenatedDataTestIdLabel: hyphenatedDataTestIdLabel
}))), !!error && /*#__PURE__*/jsx("p", {
className: "neeto-ui-input__error",
"data-testid": "".concat(hyphenatedDataTestIdLabel, "-select-error"),
children: error
}), helpText && /*#__PURE__*/jsx("p", {
className: "neeto-ui-input__help-text",
"data-testid": "".concat(hyphenatedDataTestIdLabel, "-select-help-text"),
children: helpText
})]
});
};
export { Select as default };
//# sourceMappingURL=Select.js.map