+ {categories.map((category) => {
+ const categoryItems = (category.items || []).filter((item) =>
+ inputItems.find((i) => i.type === item.type),
+ );
+ const itemColumns = Math.ceil(categoryItems.length / 2);
+
+ if (categoryItems.length === 0) {
+ return null;
+ }
+
+ return (
+
+ {category.label ? (
+
+ {category.label}
+
+ ) : null}
+ {categoryItems.map((item, index) => {
+ const itemLabel = getItemLabel(item.type, item);
+ const description = getItemDescription(item);
+ const itemIndex = inputItems.findIndex(
+ (i) => i.type === item.type,
+ );
+ const itemColumn = index + 1 <= itemColumns ? 1 : 2;
+ const hasIcon =
+ typeof item.icon !== 'undefined' && item.icon !== null;
+ let icon: JSX.Element | null | undefined = null;
+
+ if (hasIcon) {
+ icon =
+ typeof item.icon === 'string' ? (
+
+ ) : (
+ item.icon
+ );
+ }
+
+ const onMouseDown = (e) => {
+ e.stopPropagation();
+ onSelect({
+ selectedItem: item,
+ type: '__item_click__' as UseComboboxStateChangeTypes.ItemClick,
+ });
+ };
+
+ return (
+ // Side-step Downshift event handling and trigger selection on mouse down for clicks,
+ // so we preserve keyboard focus when used within rich text editors.
+ // eslint-disable-next-line jsx-a11y/no-static-element-interactions
+
+
+ {icon}
+ {/* Support for rich text options using text as an icon (for example "B" for bold). */}
+ {itemLabel && !hasIcon ? {itemLabel} : null}
+
+
+ {item.render
+ ? item.render({ option: item })
+ : description}
+
+
+ );
+ })}
+