Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { createChatMessagesComponent } from './ChatMessages';
import { createChatPromptComponent } from './ChatPrompt';
import { createChatToggleButtonComponent } from './ChatToggleButton';

import type { MutableRef, Renderer, ComponentProps } from '../../types';
import type { Renderer, ComponentProps } from '../../types';
import type { ChatHeaderProps } from './ChatHeader';
import type { ChatMessagesProps } from './ChatMessages';
import type { ChatPromptProps } from './ChatPrompt';
Expand Down Expand Up @@ -62,8 +62,6 @@ export function createChatComponent({ createElement, Fragment }: Renderer) {
const ChatMessages = createChatMessagesComponent({ createElement, Fragment });
const ChatPrompt = createChatPromptComponent({ createElement, Fragment });

const promptRef: MutableRef<HTMLTextAreaElement | null> = { current: null };

return function Chat({
open,
maximized = false,
Expand Down Expand Up @@ -95,14 +93,16 @@ export function createChatComponent({ createElement, Fragment }: Renderer) {
>
<ChatHeader {...headerProps} maximized={maximized} />
<ChatMessages {...messagesProps} />
<ChatPrompt {...promptProps} ref={promptRef} />
<ChatPrompt {...promptProps} />
</div>

<ChatToggleButton
{...toggleButtonProps}
onClick={() => {
toggleButtonProps.onClick?.();
promptRef.current?.focus?.();
if (!open) {
promptProps.promptRef?.current?.focus();
}
}}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,9 @@ export type ChatPromptProps = Omit<
*/
onInput?: ComponentProps<'textarea'>['onInput'];
/**
* Ref callback to get access to the focus function
* Ref to the prompt textarea element for focus management
*/
ref?: MutableRef<HTMLTextAreaElement | null>;
promptRef?: MutableRef<HTMLTextAreaElement | null>;
};

export function createChatPromptComponent({ createElement }: Renderer) {
Expand Down Expand Up @@ -158,12 +158,12 @@ export function createChatPromptComponent({ createElement }: Renderer) {

const setTextAreaRef = (
element: HTMLTextAreaElement | null,
ref?: MutableRef<HTMLTextAreaElement | null>
promptRef?: MutableRef<HTMLTextAreaElement | null>
) => {
textAreaElement = element;

if (ref) {
ref.current = element;
if (promptRef) {
promptRef.current = element;
}

if (element) {
Expand Down Expand Up @@ -194,7 +194,7 @@ export function createChatPromptComponent({ createElement }: Renderer) {
onSubmit,
onKeyDown,
onStop,
ref,
promptRef,
...props
} = userProps;

Expand Down Expand Up @@ -267,7 +267,7 @@ export function createChatPromptComponent({ createElement }: Renderer) {
>
<textarea
{...props}
ref={(element) => setTextAreaRef(element, ref)}
ref={(element) => setTextAreaRef(element, promptRef)}
data-max-rows={maxRows}
className={cx(cssClasses.textarea)}
value={value}
Expand Down
2 changes: 2 additions & 0 deletions packages/instantsearch.js/src/widgets/chat/chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ const createRenderer = <THit extends NonNullable<object> = BaseHit>({
const [isClearing, setIsClearing] = state.use(false);
const [maximized, setMaximized] = state.use(false);
const [isScrollAtBottom, setIsScrollAtBottom] = state.use(true);
const [promptRef] = state.use({ current: null });
Comment thread
Haroenv marked this conversation as resolved.

const onClear = () => setIsClearing(true);
const onClearTransitionEnd = () => {
Expand Down Expand Up @@ -226,6 +227,7 @@ const createRenderer = <THit extends NonNullable<object> = BaseHit>({
tools: toolsForUi,
}}
promptProps={{
promptRef,
status,
value: input,
onInput: (event) => {
Expand Down
3 changes: 3 additions & 0 deletions packages/react-instantsearch/src/widgets/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ export function Chat<
const [isClearing, setIsClearing] = React.useState(false);
const [isScrollAtBottom, setIsScrollAtBottom] = React.useState(true);

const promptRef = React.useRef<HTMLTextAreaElement>(null);

const tools = React.useMemo(() => {
const defaults = createDefaultTools(itemComponent, getSearchPageURL);

Expand Down Expand Up @@ -205,6 +207,7 @@ export function Chat<
...messagesProps,
}}
promptProps={{
promptRef,
status,
value: input,
// Explicit event type is required to prevent TypeScript error
Expand Down