Кастомизация Canvas App

Здесь можно изменить способ отображения смартапов типа Canvas App (контейнер) — по умолчанию они во всплывающем окне. В коде ниже меняем контейнер, чтобы отображалось как часть страницы.

import React, { FC } from 'react';
import { createAssistantClient } from '@sberdevices/assistant-client';
import { FloatingAssistantChat } from '@sberdevices/assistant-web-sdk';

const CustomCanvasContainer: FC<{ canvasReady: boolean; onClose: () => void }> = ({
    canvasReady,
    children,
    onClose,
}) => {
    if (!canvasReady) {
        return <div>Loading...</div>;
    }

    return (
        <div>
            <button onClick={onClose}>Закрыть</button>
            {children}
        </div>
    );
};

const Chat: FC<{ client: ReturnType<typeof createAssistantClient> }> = ({ client }) => (
    <FloatingAssistantChat assistant={client} onCanvasRender={CustomCanvasContainer} mobile={false} />
);

Также, канвас можно встроить на страницу, используя ReactDOM.createPortal:

import React, { FC } from 'react';
import ReactDOM from 'react-dom';
import { createAssistantClient } from '@sberdevices/assistant-client';
import { FloatingAssistantChat } from '@sberdevices/assistant-web-sdk';

const CONTAINER_ID = 'canvas-root';

const CustomCanvasContainer: FC<{ canvasReady: boolean; onClose: () => void }> = ({ canvasReady, children, onClose }) => {
    if (!canvasReady) {
        return <div>Loading...</div>;
    }

    return (
        <div>
            <button onClick={onClose}>Закрыть</button>
            {children}
        </div>
    );
};

const CanvasPortal: FC<{ canvasReady: boolean; onClose: () => void }> = ({ ...props }) => {
    const canvasRootRef = useRef<HTMLElement>();

    useEffect(() => {
        canvasRootRef.current = document.getElementById(CONTAINER_ID);
    }, []);

    if (!canvasRootRef.current) {
        return null;
    }

    return ReactDOM.createPortal(<CustomCanvasContainer {...props} />, canvasRootRef.current);
}

const Chat: FC<{ client: ReturnType<typeof createAssistantClient> }> = ({ client }) => (
    <FloatingAssistantChat assistant={client} onCanvasRender={CanvasPortal} mobile={false} />
);

const client = createAssistantClient(...);

const App = () => (
    <>
        <Chat client={client} />
        <div id={CONTAINER_ID} />
    </>
);

Заметили ошибку?

Выделите текст и нажмите Ctrl + Enter, чтобы сообщить нам о ней