import {
html,
useMemo,
useLayoutEffect,
useRef
} from '../../ui';
import PopupMenuItem from './PopupMenuItem';
/**
* Component that renders a popup menu entry list.
*
* @param {Array} entries
* @param {Object} selectedEntry
* @param {function} setSelectedEntry
* @param {function} onAction
* @param {Object} resultsRef
*/
export default function PopupMenuList(props) {
const {
selectedEntry,
setSelectedEntry,
entries,
...restProps
} = props;
const resultsRef = useRef();
const groups = useMemo(() => groupEntries(entries), [ entries ]);
// scroll to selected result
useLayoutEffect(() => {
const containerEl = resultsRef.current;
if (!containerEl)
return;
const selectedEl = containerEl.querySelector('.selected');
if (selectedEl) {
scrollIntoView(selectedEl);
}
}, [ selectedEntry ]);
return html`
`;
}
// helpers
function groupEntries(entries) {
const groups = [];
const getGroup = group => groups.find(elem => group.id === elem.id);
const containsGroup = group => !!getGroup(group);
// legacy support for provider built for the old popUp menu
const formatGroup = group =>
typeof group === 'string' ? { id: group } : group;
entries.forEach(entry => {
// assume a default group when none is provided
const group = entry.group ? formatGroup(entry.group) : { id: 'default' };
if (!containsGroup(group)) {
groups.push({ ...group, entries: [ entry ] });
} else {
getGroup(group).entries.push(entry);
}
});
return groups;
}
// helpers ////////////////
function scrollIntoView(el) {
if (typeof el.scrollIntoViewIfNeeded === 'function') {
el.scrollIntoViewIfNeeded();
} else {
el.scrollIntoView({
scrollMode: 'if-needed',
block: 'nearest'
});
}
}