@itwin/itwinui-react
Version:
A react component library for iTwinUI
147 lines (146 loc) • 4.53 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', {
value: true,
});
Object.defineProperty(exports, 'ComboBoxMenu', {
enumerable: true,
get: function () {
return ComboBoxMenu;
},
});
const _interop_require_default = require('@swc/helpers/_/_interop_require_default');
const _interop_require_wildcard = require('@swc/helpers/_/_interop_require_wildcard');
const _react = /*#__PURE__*/ _interop_require_wildcard._(require('react'));
const _classnames = /*#__PURE__*/ _interop_require_default._(
require('classnames'),
);
const _index = require('../../utils/index.js');
const _helpers = require('./helpers.js');
const _List = require('../List/List.js');
const VirtualizedComboBoxMenu = (props) => {
let { children, ...rest } = props;
let { filteredOptions, getMenuItem, focusedIndex } = (0,
_index.useSafeContext)(_helpers.ComboBoxStateContext);
let { menuRef } = (0, _index.useSafeContext)(_helpers.ComboBoxRefsContext);
let mostlySubLabeled = _react.useMemo(() => {
let numberOfSubLabels = 0;
for (let i = 0; i < Math.min(5, filteredOptions.length); i++)
if (filteredOptions[i].sublabel) numberOfSubLabels++;
return numberOfSubLabels >= Math.min(3, filteredOptions.length);
}, [filteredOptions]);
let focusedVisibleIndex = _react.useMemo(() => {
let currentElement = menuRef.current?.querySelector(
`[data-iui-index="${focusedIndex}"]`,
);
if (!currentElement) return focusedIndex;
return Number(
currentElement.getAttribute('data-iui-filtered-index') ?? focusedIndex,
);
}, [focusedIndex, menuRef]);
let { virtualizer, css: virtualizerCss } = (0, _index.useVirtualScroll)({
count: filteredOptions.length || 1,
getScrollElement: () => menuRef.current,
estimateSize: () => (mostlySubLabeled ? 48 : 36),
gap: -1,
});
(0, _index.useLayoutEffect)(() => {
virtualizer.scrollToIndex(focusedVisibleIndex);
}, [virtualizer, focusedVisibleIndex]);
let virtualItemRenderer = _react.useCallback(
(virtualItem) => {
let menuItem =
filteredOptions.length > 0
? getMenuItem(filteredOptions[virtualItem.index], virtualItem.index)
: children;
return _react.cloneElement(menuItem, {
key: virtualItem.key,
ref: virtualizer.measureElement,
'data-iui-virtualizer': 'item',
style: {
width: '100%',
transform: `translateY(${virtualItem.start}px)`,
},
});
},
[filteredOptions, getMenuItem, children, virtualizer.measureElement],
);
return _react.createElement(
'div',
{
style: {
display: 'contents',
},
},
_react.createElement(
_index.ShadowRoot,
{
css: virtualizerCss,
},
_react.createElement(
_index.Box,
{
as: 'div',
'data-iui-virtualizer': 'root',
...rest,
style: {
minBlockSize: virtualizer.getTotalSize(),
...props.style,
},
},
_react.createElement('slot', null),
),
),
_react.createElement(
_react.Fragment,
null,
virtualizer
.getVirtualItems()
.map((virtualItem) => virtualItemRenderer(virtualItem)),
),
);
};
const ComboBoxMenu = _react.forwardRef((props, forwardedRef) => {
let { className, children, style, portal = true, ...rest } = props;
let { id, enableVirtualization, popover } = (0, _index.useSafeContext)(
_helpers.ComboBoxStateContext,
);
let { menuRef } = (0, _index.useSafeContext)(_helpers.ComboBoxRefsContext);
let refs = (0, _index.useMergedRefs)(
popover.refs.setFloating,
forwardedRef,
menuRef,
);
return (
popover.open &&
_react.createElement(
_index.Portal,
{
portal: portal,
},
_react.createElement(
_List.List,
{
as: 'div',
className: (0, _classnames.default)('iui-menu', className),
id: `${id}-list`,
role: 'listbox',
ref: refs,
...popover.getFloatingProps({
style: enableVirtualization
? {
maxInlineSize: 0,
...style,
}
: style,
...rest,
}),
},
enableVirtualization
? _react.createElement(VirtualizedComboBoxMenu, null, children)
: children,
),
)
);
});
if ('development' === process.env.NODE_ENV)
ComboBoxMenu.displayName = 'ComboBoxMenu';