UNPKG

@bigbinary/neetoui

Version:

neetoUI drives the experience at all neeto products

524 lines (517 loc) 22.7 kB
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