pass the select through

This commit is contained in:
Nate Kelley 2025-09-29 11:45:37 -06:00
parent 8469471a45
commit 5055530bdf
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
4 changed files with 118 additions and 92 deletions

View File

@ -1,6 +1,7 @@
import { Command } from 'cmdk';
import { useCallback, useEffect, useRef, useState } from 'react';
import { useMemoizedFn } from '@/hooks/useMemoizedFn';
import type { MentionInputRef } from '../MentionInput';
import type { BusterInputProps, BusterOnSelectParams } from './BusterInput.types';
import { BusterInputContainer } from './BusterInputContainer';
import { BusterInputEmpty } from './BusterInputEmpty';
@ -41,6 +42,7 @@ export const BusterInput = ({
const commandListNavigatedRef = useRef(false);
const commandRef = useRef<HTMLDivElement>(null);
const mentionsInputRef = useRef<MentionInputRef>(null);
const showSuggestionList = !hasClickedSelect && suggestionItems.length > 0;
@ -53,7 +55,7 @@ export const BusterInput = ({
}, []);
const onSelectItem = useMemoizedFn(({ onClick, ...params }: BusterOnSelectParams) => {
const { addValueToInput, value, loading, inputValue, label, disabled } = params;
const { addValueToInput, loading, inputValue, label, disabled } = params;
if (disabled) {
console.warn('Item is disabled', params);
return;
@ -66,8 +68,11 @@ export const BusterInput = ({
console.warn('Item is loading', params);
return;
}
console.log('onSelectItem', addValueToInput, params);
if (addValueToInput) setValue(inputValue ?? String(label));
if (addValueToInput) {
const stringValue = inputValue ?? String(label);
mentionsInputRef.current?.editor?.commands.setContent(stringValue);
setValue(stringValue);
}
onClick?.();
if (closeSuggestionOnSelect) setHasClickedSelect(true);
onSuggestionItemClick?.(params);
@ -128,6 +133,7 @@ export const BusterInput = ({
variant={variant}
>
<BusterMentionsInput
ref={mentionsInputRef}
defaultValue={defaultValue}
readOnly={readOnly}
autoFocus={autoFocus}

View File

@ -1,7 +1,7 @@
/** biome-ignore-all lint/complexity/noUselessFragments: Intersting bug when NOT using fragments */
import { Command } from 'cmdk';
import React from 'react';
import { MentionInput, type MentionInputProps } from '../MentionInput';
import React, { forwardRef } from 'react';
import { MentionInput, type MentionInputProps, type MentionInputRef } from '../MentionInput';
import type { BusterInputProps } from './BusterInput.types';
export type BusterMentionsInputProps = Pick<
@ -23,17 +23,11 @@ export type BusterMentionsInputProps = Pick<
commandListNavigatedRef?: React.RefObject<boolean>;
};
export const BusterMentionsInput = ({
value: valueProp,
placeholder,
defaultValue,
mentions,
value,
...props
}: BusterMentionsInputProps) => {
export const BusterMentionsInput = forwardRef<MentionInputRef, BusterMentionsInputProps>(
({ value: valueProp, placeholder, defaultValue, mentions, value, ...props }, ref) => {
return (
<React.Fragment>
<MentionInput mentions={mentions} defaultValue={value} {...props} />
<MentionInput ref={ref} mentions={mentions} defaultValue={value} {...props} />
<Command.Input
value={value}
autoFocus={false}
@ -43,4 +37,7 @@ export const BusterMentionsInput = ({
/>
</React.Fragment>
);
};
}
);
BusterMentionsInput.displayName = 'BusterMentionsInput';

View File

@ -3,14 +3,20 @@ import Document from '@tiptap/extension-document';
import Paragraph from '@tiptap/extension-paragraph';
import Text from '@tiptap/extension-text';
import { EditorContent, EditorContext, useEditor } from '@tiptap/react';
import { useMemo } from 'react';
import { forwardRef, useImperativeHandle, useMemo } from 'react';
import { cn } from '@/lib/utils';
import { MentionExtension } from './MentionExtension';
import type { MentionInputProps, MentionSuggestionExtension } from './MentionInput.types';
import type {
MentionInputProps,
MentionInputRef,
MentionSuggestionExtension,
} from './MentionInput.types';
import { SubmitOnEnter } from './SubmitEnterExtension';
import { onUpdateTransformer } from './update-transformers';
export const MentionInput = ({
export const MentionInput = forwardRef<MentionInputRef, MentionInputProps>(
(
{
mentions,
onChange,
defaultValue = '',
@ -23,7 +29,9 @@ export const MentionInput = ({
disabled,
onPressEnter,
commandListNavigatedRef,
}: MentionInputProps) => {
},
ref
) => {
const mentionsByTrigger = useMemo(() => {
return mentions.reduce(
(acc, mention) => {
@ -67,6 +75,14 @@ export const MentionInput = ({
onBlur: onBlur,
});
useImperativeHandle(
ref,
() => ({
editor,
}),
[editor]
);
const providerValue = useMemo(() => ({ editor }), [editor]);
return (
@ -76,4 +92,7 @@ export const MentionInput = ({
</EditorContext.Provider>
</ClientOnly>
);
};
}
);
MentionInput.displayName = 'MentionInput';

View File

@ -1,5 +1,5 @@
import type { MentionNodeAttrs, MentionOptions } from '@tiptap/extension-mention';
import type { EditorEvents } from '@tiptap/react';
import type { Editor, EditorEvents } from '@tiptap/react';
import type { MentionPillAttributes } from './MentionPill';
export type MentionOnSelectParams<T = unknown> = {
@ -102,6 +102,10 @@ export type MentionInputProps = {
commandListNavigatedRef?: React.RefObject<boolean>;
};
export type MentionInputRef = {
editor: Editor | null;
};
declare module '@tiptap/core' {
interface Storage {
mention: {