mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-06-06 20:15:17 +02:00
refactor: improve InlineCombobox context handling and optimize search functionality
This commit is contained in:
parent
648b00da64
commit
0edfd116af
2 changed files with 24 additions and 11 deletions
|
|
@ -28,6 +28,18 @@ import { useComposedRef, useEditorRef } from 'platejs/react';
|
||||||
|
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
|
function useRequiredComboboxContext() {
|
||||||
|
const context = useComboboxContext();
|
||||||
|
|
||||||
|
if (!context) {
|
||||||
|
throw new Error(
|
||||||
|
'InlineCombobox compound components must be rendered within InlineCombobox'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
type FilterFn = (
|
type FilterFn = (
|
||||||
item: { value: string; group?: string; keywords?: string[]; label?: string },
|
item: { value: string; group?: string; keywords?: string[]; label?: string },
|
||||||
search: string
|
search: string
|
||||||
|
|
@ -56,7 +68,7 @@ const defaultFilter: FilterFn = (
|
||||||
);
|
);
|
||||||
|
|
||||||
return Array.from(uniqueTerms).some((keyword) =>
|
return Array.from(uniqueTerms).some((keyword) =>
|
||||||
filterWords(keyword!, search)
|
filterWords(keyword as string, search)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -91,7 +103,7 @@ const InlineCombobox = ({
|
||||||
|
|
||||||
// Check if current user is the creator of this element (for Yjs collaboration)
|
// Check if current user is the creator of this element (for Yjs collaboration)
|
||||||
const isCreator = React.useMemo(() => {
|
const isCreator = React.useMemo(() => {
|
||||||
const elementUserId = (element as any).userId;
|
const elementUserId = (element as Record<string, unknown>).userId;
|
||||||
const currentUserId = editor.meta.userId;
|
const currentUserId = editor.meta.userId;
|
||||||
|
|
||||||
// If no userId (backwards compatibility or non-Yjs), allow
|
// If no userId (backwards compatibility or non-Yjs), allow
|
||||||
|
|
@ -170,10 +182,8 @@ const InlineCombobox = ({
|
||||||
trigger,
|
trigger,
|
||||||
showTrigger,
|
showTrigger,
|
||||||
filter,
|
filter,
|
||||||
inputRef,
|
|
||||||
inputProps,
|
inputProps,
|
||||||
removeInput,
|
removeInput,
|
||||||
setHasEmpty,
|
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -189,6 +199,8 @@ const InlineCombobox = ({
|
||||||
* item.
|
* item.
|
||||||
*/
|
*/
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
|
if (items.length === 0) return;
|
||||||
|
|
||||||
if (!store.getState().activeId) {
|
if (!store.getState().activeId) {
|
||||||
store.setActiveId(store.first());
|
store.setActiveId(store.first());
|
||||||
}
|
}
|
||||||
|
|
@ -225,7 +237,7 @@ const InlineComboboxInput = ({
|
||||||
trigger,
|
trigger,
|
||||||
} = React.useContext(InlineComboboxContext);
|
} = React.useContext(InlineComboboxContext);
|
||||||
|
|
||||||
const store = useComboboxContext()!;
|
const store = useRequiredComboboxContext();
|
||||||
const value = store.useState('value');
|
const value = store.useState('value');
|
||||||
|
|
||||||
const ref = useComposedRef(propRef, contextRef);
|
const ref = useComposedRef(propRef, contextRef);
|
||||||
|
|
@ -341,14 +353,15 @@ const InlineComboboxItem = ({
|
||||||
|
|
||||||
const { filter, removeInput } = React.useContext(InlineComboboxContext);
|
const { filter, removeInput } = React.useContext(InlineComboboxContext);
|
||||||
|
|
||||||
const store = useComboboxContext()!;
|
const store = useRequiredComboboxContext();
|
||||||
|
|
||||||
// Optimization: Do not subscribe to value if filter is false
|
// Always call hook unconditionally; only use value if filter is active
|
||||||
const search = filter && store.useState('value');
|
const storeValue = store.useState('value');
|
||||||
|
const search = filter ? storeValue : '';
|
||||||
|
|
||||||
const visible = React.useMemo(
|
const visible = React.useMemo(
|
||||||
() =>
|
() =>
|
||||||
!filter || filter({ group, keywords, label, value }, search as string),
|
!filter || filter({ group, keywords, label, value }, search),
|
||||||
[filter, group, keywords, label, value, search]
|
[filter, group, keywords, label, value, search]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -371,7 +384,7 @@ const InlineComboboxEmpty = ({
|
||||||
className,
|
className,
|
||||||
}: React.HTMLAttributes<HTMLDivElement>) => {
|
}: React.HTMLAttributes<HTMLDivElement>) => {
|
||||||
const { setHasEmpty } = React.useContext(InlineComboboxContext);
|
const { setHasEmpty } = React.useContext(InlineComboboxContext);
|
||||||
const store = useComboboxContext()!;
|
const store = useRequiredComboboxContext();
|
||||||
const items = store.useState('items');
|
const items = store.useState('items');
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
|
|
|
||||||
|
|
@ -186,7 +186,7 @@ export function SlashInputElement({
|
||||||
>
|
>
|
||||||
<InlineComboboxInput />
|
<InlineComboboxInput />
|
||||||
|
|
||||||
<InlineComboboxContent>
|
<InlineComboboxContent className="dark:bg-neutral-800 dark:border dark:border-neutral-700">
|
||||||
<InlineComboboxEmpty>No results found.</InlineComboboxEmpty>
|
<InlineComboboxEmpty>No results found.</InlineComboboxEmpty>
|
||||||
|
|
||||||
{slashCommandGroups.map(({ heading, items }) => (
|
{slashCommandGroups.map(({ heading, items }) => (
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue