| 1 | "use client"; |
| 2 | |
| 3 | import { EmojiInlineIndexSearch, insertEmoji } from "@platejs/emoji"; |
| 4 | import { EmojiPlugin } from "@platejs/emoji/react"; |
| 5 | import { |
| 6 | PlateElement, |
| 7 | usePluginOption, |
| 8 | type PlateElementProps, |
| 9 | } from "platejs/react"; |
| 10 | import * as React from "react"; |
| 11 | |
| 12 | import { useDebounce } from "@/components/plate/hooks/use-debounce"; |
| 13 | import { |
| 14 | InlineCombobox, |
| 15 | InlineComboboxContent, |
| 16 | InlineComboboxEmpty, |
| 17 | InlineComboboxGroup, |
| 18 | InlineComboboxInput, |
| 19 | InlineComboboxItem, |
| 20 | } from "./inline-combobox"; |
| 21 | |
| 22 | export function EmojiInputElement(props: PlateElementProps) { |
| 23 | const { children, editor, element } = props; |
| 24 | const data = usePluginOption(EmojiPlugin, "data")!; |
| 25 | const [value, setValue] = React.useState(""); |
| 26 | const debouncedValue = useDebounce(value, 100); |
| 27 | const isPending = value !== debouncedValue; |
| 28 | |
| 29 | const filteredEmojis = React.useMemo(() => { |
| 30 | if (debouncedValue.trim().length === 0) return []; |
| 31 | |
| 32 | return EmojiInlineIndexSearch.getInstance(data) |
| 33 | .search(debouncedValue.replace(/:$/, "")) |
| 34 | .get(); |
| 35 | }, [data, debouncedValue]); |
| 36 | |
| 37 | return ( |
| 38 | <PlateElement as="span" data-slate-value={element.value} {...props}> |
| 39 | <InlineCombobox |
| 40 | value={value} |
| 41 | element={element} |
| 42 | filter={false} |
| 43 | setValue={setValue} |
| 44 | trigger=":" |
| 45 | hideWhenNoValue |
| 46 | > |
| 47 | <InlineComboboxInput /> |
| 48 | |
| 49 | <InlineComboboxContent> |
| 50 | {!isPending && <InlineComboboxEmpty>No results</InlineComboboxEmpty>} |
| 51 | |
| 52 | <InlineComboboxGroup> |
| 53 | {filteredEmojis.map((emoji) => ( |
| 54 | <InlineComboboxItem |
| 55 | key={emoji.id} |
| 56 | value={emoji.name} |
| 57 | onClick={() => insertEmoji(editor, emoji)} |
| 58 | > |
| 59 | {emoji.skins[0]?.native} {emoji.name} |
| 60 | </InlineComboboxItem> |
| 61 | ))} |
| 62 | </InlineComboboxGroup> |
| 63 | </InlineComboboxContent> |
| 64 | </InlineCombobox> |
| 65 | |
| 66 | {children} |
| 67 | </PlateElement> |
| 68 | ); |
| 69 | } |
| 70 |