feat(react/note_icon): render dropdown only when needed

This commit is contained in:
Elian Doran 2025-08-21 15:03:54 +03:00
parent 3fa290a257
commit ef018e22d6
No known key found for this signature in database
2 changed files with 16 additions and 17 deletions

View File

@ -26,10 +26,6 @@ export default class NoteIconWidget extends NoteContextAwareWidget {
} }
}); });
this.$iconCategory = this.$widget.find("select[name='icon-category']");
this.$iconCategory.on("change", () => this.renderDropdown());
this.$iconCategory.on("click", (e) => e.stopPropagation());
this.$iconSearch = this.$widget.find("input[name='icon-search']"); this.$iconSearch = this.$widget.find("input[name='icon-search']");
this.$iconSearch.on("input", () => this.renderDropdown()); this.$iconSearch.on("input", () => this.renderDropdown());
@ -43,8 +39,6 @@ export default class NoteIconWidget extends NoteContextAwareWidget {
} }
this.$iconSearch.val(""); this.$iconSearch.val("");
this.renderDropdown();
}); });
} }
@ -85,11 +79,8 @@ export default class NoteIconWidget extends NoteContextAwareWidget {
); );
} }
const categoryId = parseInt(String(this.$iconCategory.find("option:selected")?.val()));
const search = String(this.$iconSearch.val())?.trim()?.toLowerCase(); const search = String(this.$iconSearch.val())?.trim()?.toLowerCase();
const filteredIcons = icons.filter
if (iconToCount) { if (iconToCount) {
filteredIcons.sort((a, b) => { filteredIcons.sort((a, b) => {
const countA = iconToCount[a.className ?? ""] || 0; const countA = iconToCount[a.className ?? ""] || 0;

View File

@ -1,7 +1,7 @@
import { Dropdown as BootstrapDropdown } from "bootstrap"; import { Dropdown as BootstrapDropdown } from "bootstrap";
import { ComponentChildren } from "preact"; import { ComponentChildren } from "preact";
import { CSSProperties } from "preact/compat"; import { CSSProperties } from "preact/compat";
import { useEffect, useRef } from "preact/hooks"; import { useCallback, useEffect, useRef, useState } from "preact/hooks";
import { useUniqueName } from "./hooks"; import { useUniqueName } from "./hooks";
interface DropdownProps { interface DropdownProps {
@ -18,6 +18,8 @@ export default function Dropdown({ className, buttonClassName, isStatic, childre
const dropdownRef = useRef<HTMLDivElement | null>(null); const dropdownRef = useRef<HTMLDivElement | null>(null);
const triggerRef = useRef<HTMLButtonElement | null>(null); const triggerRef = useRef<HTMLButtonElement | null>(null);
const [ shown, setShown ] = useState(false);
useEffect(() => { useEffect(() => {
if (!triggerRef.current) return; if (!triggerRef.current) return;
@ -25,19 +27,25 @@ export default function Dropdown({ className, buttonClassName, isStatic, childre
return () => dropdown.dispose(); return () => dropdown.dispose();
}, []); // Add dependency array }, []); // Add dependency array
const onShown = useCallback(() => {
setShown(true);
}, [])
const onHidden = useCallback(() => {
setShown(false);
}, []);
useEffect(() => { useEffect(() => {
if (!dropdownRef.current) return; if (!dropdownRef.current) return;
const handleHide = () => {
// Remove console.log from production code
};
const $dropdown = $(dropdownRef.current); const $dropdown = $(dropdownRef.current);
$dropdown.on("hide.bs.dropdown", handleHide); $dropdown.on("show.bs.dropdown", onShown);
$dropdown.on("hide.bs.dropdown", onHidden);
// Add proper cleanup // Add proper cleanup
return () => { return () => {
$dropdown.off("hide.bs.dropdown", handleHide); $dropdown.off("show.bs.dropdown", onShown);
$dropdown.off("hide.bs.dropdown", onHidden);
}; };
}, []); // Add dependency array }, []); // Add dependency array
@ -62,7 +70,7 @@ export default function Dropdown({ className, buttonClassName, isStatic, childre
style={dropdownContainerStyle} style={dropdownContainerStyle}
aria-labelledby={ariaId} aria-labelledby={ariaId}
> >
{children} {shown && children}
</div> </div>
</div> </div>
) )