diff --git a/apps/client/src/widgets/note_icon.tsx b/apps/client/src/widgets/note_icon.tsx
index af20a69d0..76d8cbed0 100644
--- a/apps/client/src/widgets/note_icon.tsx
+++ b/apps/client/src/widgets/note_icon.tsx
@@ -3,9 +3,10 @@ import "./note_icon.css";
import { IconRegistry } from "@triliumnext/commons";
import { Dropdown as BootstrapDropdown } from "bootstrap";
import clsx from "clsx";
-import { t, use } from "i18next";
-import { RefObject } from "preact";
+import { t } from "i18next";
+import { CSSProperties, RefObject } from "preact";
import { useEffect, useMemo, useRef, useState } from "preact/hooks";
+import { CellComponentProps, Grid } from "react-window";
import FNote from "../entities/fnote";
import attributes from "../services/attributes";
@@ -132,13 +133,16 @@ function NoteIconList({ note, dropdownRef }: {
}}
>
{filteredIcons.length ? (
- (filteredIcons ?? []).map(({ id, terms, iconPack }) => (
-
- ))
+
) : (
{t("note_icon.no_results")}
)}
@@ -147,6 +151,22 @@ function NoteIconList({ note, dropdownRef }: {
);
}
+function IconItemCell({ rowIndex, columnIndex, style, filteredIcons }: CellComponentProps<{
+ filteredIcons: IconWithName[];
+}>): React.JSX.Element {
+ const iconIndex = rowIndex * 12 + columnIndex;
+ const iconData = filteredIcons[iconIndex];
+ const { id, terms, iconPack } = iconData;
+ return (
+
+ );
+}
+
function IconFilterContent({ filterByPrefix, setFilterByPrefix }: {
filterByPrefix: string | null;
setFilterByPrefix: (value: string | null) => void;
@@ -212,7 +232,7 @@ function useFilteredIcons(allIcons: IconWithName[] | undefined, search: string |
if (processedSearch || filterByPrefix !== null) {
icons = icons.filter((icon) => {
if (filterByPrefix) {
- if (!icon.id?.startsWith(`${filterByPrefix}-`)) {
+ if (!icon.id?.startsWith(`${filterByPrefix} `)) {
return false;
}
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index b11794447..3758f174c 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -292,6 +292,9 @@ importers:
react-i18next:
specifier: 16.5.0
version: 16.5.0(i18next@25.7.3(typescript@5.9.3))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3)
+ react-window:
+ specifier: 2.2.3
+ version: 2.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
reveal.js:
specifier: 5.2.1
version: 5.2.1
@@ -483,11 +486,7 @@ importers:
specifier: 11.3.3
version: 11.3.3
- apps/icon-pack-builder:
- devDependencies:
- '@phosphor-icons/web':
- specifier: 2.1.2
- version: 2.1.2
+ apps/icon-pack-builder: {}
apps/server:
dependencies:
@@ -4035,9 +4034,6 @@ packages:
resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==}
engines: {node: '>= 10.0.0'}
- '@phosphor-icons/web@2.1.2':
- resolution: {integrity: sha512-rPAR9o/bEcp4Cw4DEeZHXf+nlGCMNGkNDRizYHM47NLxz9vvEHp/Tt6FMK1NcWadzw/pFDPnRBGi/ofRya958A==}
-
'@pkgjs/parseargs@0.11.0':
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'}
@@ -12010,6 +12006,12 @@ packages:
peerDependencies:
react: ^18.0.0 || ^19.0.0
+ react-window@2.2.3:
+ resolution: {integrity: sha512-gTRqQYC8ojbiXyd9duYFiSn2TJw0ROXCgYjenOvNKITWzK0m0eCvkUsEUM08xvydkMh7ncp+LE0uS3DeNGZxnQ==}
+ peerDependencies:
+ react: ^18.0.0 || ^19.0.0
+ react-dom: ^18.0.0 || ^19.0.0
+
react@16.14.0:
resolution: {integrity: sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==}
engines: {node: '>=0.10.0'}
@@ -18460,8 +18462,6 @@ snapshots:
'@parcel/watcher-win32-x64': 2.5.1
optional: true
- '@phosphor-icons/web@2.1.2': {}
-
'@pkgjs/parseargs@0.11.0':
optional: true
@@ -28213,6 +28213,11 @@ snapshots:
prop-types: 15.8.1
react: 19.2.3
+ react-window@2.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3):
+ dependencies:
+ react: 19.2.3
+ react-dom: 19.2.3(react@19.2.3)
+
react@16.14.0:
dependencies:
loose-envify: 1.4.0