import { Popover, PopoverContent } from '@radix-ui/react-popover' import { useCombobox } from 'downshift' import { CornerDownRight, Edit3Icon, ExpandIcon, XIcon } from 'lucide-react' import { unique } from 'radashi' import React, { useEffect, useMemo } from 'react' import { EhBaseSelectorRoot } from '../../../ui/components/commandInput/EhBaseSelector' import { mapDisplayedItems } from '../helpers' import { useResourceJumpContext } from '../ResourceJumpContext' import type { BaseAutoCompletableItem, BaseAutoCompleteItemRender, } from '~/modules/pluginCore/types' import type { AppAutoCompleteAmend, AutoCompleteContext, } from '../../../ui/components/commandInput/types' import { Button } from '~/components/ui/button' import { PopoverTrigger } from '~/components/ui/popover' import { cn } from '~/lib/utils' import { autocompleteFilter, autocompleteToString, isAutocompleteItem, } from '~/plugins/builtin/pageUrl/pageUrlAutoCompletePlugin' import { highlightMatches } from '~/util/highlightMatches' interface EhJumpResourceSelectorProps { className?: string } export function EhJumpResourceSelector({ className = '', }: EhJumpResourceSelectorProps) { const { jumpResources, currentResourceJump, setCurrentResourceJumpSlug } = useResourceJumpContext() const appFilter = ( needle: string, allItems: Array, ) => { return autocompleteFilter( allItems.filter((i) => isAutocompleteItem(i)), needle, ) } const [displayedItems, setDisplayedItems] = React.useState>(jumpResources) const { isOpen: comboIsOpen, getLabelProps, getMenuProps, getInputProps, getToggleButtonProps, highlightedIndex, getItemProps, selectItem, selectedItem: comboSelectedItem, inputValue: comboInputValue, setInputValue, } = useCombobox({ onInputValueChange({ inputValue: changedInputValue, isOpen: changedIsOpen, }) { if (changedIsOpen) { const matchedIds = unique(appFilter(changedInputValue, jumpResources)) setDisplayedItems(matchedIds) } }, onSelectedItemChange({ selectedItem: changedSelectedItem }) { setCurrentResourceJumpSlug(changedSelectedItem?.slug) }, // selectedItem, items: displayedItems, itemToString(item) { if (isAutocompleteItem(item)) { return autocompleteToString(item) } return 'n/a' }, }) useEffect(() => { if (currentResourceJump) { const f = jumpResources.find((e) => e.slug === currentResourceJump.slug) if (f) { selectItem(f) } } }, [currentResourceJump, jumpResources, selectItem]) const ctx = useMemo(() => { return { searchString: comboInputValue, } }, [comboInputValue]) return (
{ const userHasSelectedSomeText = e.currentTarget.selectionStart !== e.currentTarget.selectionEnd if (!userHasSelectedSomeText) { // setInputValue('asdads') e.currentTarget.select() } }, onKeyUp: (e) => { if (e.key !== 'Enter') { // console.log(e.target.value) // setLastUsersInputText(e.target.value) } }, })} /> {comboInputValue.length ? ( setInputValue('')} /> ) : ( )}
e.preventDefault()} forceMount >
{[...mapDisplayedItems(displayedItems)].map( ({ item, itemRenderData, isChild }, index) => { return ( ) }, )} {displayedItems.length === 0 && (
'{comboInputValue}' not found. Try a different search.
)}
{/* */}
) } export interface DisplayItemProps extends React.ComponentPropsWithoutRef<'div'>, AppAutoCompleteAmend { item: BaseAutoCompletableItem itemRenderData: BaseAutoCompleteItemRender isChild?: boolean selected: boolean highlighted: boolean getItemProps: (props: { item: BaseAutoCompletableItem }) => any ctx: AutoCompleteContext } export function DisplayItem({ item, itemRenderData, selected, isChild, highlighted, ctx, getItemProps, ...props }: DisplayItemProps) { const { displayName, parentDisplayName, isDefaultGroupItem } = itemRenderData const content = () => { let finalStr = [parentDisplayName, isChild ? '-' : false, displayName] .filter(Boolean) .join(' / ') if (isDefaultGroupItem && parentDisplayName) { finalStr = parentDisplayName } if (isChild) { return (
{highlightMatches(displayName, ctx.searchString)}
) } return highlightMatches(finalStr, ctx.searchString) } return (
{content()}
) }