Added callback for suggestions

This commit is contained in:
Nate Kelley 2025-09-29 19:58:03 -06:00
parent 77847ed4b7
commit 1676402541
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
2 changed files with 43 additions and 21 deletions

View File

@ -2,7 +2,7 @@ import type { ListShortcutsResponse } from '@buster/server-shared/shortcuts';
import type { GetSuggestedPromptsResponse } from '@buster/server-shared/user';
import type { Editor } from '@tiptap/react';
import sampleSize from 'lodash/sampleSize';
import React, { useMemo, useRef, useState } from 'react';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import { useCreateShortcutsMentionsSuggestions } from '@/components/features/input/Mentions/ShortcutsSuggestions/ShortcutsSuggestions';
import { Plus } from '@/components/ui/icons';
import CircleQuestion from '@/components/ui/icons/NucleoIconOutlined/circle-question';
@ -35,10 +35,11 @@ export const BusterChatInputBase: React.FC<BusterChatInput> = React.memo(
const uniqueSuggestions = useUniqueSuggestions(suggestedPrompts);
const [openCreateShortcutModal, setOpenCreateShortcutModal] = useState(false);
const [mode, setMode] = useState<BusterChatInputMode>('auto');
const shortcutsSuggestions = useShortcuts(
shortcuts,
setOpenCreateShortcutModal,
mentionInputSuggestionsRef.current?.onChangeValue
mentionInputSuggestionsRef
);
const suggestionItems: MentionInputSuggestionsProps['suggestionItems'] = useMemo(() => {
@ -66,10 +67,6 @@ export const BusterChatInputBase: React.FC<BusterChatInput> = React.memo(
return [shortcutsMentionsSuggestions];
}, [shortcutsMentionsSuggestions]);
const onDictate = useMemoizedFn((transcript: string) => {
mentionInputSuggestionsRef.current?.onChangeValue(transcript);
});
const onSubmitPreflight = (value: string) => {
if (submitting) {
console.warn('Input is submitting');
@ -88,14 +85,6 @@ export const BusterChatInputBase: React.FC<BusterChatInput> = React.memo(
}
);
const onSubmitButton = useMemoizedFn(() => {
const value = mentionInputSuggestionsRef.current?.getValue();
if (value) {
onSubmitPreflight(value.transformedValue);
}
});
return (
<React.Fragment>
<MentionInputSuggestions
@ -107,13 +96,12 @@ export const BusterChatInputBase: React.FC<BusterChatInput> = React.memo(
ref={mentionInputSuggestionsRef}
>
<BusterChatInputButtons
onSubmit={onSubmitButton}
onSubmit={onSubmitPreflight}
onStop={onStop}
submitting={submitting}
disabled={disabled}
mode={mode}
onModeChange={setMode}
onDictate={onDictate}
/>
</MentionInputSuggestions>
@ -182,7 +170,7 @@ const useUniqueSuggestions = (
const useShortcuts = (
shortcuts: ListShortcutsResponse['shortcuts'],
setOpenCreateShortcutModal: (open: boolean) => void,
onChangeValue: MentionInputSuggestionsRef['onChangeValue'] | undefined
mentionInputSuggestionsRef: React.RefObject<MentionInputSuggestionsRef | null>
): MentionInputSuggestionsProps['suggestionItems'] => {
return useMemo(() => {
const shortcutsItems = shortcuts.map<MentionInputSuggestionsDropdownItem>((shortcut) => {
@ -193,6 +181,7 @@ const useShortcuts = (
icon: '/',
inputValue: `/ ${shortcut.name}`,
onClick: () => {
const onChangeValue = mentionInputSuggestionsRef.current?.onChangeValue;
onChangeValue?.(shortcut.name);
},
};
@ -218,5 +207,5 @@ const useShortcuts = (
closeOnSelect: true,
},
];
}, [shortcuts]);
}, [shortcuts, setOpenCreateShortcutModal, mentionInputSuggestionsRef]);
};

View File

@ -2,6 +2,7 @@ import { Command, useCommandState } from 'cmdk';
import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';
import { createContext, useContextSelector } from 'use-context-selector';
import { useMemoizedFn } from '@/hooks/useMemoizedFn';
import { useMounted } from '@/hooks/useMount';
import { cn } from '@/lib/utils';
import type { MentionInputProps, MentionInputRef } from '../MentionInput';
import type {
@ -157,11 +158,15 @@ export const MentionInputSuggestions = forwardRef<
onChangeValue,
getValue,
}),
[value]
[value, onChangeValue, getValue]
);
return (
<MentionInputSuggestionsProvider value={value}>
<MentionInputSuggestionsProvider
value={value}
onChangeValue={onChangeValue}
getValue={getValue}
>
<Command
ref={commandRef}
label={ariaLabel}
@ -211,21 +216,31 @@ export const MentionInputSuggestions = forwardRef<
}
);
MentionInputSuggestions.displayName = 'MentionInputSuggestions';
const MentionInputSuggestionsContext = createContext<{
value: string;
onChangeValue: MentionInputSuggestionsRef['onChangeValue'];
getValue: MentionInputSuggestionsRef['getValue'];
}>({
value: '',
onChangeValue: () => {},
getValue: () => undefined,
});
const MentionInputSuggestionsProvider = ({
children,
value,
onChangeValue,
getValue,
}: {
children: React.ReactNode;
value: string;
onChangeValue: MentionInputSuggestionsRef['onChangeValue'];
getValue: MentionInputSuggestionsRef['getValue'];
}) => {
return (
<MentionInputSuggestionsContext.Provider value={{ value }}>
<MentionInputSuggestionsContext.Provider value={{ onChangeValue, value, getValue }}>
{children}
</MentionInputSuggestionsContext.Provider>
);
@ -237,6 +252,24 @@ export const useMentionInputHasValue = () => {
return hasValue;
};
const stableSelectorGetValue = (x: { getValue: MentionInputSuggestionsRef['getValue'] }) =>
x.getValue;
export const useMentionInputSuggestionsGetValue = () => {
const getValue = useContextSelector(MentionInputSuggestionsContext, stableSelectorGetValue);
return getValue;
};
const stableSelectorOnChangeValue = (x: {
onChangeValue: MentionInputSuggestionsRef['onChangeValue'];
}) => x.onChangeValue;
export const useMentionInputSuggestionsOnChangeValue = () => {
const onChangeValue = useContextSelector(
MentionInputSuggestionsContext,
stableSelectorOnChangeValue
);
return onChangeValue;
};
const SuggestionsSeperator = () => {
const hasResults = useCommandState((x) => x.filtered.count) > 0;
if (!hasResults) return null;