| import { useState } from 'react'; | |
| import { Spinner } from '@librechat/client'; | |
| import { MenuItem } from '@headlessui/react'; | |
| import { BookmarkFilledIcon, BookmarkIcon } from '@radix-ui/react-icons'; | |
| import type { FC } from 'react'; | |
| type MenuItemProps = { | |
| tag: string | React.ReactNode; | |
| selected: boolean; | |
| count?: number; | |
| handleSubmit: (tag?: string) => void; | |
| icon?: React.ReactNode; | |
| }; | |
| const BookmarkItem: FC<MenuItemProps> = ({ tag, selected, handleSubmit, icon, ...rest }) => { | |
| const [isLoading, setIsLoading] = useState(false); | |
| const clickHandler = async () => { | |
| if (tag === 'New Bookmark') { | |
| handleSubmit(); | |
| return; | |
| } | |
| setIsLoading(true); | |
| handleSubmit(tag as string); | |
| setIsLoading(false); | |
| }; | |
| const breakWordStyle: React.CSSProperties = { | |
| wordBreak: 'break-word', | |
| overflowWrap: 'anywhere', | |
| }; | |
| const renderIcon = () => { | |
| if (icon != null) { | |
| return icon; | |
| } | |
| if (isLoading) { | |
| return <Spinner className="size-4" />; | |
| } | |
| if (selected) { | |
| return <BookmarkFilledIcon className="size-4" />; | |
| } | |
| return <BookmarkIcon className="size-4" />; | |
| }; | |
| return ( | |
| <MenuItem | |
| aria-label={tag as string} | |
| className="group flex w-full gap-2 rounded-lg p-2.5 text-sm text-text-primary transition-colors duration-200 focus:outline-none data-[focus]:bg-surface-hover data-[focus-visible]:ring-2 data-[focus-visible]:ring-primary" | |
| {...rest} | |
| as="button" | |
| onClick={clickHandler} | |
| > | |
| <div className="flex grow items-center justify-between gap-2"> | |
| <div className="flex items-center gap-2"> | |
| {renderIcon()} | |
| <div style={breakWordStyle}>{tag}</div> | |
| </div> | |
| </div> | |
| </MenuItem> | |
| ); | |
| }; | |
| export default BookmarkItem; | |