diff --git a/web/src/ui/emojipicker/EmojiGroup.tsx b/web/src/ui/emojipicker/EmojiGroup.tsx index f99bcde..b58d0d7 100644 --- a/web/src/ui/emojipicker/EmojiGroup.tsx +++ b/web/src/ui/emojipicker/EmojiGroup.tsx @@ -90,6 +90,7 @@ export const EmojiGroup = ({ ref={divRef} className="emoji-category" id={`emoji-category-${categoryID}`} + data-category-id={categoryID} style={{ containIntrinsicHeight: `${1.5 + Math.ceil(emojis.length / 8) * 2.5}rem` }} >

diff --git a/web/src/ui/emojipicker/EmojiPicker.css b/web/src/ui/emojipicker/EmojiPicker.css index fc74c95..9dbad56 100644 --- a/web/src/ui/emojipicker/EmojiPicker.css +++ b/web/src/ui/emojipicker/EmojiPicker.css @@ -90,6 +90,11 @@ div.emoji-picker { border-bottom-left-radius: 0; border-bottom-right-radius: 0; border-bottom: 2px solid transparent; + + &.visible { + border-bottom: 2px solid var(--primary-color); + } + &:hover { border-bottom: 2px solid var(--primary-color-dark); } diff --git a/web/src/ui/emojipicker/EmojiPicker.tsx b/web/src/ui/emojipicker/EmojiPicker.tsx index 16a8638..b3ef7a7 100644 --- a/web/src/ui/emojipicker/EmojiPicker.tsx +++ b/web/src/ui/emojipicker/EmojiPicker.tsx @@ -13,7 +13,7 @@ // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -import React, { CSSProperties, JSX, use, useCallback, useState } from "react" +import React, { CSSProperties, JSX, use, useCallback, useEffect, useRef, useState } from "react" import { getMediaURL } from "@/api/media.ts" import { RoomStateStore, useCustomEmojis } from "@/api/statestore" import { roomStateGUIDToString } from "@/api/types" @@ -64,6 +64,8 @@ const EmojiPicker = ({ style, selected, onSelect, room, allowFreeform, closeOnSe const client = use(ClientContext)! const [query, setQuery] = useState("") const [previewEmoji, setPreviewEmoji] = useState() + const emojiCategoryBarRef = useRef(null) + const emojiListRef = useRef(null) const watchedEmojiPackKeys = client.store.getEmojiPackKeys().map(roomStateGUIDToString) const customEmojiPacks = useCustomEmojis(client.store, room) const emojis = useFilteredEmojis(query, { @@ -89,8 +91,33 @@ const EmojiPicker = ({ style, selected, onSelect, room, allowFreeform, closeOnSe const categoryID = evt.currentTarget.getAttribute("data-category-id")! document.getElementById(`emoji-category-${categoryID}`)?.scrollIntoView() }, []) + useEffect(() => { + const cats = emojiCategoryBarRef.current + const lists = emojiListRef.current + if (!cats || !lists) { + return + } + const observer = new IntersectionObserver(entries => { + for (const entry of entries) { + const catID = entry.target.getAttribute("data-category-id") + const cat = catID && cats.querySelector(`.emoji-category-icon[data-category-id="${catID}"]`) + if (!cat) { + continue + } + if (entry.isIntersecting) { + cat.classList.add("visible") + } else { + cat.classList.remove("visible") + } + } + }) + for (const cat of lists.getElementsByClassName("emoji-category")) { + observer.observe(cat) + } + return () => observer.disconnect() + }, []) return
-
+