import {PlatformSelector} from '@site/src/components/PlatformSelector/PlatformSelector';
import {PlatformSection} from '@site/src/components/PlatformSection/PlatformSection';

import ReactJs from './_003-custom-renderers/#react.mdx';
import JavaScript from './_003-custom-renderers/#js.mdx';

import ConfigReactJs from './_003-custom-renderers/#react/config.mdx';
import ConfigJavaScript from './_003-custom-renderers/#js/config.mdx';

import ResponseInterfaceReactJs from './_003-custom-renderers/#react/response-interfaces.mdx';
import ResponseInterfaceJavaScript from './_003-custom-renderers/#js/response-interfaces.mdx';

import PromptInterfaceReactJs from './_003-custom-renderers/#react/prompt-interface.mdx';
import PromptInterfaceJavaScript from './_003-custom-renderers/#js/prompt-interface.mdx';

# Custom Renderers

The custom renderers feature allows developers to define customised display logic for messages in the chat area.

This feature is particularly useful when the data is not a simple string, but a complex object that needs to be rendered
in a specific way, or when the developer needs to render additional elements that are not part of the response
but related to it, such as rating buttons or other interactive elements.

## Usage

Custom renderers can be provided to the `AiChat` component as part of the `messageOptions` prop.

<PlatformSelector reactJs={ConfigReactJs} javascript={ConfigJavaScript}/>

## Interfaces

Below are the interfaces that custom renderers should implement.

---

> ### Response Renderer

<PlatformSelector reactJs={ResponseInterfaceReactJs} javascript={ResponseInterfaceJavaScript}/>

---

> ### Prompt Renderer

<PlatformSelector reactJs={PromptInterfaceReactJs} javascript={PromptInterfaceJavaScript}/>

---

## Behaviour

Custom renderers can either be provided for responses from the AI assistant, or for user prompts that are displayed
in the chat area.

For AI responses, the behaviour of custom renders depends on whether the data is streamed from the server or received
in a single batch.

---

> ### Rendering Streamed AI Responses

For streamed data, a loading spinner will be briefly displayed when the prompt is submitted.<br />
The custom renderer will be **displayed when the streaming starts**, and will receive a `RefObject<HTMLElement>`.<br />
That `containerRef` should be pointed to the HTML element where streamed markdown messages will be appended:

```tsx
const MyCustomRenderer: FC<StreamResponseComponentProps<MyMessage>> = (props) => {
    return (
        <div>
            {/* The container where streamed markdown messages should be appended */}
            <div ref={props.containerRef} />
        </div>
    );
};
```

The properties of the custom renderer will be **updated when the streaming is complete** and the message that has been
fully received.

---

> ### Rendering Batched AI Responses

For batched data, the custom renderer will only be **displayed once the message has been fully received**.<br />
Until then, the message a loading spinner will be displayed.

---

> ### Rendering User Prompts

For user prompts, the custom renderer will be **displayed once the message is sent**.<br />
The custom renderer will receive the message content and the user prompt.
