@braineet/ui
Version:
Braineet design system
222 lines (221 loc) • 8.66 kB
JavaScript
var _excluded = ["value", "defaultValue", "options", "disabled", "multiple", "field", "form", "placeholder", "renderPlaceholder", "renderOption", "className", "noArrow", "noResult", "size", "maxHeightList", "maxWidthList", "onChange", "comboboxPlaceholder", "disableSearch", "classNames", "buttonStyle", "popoverStyles", "popoverProps", "virtual", "minOptionsForVirtual", "buttonProps"],
_excluded2 = ["value", "setValue"];
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
/* eslint-disable react/no-array-index-key */
import React, { useMemo } from 'react';
import { useVirtualizer } from '@tanstack/react-virtual';
import { getIn } from 'formik';
import { useSearch } from '../../hooks';
import Box from '../box';
import { Combobox, ComboboxList, useCombobox } from '../combobox';
import { RenderOptions } from './renderOptions';
import RenderPlaceholder from './RenderPlaceholder';
import { useSelectState } from './select-state';
import { SelectPopover } from './SelectPopover';
import { StyledSelect, StyledIconSelect, StyledSelected } from './styles';
/**
* The `Select` component.
*/
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
export var Select = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
var value = _ref.value,
defaultValue = _ref.defaultValue,
options = _ref.options,
disabled = _ref.disabled,
multiple = _ref.multiple,
field = _ref.field,
form = _ref.form,
placeholder = _ref.placeholder,
renderPlaceholder = _ref.renderPlaceholder,
renderOption = _ref.renderOption,
className = _ref.className,
noArrow = _ref.noArrow,
noResult = _ref.noResult,
size = _ref.size,
maxHeightList = _ref.maxHeightList,
maxWidthList = _ref.maxWidthList,
onChange = _ref.onChange,
comboboxPlaceholder = _ref.comboboxPlaceholder,
disableSearch = _ref.disableSearch,
classNames = _ref.classNames,
buttonStyle = _ref.buttonStyle,
popoverStyles = _ref.popoverStyles,
popoverProps = _ref.popoverProps,
virtual = _ref.virtual,
minOptionsForVirtual = _ref.minOptionsForVirtual,
buttonProps = _ref.buttonProps,
selectStateProps = _objectWithoutPropertiesLoose(_ref, _excluded);
var localValue = field ? field.value : value;
var _useSearch = useSearch(options, ['label']),
matches = _useSearch.items,
setValue = _useSearch.setValue;
var combobox = useCombobox(_extends({
setValue: setValue
}, selectStateProps));
var comboboxValue = combobox.value,
setValueCombobox = combobox.setValue,
selectProps = _objectWithoutPropertiesLoose(combobox, _excluded2);
var selectValueProps = localValue !== undefined ? {
value: multiple ? localValue || [] : "" + localValue || ''
} : {
defaultValue: defaultValue || (multiple ? [] : '')
};
var select = useSelectState(_extends({}, selectValueProps, {
virtualFocus: false,
setValue: function setValue(v) {
if (form && field != null && field.name && form != null && form.setFieldValue) {
form == null || form.setFieldValue(field.name, v);
}
if (onChange) onChange(v);
}
}, selectProps));
var hasVirtual = virtual && matches.length >= minOptionsForVirtual;
var virtualizer = useVirtualizer({
count: matches.length,
getScrollElement: function getScrollElement() {
return select.contentElement;
},
estimateSize: function estimateSize() {
return 32;
}
});
if (!select.mounted && combobox.value) {
combobox.setValue('');
}
var error = (form == null ? void 0 : form.errors) && (field == null ? void 0 : field.name) && getIn(form.errors, field.name);
var touch = (form == null ? void 0 : form.touched) && (field == null ? void 0 : field.name) && getIn(form.touched, field.name);
var _useMemo = useMemo(function () {
var selectedValue;
var selectValueObj;
if (Array.isArray(select.value)) {
if (select.value.length >= 1 && options.length > 0) {
selectedValue = "(" + select.value.length + ") " + select.value.reduce(function (acc, elm, index) {
var label;
if (options.find(function (option) {
return option.value === elm;
})) {
label = options.find(function (option) {
return option.value === elm;
}).label;
}
return acc + (label !== undefined ? label + (index < select.value.length - 1 ? ', ' : '') : '');
}, '');
} else {
selectedValue = undefined;
}
} else {
selectedValue = _extends({}, options.find(function (elm) {
return "" + elm.value === "" + select.value;
})).label;
selectValueObj = _extends({}, options.find(function (elm) {
return "" + elm.value === "" + select.value;
}));
}
return {
selected: selectedValue,
selectObj: selectValueObj
};
}, [options, select.value]),
selected = _useMemo.selected,
selectObj = _useMemo.selectObj;
var optionItems = hasVirtual ? virtualizer.getVirtualItems().map(function (virtualItem) {
return _extends({}, matches[virtualItem.index], virtualItem, {
ref: virtualizer.measureElement,
style: {
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: virtualItem.size + "px",
transform: "translateY(" + virtualItem.start + "px)"
}
});
}) : matches;
return /*#__PURE__*/_jsxs(_Fragment, {
children: [/*#__PURE__*/_jsxs(StyledSelect, _extends({
type: "button",
state: select,
ref: ref,
"data-invalid": touch && error,
"data-filled": selected,
disabled: disabled,
value: select.value,
className: className,
size: size,
$buttonStyle: buttonStyle
}, buttonProps, {
children: [!noArrow && /*#__PURE__*/_jsx(StyledIconSelect, {
name: "drop",
size: 24,
color: "black",
className: classNames.selectIndicator
}), /*#__PURE__*/_jsx(StyledSelected, {
as: "span",
className: classNames.selectedItemWrapper,
children: /*#__PURE__*/_jsx(RenderPlaceholder, {
placeholder: placeholder,
value: select.value,
selected: selected,
selectObj: selectObj,
renderPlaceholder: renderPlaceholder,
renderOption: renderOption,
classNames: classNames,
size: size
})
})]
})), /*#__PURE__*/_jsx(SelectPopover, _extends({
state: select,
composite: !(!disableSearch && options.length >= 5),
className: classNames.popover,
$maxHeightList: maxHeightList,
$maxWidthList: maxWidthList,
$padding: !disableSearch && options.length >= 5 ? '0 0.5rem 0.5rem' : '0.5rem',
$popoverStyles: popoverStyles
}, popoverProps, {
children: select.mounted && /*#__PURE__*/_jsxs(_Fragment, {
children: [!disableSearch && options.length >= 5 ? /*#__PURE__*/_jsx(Box, {
position: "sticky",
top: "0",
backgroundColor: "inherit",
padding: "0.5rem 0",
zIndex: "1",
children: /*#__PURE__*/_jsx(Combobox, {
state: combobox,
comboboxOptions: {
autoComplete: 'list'
},
placeholder: comboboxPlaceholder,
withCancel: true,
className: classNames.combobox
})
}) : null, /*#__PURE__*/_jsx(ComboboxList, {
state: combobox,
style: {
height: hasVirtual && virtualizer.getTotalSize() + "px",
width: '100%',
position: 'relative'
},
children: /*#__PURE__*/_jsx(RenderOptions, {
value: select.value,
options: optionItems,
multiple: multiple,
noResult: noResult,
renderOption: renderOption,
form: form,
field: field,
classNames: classNames
})
})]
})
}))]
});
});
Select.defaultProps = {
size: 'md',
noResult: 'No options available',
classNames: {},
buttonProps: {},
virtual: true,
minOptionsForVirtual: 50
};