import React from 'react'; import { MenuToggle, MenuSearch, MenuSearchInput, Tooltip, Divider, SearchInput, Dropdown, DropdownGroup, DropdownList, DropdownItem } from '@patternfly/react-core'; import ThIcon from '@patternfly/react-icons/dist/js/icons/th-icon'; import pfIcon from '@patternfly/react-core/src/demos/Card/pf-logo-small.svg'; const MockLink: React.FunctionComponent = ({ to, ...props }: any) => ; export const ApplicationLauncherDemo: React.FunctionComponent = () => { const [isOpen, setIsOpen] = React.useState(false); const [refFullOptions, setRefFullOptions] = React.useState(); const [favorites, setFavorites] = React.useState([]); const [filteredIds, setFilteredIds] = React.useState(['*']); const menuRef = React.useRef(null); const onToggleClick = () => { setTimeout(() => { if (menuRef.current) { const firstElement = menuRef.current.querySelector( 'li > button:not(:disabled), li > a:not(:disabled), input:not(:disabled)' ); firstElement && (firstElement as HTMLElement).focus(); setRefFullOptions(Array.from(menuRef.current.querySelectorAll('li:not(li[role=separator])>*:first-child'))); } }, 0); setIsOpen(!isOpen); }; const menuItems = [ Application 1 ev.preventDefault()} > Application 2 , , } > Custom component (such as @reach/router Link) } component={(props) => } > Custom component with icon , , Launch Application 3} position="right"> Application 3 with tooltip Unavailable Application ]; const createFavorites = (favIds: string[]) => { const favorites: unknown[] = []; menuItems.forEach((item) => { if (item.type === DropdownList) { item.props.children.filter((child) => { if (favIds.includes(child.props.value)) { favorites.push(child); } }); } else if (item.type === DropdownGroup) { item.props.children.props.children.filter((child) => { if (favIds.includes(child.props.value)) { favorites.push(child); } }); } else { if (favIds.includes(item.props.value)) { favorites.push(item); } } }); return favorites; }; const filterItems = (items: any[], filteredIds: string[]) => { if (filteredIds.length === 1 && filteredIds[0] === '*') { return items; } let keepDivider = false; const filteredCopy = items .map((group) => { if (group.type === DropdownGroup) { const filteredGroup = React.cloneElement(group, { children: React.cloneElement(group.props.children, { children: group.props.children.props.children.filter((child) => { if (filteredIds.includes(child.props.value)) { return child; } }) }) }); const filteredList = filteredGroup.props.children; if (filteredList.props.children.length > 0) { keepDivider = true; return filteredGroup; } else { keepDivider = false; } } else if (group.type === DropdownList) { const filteredGroup = React.cloneElement(group, { children: group.props.children.filter((child) => { if (filteredIds.includes(child.props.value)) { return child; } }) }); if (filteredGroup.props.children.length > 0) { keepDivider = true; return filteredGroup; } else { keepDivider = false; } } else { if ((keepDivider && group.type === Divider) || filteredIds.includes(group.props.value)) { return group; } } }) .filter((newGroup) => newGroup); if (filteredCopy.length > 0) { const lastGroup = filteredCopy.pop(); if (lastGroup.type !== Divider) { filteredCopy.push(lastGroup); } } return filteredCopy; }; const onTextChange = (textValue: string) => { if (textValue === '') { setFilteredIds(['*']); return; } const filteredIds = refFullOptions ?.filter((item) => (item as HTMLElement).innerText.toLowerCase().includes(textValue.toString().toLowerCase())) .map((item) => item.id) || []; setFilteredIds(filteredIds); }; const onFavorite = (event: any, value: string, actionId: string) => { event.stopPropagation(); if (actionId === 'fav') { const isFavorite = favorites.includes(value); if (isFavorite) { setFavorites(favorites.filter((fav) => fav !== value)); } else { setFavorites([...favorites, value]); } } }; const filteredFavorites = filterItems(createFavorites(favorites), filteredIds); const filteredItems = filterItems(menuItems, filteredIds); if (filteredItems.length === 0) { filteredItems.push(No results found); } return ( // eslint-disable-next-line no-console setIsOpen(isOpen)} onOpenChangeKeys={['Escape']} toggle={(toggleRef) => ( )} ref={menuRef} onActionClick={onFavorite} // eslint-disable-next-line no-console onSelect={(_ev, value) => console.log('selected', value)} > onTextChange(value)} /> {filteredFavorites.length > 0 && ( {filteredFavorites} )} {filteredItems} ); };