@itwin/itwinui-react
Version:
A react component library for iTwinUI
195 lines (194 loc) • 6.25 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', {
value: true,
});
Object.defineProperty(exports, 'ComboBoxInput', {
enumerable: true,
get: function () {
return ComboBoxInput;
},
});
const _interop_require_wildcard = require('@swc/helpers/_/_interop_require_wildcard');
const _react = /*#__PURE__*/ _interop_require_wildcard._(require('react'));
const _Input = require('../Input/Input.js');
const _index = require('../../utils/index.js');
const _ComboBoxMultipleContainer = require('./ComboBoxMultipleContainer.js');
const _helpers = require('./helpers.js');
const ComboBoxInput = _react.forwardRef((props, forwardedRef) => {
let { selectTags, size, style, ...rest } = props;
let {
isOpen,
id,
focusedIndex,
setFocusedIndex,
enableVirtualization,
multiple,
onClickHandler,
popover,
show,
hide,
} = (0, _index.useSafeContext)(_helpers.ComboBoxStateContext);
let { inputRef, menuRef, optionsExtraInfo } = (0, _index.useSafeContext)(
_helpers.ComboBoxRefsContext,
);
let refs = (0, _index.useMergedRefs)(
inputRef,
popover.refs.setReference,
forwardedRef,
);
let focusedIndexRef = (0, _index.useLatestRef)(focusedIndex ?? -1);
let getIdFromIndex = (index) =>
menuRef.current?.querySelector(`[data-iui-index="${index}"]`)?.id ?? '';
let handleKeyDown = _react.useCallback(
(event) => {
let length = Object.keys(optionsExtraInfo).length ?? 0;
if (event.altKey) return;
switch (event.key) {
case 'ArrowDown': {
event.preventDefault();
if (!isOpen) return show();
if (0 === length) return;
if (-1 === focusedIndexRef.current) {
let currentElement =
menuRef.current?.querySelector('[data-iui-index]');
return setFocusedIndex(
Number(currentElement?.getAttribute('data-iui-index') ?? 0),
);
}
if (
enableVirtualization &&
!menuRef.current?.querySelector(
`[data-iui-index="${focusedIndexRef.current}"]`,
)?.nextElementSibling
)
return;
let nextIndex = focusedIndexRef.current;
do {
let currentElement = menuRef.current?.querySelector(
`[data-iui-index="${nextIndex}"]`,
);
let nextElement =
currentElement?.nextElementSibling ??
menuRef.current?.querySelector('[data-iui-index]');
nextIndex = Number(nextElement?.getAttribute('data-iui-index'));
if (nextElement) return setFocusedIndex(nextIndex);
} while (nextIndex !== focusedIndexRef.current);
break;
}
case 'ArrowUp': {
event.preventDefault();
if (!isOpen) return show();
if (0 === length) return;
if (
enableVirtualization &&
!menuRef.current?.querySelector(
`[data-iui-index="${focusedIndexRef.current}"]`,
)?.previousElementSibling
)
return;
if (-1 === focusedIndexRef.current)
return setFocusedIndex(
Object.values(optionsExtraInfo)?.[length - 1].__originalIndex ??
-1,
);
let prevIndex = focusedIndexRef.current;
do {
let currentElement = menuRef.current?.querySelector(
`[data-iui-index="${prevIndex}"]`,
);
let prevElement =
currentElement?.previousElementSibling ??
menuRef.current?.querySelector('[data-iui-index]:last-of-type');
prevIndex = Number(prevElement?.getAttribute('data-iui-index'));
if (prevElement) return setFocusedIndex(prevIndex);
} while (prevIndex !== focusedIndexRef.current);
break;
}
case 'Enter':
event.preventDefault();
if (isOpen) {
if (focusedIndexRef.current > -1)
onClickHandler?.(focusedIndexRef.current);
} else show();
break;
case 'Escape':
event.preventDefault();
hide();
break;
case 'Tab':
hide();
break;
}
},
[
setFocusedIndex,
enableVirtualization,
focusedIndexRef,
isOpen,
menuRef,
onClickHandler,
optionsExtraInfo,
show,
hide,
],
);
let wasOpenBeforeClick = _react.useRef(false);
let handlePointerDown = _react.useCallback(() => {
wasOpenBeforeClick.current = isOpen;
}, [isOpen]);
let handleClick = _react.useCallback(() => {
if (wasOpenBeforeClick.current) hide();
else show();
wasOpenBeforeClick.current = false;
}, [hide, show]);
let [tagContainerWidthRef, tagContainerWidth] = (0,
_index.useContainerWidth)();
return _react.createElement(
_react.Fragment,
null,
_react.createElement(_Input.Input, {
ref: refs,
'aria-expanded': isOpen,
'aria-activedescendant':
isOpen && void 0 != focusedIndex && focusedIndex > -1
? getIdFromIndex(focusedIndex)
: void 0,
role: 'combobox',
'aria-controls': isOpen ? `${id}-list` : void 0,
'aria-autocomplete': 'list',
spellCheck: false,
autoCapitalize: 'none',
autoCorrect: 'off',
style: {
...(multiple && {
paddingInlineStart: tagContainerWidth + 18,
}),
...style,
},
size: size,
...popover.getReferenceProps({
...rest,
onPointerDown: (0, _index.mergeEventHandlers)(
props.onPointerDown,
handlePointerDown,
),
onClick: (0, _index.mergeEventHandlers)(props.onClick, handleClick),
onKeyDown: (0, _index.mergeEventHandlers)(
props.onKeyDown,
handleKeyDown,
),
}),
}),
multiple && selectTags
? _react.createElement(
_ComboBoxMultipleContainer.ComboBoxMultipleContainer,
{
ref: tagContainerWidthRef,
selectedItems: selectTags,
},
)
: null,
);
});
if ('development' === process.env.NODE_ENV)
ComboBoxInput.displayName = 'ComboBoxInput';