mirror of
https://github.com/zadam/trilium.git
synced 2025-10-20 07:08:55 +02:00
chore(react/collections): title highlighting in list title
This commit is contained in:
parent
f92948d65c
commit
68dff71512
@ -448,7 +448,7 @@ function sleep(time_ms: number) {
|
||||
});
|
||||
}
|
||||
|
||||
function escapeRegExp(str: string) {
|
||||
export function escapeRegExp(str: string) {
|
||||
return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
|
||||
}
|
||||
|
||||
|
@ -6,30 +6,31 @@ import { ListView, GridView } from "./legacy/ListView";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
|
||||
interface NoteListProps {
|
||||
note?: FNote | null;
|
||||
displayOnlyCollections?: boolean;
|
||||
highlightedTokens?: string[] | null;
|
||||
}
|
||||
|
||||
export default function NoteList({ }: NoteListProps) {
|
||||
const { note } = useNoteContext();
|
||||
export default function NoteList({ note: providedNote, highlightedTokens }: NoteListProps) {
|
||||
const { note: contextNote } = useNoteContext();
|
||||
const note = providedNote ?? contextNote;
|
||||
const viewType = useNoteViewType(note);
|
||||
const noteIds = useNoteIds(note, viewType);
|
||||
const isEnabled = (note && !!viewType);
|
||||
|
||||
// Refresh note Ids
|
||||
|
||||
return (
|
||||
<div className="note-list-widget">
|
||||
{isEnabled && (
|
||||
<div className="note-list-widget-content">
|
||||
{getComponentByViewType(note, noteIds, viewType)}
|
||||
{getComponentByViewType(note, noteIds, viewType, highlightedTokens)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function getComponentByViewType(note: FNote, noteIds: string[], viewType: ViewTypeOptions) {
|
||||
const props: ViewModeProps = { note, noteIds };
|
||||
function getComponentByViewType(note: FNote, noteIds: string[], viewType: ViewTypeOptions, highlightedTokens: string[] | null | undefined) {
|
||||
const props: ViewModeProps = { note, noteIds, highlightedTokens };
|
||||
|
||||
switch (viewType) {
|
||||
case "list":
|
||||
|
@ -11,4 +11,5 @@ export interface ViewModeProps {
|
||||
* We're using noteIds so that it's not necessary to load all notes at once when paging.
|
||||
*/
|
||||
noteIds: string[];
|
||||
highlightedTokens: string[] | null | undefined;
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import link from "../../../services/link";
|
||||
import { t } from "../../../services/i18n";
|
||||
import attribute_renderer from "../../../services/attribute_renderer";
|
||||
|
||||
export function ListView({ note, noteIds: unfilteredNoteIds }: ViewModeProps) {
|
||||
export function ListView({ note, noteIds: unfilteredNoteIds, highlightedTokens }: ViewModeProps) {
|
||||
const [ isExpanded ] = useNoteLabelBoolean(note, "expanded");
|
||||
const noteIds = useFilteredNoteIds(note, unfilteredNoteIds);
|
||||
const { pageNotes, ...pagination } = usePagination(note, noteIds);
|
||||
@ -24,7 +24,7 @@ export function ListView({ note, noteIds: unfilteredNoteIds }: ViewModeProps) {
|
||||
|
||||
<div class="note-list-container use-tn-links">
|
||||
{pageNotes?.map(childNote => (
|
||||
<ListNoteCard note={childNote} parentNote={note} expand={isExpanded} />
|
||||
<ListNoteCard note={childNote} parentNote={note} expand={isExpanded} highlightedTokens={highlightedTokens} />
|
||||
))}
|
||||
</div>
|
||||
|
||||
@ -34,7 +34,7 @@ export function ListView({ note, noteIds: unfilteredNoteIds }: ViewModeProps) {
|
||||
);
|
||||
}
|
||||
|
||||
export function GridView({ note, noteIds: unfilteredNoteIds }: ViewModeProps) {
|
||||
export function GridView({ note, noteIds: unfilteredNoteIds, highlightedTokens }: ViewModeProps) {
|
||||
const noteIds = useFilteredNoteIds(note, unfilteredNoteIds);
|
||||
const { pageNotes, ...pagination } = usePagination(note, noteIds);
|
||||
|
||||
@ -45,7 +45,7 @@ export function GridView({ note, noteIds: unfilteredNoteIds }: ViewModeProps) {
|
||||
|
||||
<div class="note-list-container use-tn-links">
|
||||
{pageNotes?.map(childNote => (
|
||||
<GridNoteCard note={childNote} parentNote={note} />
|
||||
<GridNoteCard note={childNote} parentNote={note} highlightedTokens={highlightedTokens} />
|
||||
))}
|
||||
</div>
|
||||
|
||||
@ -55,7 +55,7 @@ export function GridView({ note, noteIds: unfilteredNoteIds }: ViewModeProps) {
|
||||
);
|
||||
}
|
||||
|
||||
function ListNoteCard({ note, parentNote, expand }: { note: FNote, parentNote: FNote, expand?: boolean }) {
|
||||
function ListNoteCard({ note, parentNote, expand, highlightedTokens }: { note: FNote, parentNote: FNote, expand?: boolean, highlightedTokens: string[] | null | undefined }) {
|
||||
const [ isExpanded, setExpanded ] = useState(expand);
|
||||
const notePath = getNotePath(parentNote, note);
|
||||
|
||||
@ -71,7 +71,7 @@ function ListNoteCard({ note, parentNote, expand }: { note: FNote, parentNote: F
|
||||
/>
|
||||
|
||||
<Icon className="note-icon" icon={note.getIcon()} />
|
||||
<NoteLink className="note-book-title" notePath={notePath} noPreview showNotePath={note.type === "search"} />
|
||||
<NoteLink className="note-book-title" notePath={notePath} noPreview showNotePath={note.type === "search"} highlightedTokens={highlightedTokens} />
|
||||
<NoteAttributes note={note} />
|
||||
|
||||
{isExpanded && <>
|
||||
@ -83,7 +83,8 @@ function ListNoteCard({ note, parentNote, expand }: { note: FNote, parentNote: F
|
||||
)
|
||||
}
|
||||
|
||||
function GridNoteCard({ note, parentNote }: { note: FNote, parentNote: FNote }) {
|
||||
function GridNoteCard({ note, parentNote, highlightedTokens }: { note: FNote, parentNote: FNote, highlightedTokens: string[] | null | undefined }) {
|
||||
const titleRef = useRef<HTMLSpanElement>(null);
|
||||
const [ noteTitle, setNoteTitle ] = useState<string>();
|
||||
const notePath = getNotePath(parentNote, note);
|
||||
|
||||
@ -100,7 +101,7 @@ function GridNoteCard({ note, parentNote }: { note: FNote, parentNote: FNote })
|
||||
>
|
||||
<h5 className="note-book-header">
|
||||
<Icon className="note-icon" icon={note.getIcon()} />
|
||||
<span className="note-book-title">{noteTitle}</span>
|
||||
<span ref={titleRef} className="note-book-title">{noteTitle}</span>
|
||||
<NoteAttributes note={note} />
|
||||
</h5>
|
||||
<NoteContent note={note} trim />
|
||||
@ -149,7 +150,7 @@ function NoteChildren({ note, parentNote }: { note: FNote, parentNote: FNote })
|
||||
});
|
||||
}, [ note ]);
|
||||
|
||||
return childNotes?.map(childNote => <ListNoteCard note={childNote} parentNote={parentNote} />)
|
||||
return childNotes?.map(childNote => <ListNoteCard note={childNote} parentNote={parentNote} highlightedTokens={null} />)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
import { useEffect, useRef, useState } from "preact/hooks";
|
||||
import link from "../../services/link";
|
||||
import RawHtml from "./RawHtml";
|
||||
import { useSearchHighlighlighting } from "./hooks";
|
||||
|
||||
interface NoteLinkOpts {
|
||||
className?: string;
|
||||
@ -10,11 +11,14 @@ interface NoteLinkOpts {
|
||||
style?: Record<string, string | number>;
|
||||
noPreview?: boolean;
|
||||
noTnLink?: boolean;
|
||||
highlightedTokens?: string[] | null | undefined;
|
||||
}
|
||||
|
||||
export default function NoteLink({ className, notePath, showNotePath, showNoteIcon, style, noPreview, noTnLink }: NoteLinkOpts) {
|
||||
export default function NoteLink({ className, notePath, showNotePath, showNoteIcon, style, noPreview, noTnLink, highlightedTokens }: NoteLinkOpts) {
|
||||
const stringifiedNotePath = Array.isArray(notePath) ? notePath.join("/") : notePath;
|
||||
const [ jqueryEl, setJqueryEl ] = useState<JQuery<HTMLElement>>();
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
useSearchHighlighlighting(containerRef, highlightedTokens);
|
||||
|
||||
useEffect(() => {
|
||||
link.createLink(stringifiedNotePath, { showNotePath, showNoteIcon })
|
||||
@ -38,6 +42,6 @@ export default function NoteLink({ className, notePath, showNotePath, showNoteIc
|
||||
$linkEl?.addClass(className);
|
||||
}
|
||||
|
||||
return <RawHtml html={jqueryEl} />
|
||||
|
||||
}
|
||||
return <RawHtml containerRef={containerRef} html={jqueryEl} />
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { CSSProperties } from "preact/compat";
|
||||
import type { CSSProperties, RefObject } from "preact/compat";
|
||||
|
||||
type HTMLElementLike = string | HTMLElement | JQuery<HTMLElement>;
|
||||
|
||||
@ -9,12 +9,12 @@ interface RawHtmlProps {
|
||||
onClick?: (e: MouseEvent) => void;
|
||||
}
|
||||
|
||||
export default function RawHtml(props: RawHtmlProps) {
|
||||
return <span {...getProps(props)} />;
|
||||
export default function RawHtml({containerRef, ...props}: RawHtmlProps & { containerRef?: RefObject<HTMLSpanElement>}) {
|
||||
return <span ref={containerRef} {...getProps(props)} />;
|
||||
}
|
||||
|
||||
export function RawHtmlBlock(props: RawHtmlProps) {
|
||||
return <div {...getProps(props)} />
|
||||
export function RawHtmlBlock({containerRef, ...props}: RawHtmlProps & { containerRef?: RefObject<HTMLDivElement>}) {
|
||||
return <div ref={containerRef} {...getProps(props)} />
|
||||
}
|
||||
|
||||
function getProps({ className, html, style, onClick }: RawHtmlProps) {
|
||||
@ -38,4 +38,4 @@ export function getHtml(html: string | HTMLElement | JQuery<HTMLElement>) {
|
||||
return {
|
||||
__html: html as string
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import { ParentComponent } from "./react_utils";
|
||||
import SpacedUpdate from "../../services/spaced_update";
|
||||
import { KeyboardActionNames, OptionNames } from "@triliumnext/commons";
|
||||
import options, { type OptionValue } from "../../services/options";
|
||||
import utils, { reloadFrontendApp } from "../../services/utils";
|
||||
import utils, { escapeRegExp, reloadFrontendApp } from "../../services/utils";
|
||||
import NoteContext from "../../components/note_context";
|
||||
import BasicWidget, { ReactWrappedWidget } from "../basic_widget";
|
||||
import FNote from "../../entities/fnote";
|
||||
@ -15,6 +15,7 @@ import { RefObject, VNode } from "preact";
|
||||
import { Tooltip } from "bootstrap";
|
||||
import { CSSProperties } from "preact/compat";
|
||||
import keyboard_actions from "../../services/keyboard_actions";
|
||||
import Mark from "mark.js";
|
||||
|
||||
export function useTriliumEvent<T extends EventNames>(eventName: T, handler: (data: EventData<T>) => void) {
|
||||
const parentComponent = useContext(ParentComponent);
|
||||
@ -27,7 +28,7 @@ export function useTriliumEvent<T extends EventNames>(eventName: T, handler: (da
|
||||
|
||||
export function useTriliumEvents<T extends EventNames>(eventNames: T[], handler: (data: EventData<T>, eventName: T) => void) {
|
||||
const parentComponent = useContext(ParentComponent);
|
||||
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const handlers: ({ eventName: T, callback: (data: EventData<T>) => void })[] = [];
|
||||
for (const eventName of eventNames) {
|
||||
@ -35,11 +36,11 @@ export function useTriliumEvents<T extends EventNames>(eventNames: T[], handler:
|
||||
handler(data, eventName);
|
||||
}})
|
||||
}
|
||||
|
||||
|
||||
for (const { eventName, callback } of handlers) {
|
||||
parentComponent?.registerHandler(eventName, callback);
|
||||
}
|
||||
|
||||
|
||||
return (() => {
|
||||
for (const { eventName, callback } of handlers) {
|
||||
parentComponent?.removeHandler(eventName, callback);
|
||||
@ -76,10 +77,10 @@ export function useSpacedUpdate(callback: () => void | Promise<void>, interval =
|
||||
|
||||
/**
|
||||
* Allows a React component to read and write a Trilium option, while also watching for external changes.
|
||||
*
|
||||
*
|
||||
* Conceptually, `useTriliumOption` works just like `useState`, but the value is also automatically updated if
|
||||
* the option is changed somewhere else in the client.
|
||||
*
|
||||
*
|
||||
* @param name the name of the option to listen for.
|
||||
* @param needsRefresh whether to reload the frontend whenever the value is changed.
|
||||
* @returns an array where the first value is the current option value and the second value is the setter.
|
||||
@ -115,7 +116,7 @@ export function useTriliumOption(name: OptionNames, needsRefresh?: boolean): [st
|
||||
|
||||
/**
|
||||
* Similar to {@link useTriliumOption}, but the value is converted to and from a boolean instead of a string.
|
||||
*
|
||||
*
|
||||
* @param name the name of the option to listen for.
|
||||
* @param needsRefresh whether to reload the frontend whenever the value is changed.
|
||||
* @returns an array where the first value is the current option value and the second value is the setter.
|
||||
@ -131,7 +132,7 @@ export function useTriliumOptionBool(name: OptionNames, needsRefresh?: boolean):
|
||||
|
||||
/**
|
||||
* Similar to {@link useTriliumOption}, but the value is converted to and from a int instead of a string.
|
||||
*
|
||||
*
|
||||
* @param name the name of the option to listen for.
|
||||
* @param needsRefresh whether to reload the frontend whenever the value is changed.
|
||||
* @returns an array where the first value is the current option value and the second value is the setter.
|
||||
@ -147,7 +148,7 @@ export function useTriliumOptionInt(name: OptionNames): [number, (newValue: numb
|
||||
|
||||
/**
|
||||
* Similar to {@link useTriliumOption}, but the object value is parsed to and from a JSON instead of a string.
|
||||
*
|
||||
*
|
||||
* @param name the name of the option to listen for.
|
||||
* @returns an array where the first value is the current option value and the second value is the setter.
|
||||
*/
|
||||
@ -161,8 +162,8 @@ export function useTriliumOptionJson<T>(name: OptionNames): [ T, (newValue: T) =
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to {@link useTriliumOption}, but operates with multiple options at once.
|
||||
*
|
||||
* Similar to {@link useTriliumOption}, but operates with multiple options at once.
|
||||
*
|
||||
* @param names the name of the option to listen for.
|
||||
* @returns an array where the first value is a map where the keys are the option names and the values, and the second value is the setter which takes in the same type of map and saves them all at once.
|
||||
*/
|
||||
@ -182,10 +183,10 @@ export function useTriliumOptions<T extends OptionNames>(...names: T[]) {
|
||||
|
||||
/**
|
||||
* Generates a unique name via a random alphanumeric string of a fixed length.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Generally used to assign names to inputs that are unique, especially useful for widgets inside tabs.
|
||||
*
|
||||
*
|
||||
* @param prefix a prefix to add to the unique name.
|
||||
* @returns a name with the given prefix and a random alpanumeric string appended to it.
|
||||
*/
|
||||
@ -196,7 +197,7 @@ export function useUniqueName(prefix?: string) {
|
||||
export function useNoteContext() {
|
||||
const [ noteContext, setNoteContext ] = useState<NoteContext>();
|
||||
const [ notePath, setNotePath ] = useState<string | null | undefined>();
|
||||
const [ note, setNote ] = useState<FNote | null | undefined>();
|
||||
const [ note, setNote ] = useState<FNote | null | undefined>();
|
||||
const [ refreshCounter, setRefreshCounter ] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
@ -205,7 +206,7 @@ export function useNoteContext() {
|
||||
|
||||
useTriliumEvents([ "setNoteContext", "activeContextChanged", "noteSwitchedAndActivated", "noteSwitched" ], ({ noteContext }) => {
|
||||
setNoteContext(noteContext);
|
||||
setNotePath(noteContext.notePath);
|
||||
setNotePath(noteContext.notePath);
|
||||
});
|
||||
useTriliumEvent("frocaReloaded", () => {
|
||||
setNote(noteContext?.note);
|
||||
@ -235,7 +236,7 @@ export function useNoteContext() {
|
||||
|
||||
/**
|
||||
* Allows a React component to listen to obtain a property of a {@link FNote} while also automatically watching for changes, either via the user changing to a different note or the property being changed externally.
|
||||
*
|
||||
*
|
||||
* @param note the {@link FNote} whose property to obtain.
|
||||
* @param property a property of a {@link FNote} to obtain the value from (e.g. `title`, `isProtected`).
|
||||
* @param componentId optionally, constricts the refresh of the value if an update occurs externally via the component ID of a legacy widget. This can be used to avoid external data replacing fresher, user-inputted data.
|
||||
@ -287,7 +288,7 @@ export function useNoteRelation(note: FNote | undefined | null, relationName: st
|
||||
|
||||
/**
|
||||
* Allows a React component to read or write a note's label while also reacting to changes in value.
|
||||
*
|
||||
*
|
||||
* @param note the note whose label to read/write.
|
||||
* @param labelName the name of the label to read/write.
|
||||
* @returns an array where the first element is the getter and the second element is the setter. The setter has a special behaviour for convenience: if the value is undefined, the label is created without a value (e.g. a tag), if the value is null then the label is removed.
|
||||
@ -352,9 +353,9 @@ export function useNoteLabelBoolean(note: FNote | undefined | null, labelName: s
|
||||
|
||||
export function useNoteBlob(note: FNote | null | undefined): [ FBlob | null | undefined ] {
|
||||
const [ blob, setBlob ] = useState<FBlob | null>();
|
||||
|
||||
|
||||
function refresh() {
|
||||
note?.getBlob().then(setBlob);
|
||||
note?.getBlob().then(setBlob);
|
||||
}
|
||||
|
||||
useEffect(refresh, [ note?.noteId ]);
|
||||
@ -388,7 +389,7 @@ export function useLegacyWidget<T extends BasicWidget>(widgetFactory: () => T, {
|
||||
if (noteContext && widget instanceof NoteContextAwareWidget) {
|
||||
widget.setNoteContextEvent({ noteContext });
|
||||
}
|
||||
|
||||
|
||||
const renderedWidget = widget.render();
|
||||
return [ widget, renderedWidget ];
|
||||
}, []);
|
||||
@ -415,7 +416,7 @@ export function useLegacyWidget<T extends BasicWidget>(widgetFactory: () => T, {
|
||||
|
||||
/**
|
||||
* Attaches a {@link ResizeObserver} to the given ref and reads the bounding client rect whenever it changes.
|
||||
*
|
||||
*
|
||||
* @param ref a ref to a {@link HTMLElement} to determine the size and observe the changes in size.
|
||||
* @returns the size of the element, reacting to changes.
|
||||
*/
|
||||
@ -445,7 +446,7 @@ export function useElementSize(ref: RefObject<HTMLElement>) {
|
||||
|
||||
/**
|
||||
* Obtains the inner width and height of the window, as well as reacts to changes in size.
|
||||
*
|
||||
*
|
||||
* @returns the width and height of the window.
|
||||
*/
|
||||
export function useWindowSize() {
|
||||
@ -453,7 +454,7 @@ export function useWindowSize() {
|
||||
windowWidth: window.innerWidth,
|
||||
windowHeight: window.innerHeight
|
||||
});
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
function onResize() {
|
||||
setSize({
|
||||
@ -499,7 +500,7 @@ export function useTooltip(elRef: RefObject<HTMLElement>, config: Partial<Toolti
|
||||
|
||||
/**
|
||||
* Similar to {@link useTooltip}, but doesn't expose methods to imperatively hide or show the tooltip.
|
||||
*
|
||||
*
|
||||
* @param elRef the element to bind the tooltip to.
|
||||
* @param config optionally, the tooltip configuration.
|
||||
*/
|
||||
@ -547,4 +548,28 @@ export function useSyncedRef<T>(externalRef?: RefObject<T>, initialValue: T | nu
|
||||
}, [ ref, externalRef ]);
|
||||
|
||||
return ref;
|
||||
}
|
||||
}
|
||||
|
||||
export function useSearchHighlighlighting(ref: RefObject<HTMLElement>, highlightedTokens: string[] | null | undefined) {
|
||||
const mark = useRef<Mark>();
|
||||
const highlightRegex = useMemo(() => {
|
||||
if (!highlightedTokens?.length) return null;
|
||||
const regex = highlightedTokens.map((token) => escapeRegExp(token)).join("|");
|
||||
return new RegExp(regex, "gi")
|
||||
}, [ highlightedTokens ]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!ref.current || !highlightRegex) return;
|
||||
|
||||
if (!mark.current) {
|
||||
mark.current = new Mark(ref.current);
|
||||
}
|
||||
|
||||
mark.current.markRegExp(highlightRegex, {
|
||||
element: "span",
|
||||
className: "ck-find-result"
|
||||
});
|
||||
|
||||
return () => mark.current?.unmark();
|
||||
});
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
import { useEffect, useRef, useState } from "preact/hooks";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
import { t } from "../services/i18n";
|
||||
import Alert from "./react/Alert";
|
||||
import { useNoteContext, useNoteProperty, useTriliumEvent } from "./react/hooks";
|
||||
import { useNoteContext, useTriliumEvent } from "./react/hooks";
|
||||
import "./search_result.css";
|
||||
import NoteList from "./collections/NoteList";
|
||||
// import NoteListRenderer from "../services/note_list_renderer";
|
||||
|
||||
enum SearchResultState {
|
||||
enum SearchResultState {
|
||||
NO_RESULTS,
|
||||
NOT_EXECUTED,
|
||||
GOT_RESULTS
|
||||
@ -14,27 +15,18 @@ enum SearchResultState {
|
||||
export default function SearchResult() {
|
||||
const { note, ntxId } = useNoteContext();
|
||||
const [ state, setState ] = useState<SearchResultState>();
|
||||
const searchContainerRef = useRef<HTMLDivElement>(null);
|
||||
const [ highlightedTokens, setHighlightedTokens ] = useState<string[]>();
|
||||
|
||||
function refresh() {
|
||||
searchContainerRef.current?.replaceChildren();
|
||||
|
||||
if (note?.type !== "search") {
|
||||
setState(undefined);
|
||||
} else if (!note?.searchResultsLoaded) {
|
||||
setState(SearchResultState.NOT_EXECUTED);
|
||||
} else if (note.getChildNoteIds().length === 0) {
|
||||
setState(SearchResultState.NO_RESULTS);
|
||||
} else if (searchContainerRef.current) {
|
||||
} else {
|
||||
setState(SearchResultState.GOT_RESULTS);
|
||||
|
||||
// TODO: Fix me.
|
||||
// const noteListRenderer = new NoteListRenderer({
|
||||
// $parent: $(searchContainerRef.current),
|
||||
// parentNote: note,
|
||||
// showNotePath: true
|
||||
// });
|
||||
// noteListRenderer.renderList();
|
||||
setHighlightedTokens(note.highlightedTokens);
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,7 +52,9 @@ export default function SearchResult() {
|
||||
<Alert type="info" className="search-no-results">{t("search_result.no_notes_found")}</Alert>
|
||||
)}
|
||||
|
||||
<div ref={searchContainerRef} className="search-result-widget-content" />
|
||||
{state === SearchResultState.GOT_RESULTS && (
|
||||
<NoteList note={note} highlightedTokens={highlightedTokens} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user