Pular para o conteúdo principal

Mude uma coisa só

Mantenha o widget padrão e troque uma peça pequena por vez.

O Support foi feito para mudanças pequenas. Comece pelos estilos, depois troque um componente e deixe o resto do widget funcionando como está.

Os exemplos em TSX usam utilitários do Tailwind por brevidade. O Tailwind não é obrigatório: troque esses nomes de classe pelo seu próprio CSS quando usar o ponto de entrada pré-compilado @fluxolat/react/styles.css.

Use isto quando

  • você quer o widget no ar rápido
  • precisa que a bolha ou a primeira tela pareçam mais com o seu produto
  • quer substituir coisas com segurança, sem refazer o router nem a interface de conversa

A menor mudança que funciona

import { Support } from "@fluxolat/react";
 
<Support
  classNames={{
    trigger: "bg-black text-white",
    content: "border-neutral-200 shadow-2xl",
  }}
  slotProps={{
    content: {
      className: "border border-neutral-200 shadow-2xl",
    },
  }}
/>;

Use classNames para o gatilho e o conteúdo embutidos. Use slotProps quando quiser passar props de apresentação extras às partes embutidas.

O widget padrão também expõe pontos de estilo estáveis:

  • data-slot
  • data-state
  • data-page
[data-slot="trigger"][data-state="open"] {
  transform: scale(1.02);
}
 
[data-slot="content"] {
  backdrop-filter: blur(12px);
}

Quando você substitui um slot, herda as responsabilidades de acessibilidade dele. Mantenha a ref encaminhada e as props do botão, preserve o nome acessível e os estilos de foco do gatilho, faça a área ter pelo menos 44 × 44 pixels CSS e anuncie as mensagens não lidas com um texto significativo quando isso importar para o usuário.

Exemplo de bolha 1

Use slots.trigger quando a única coisa a mudar for o lançador.

import { Support, type SupportTriggerSlotProps } from "@fluxolat/react";
import * as React from "react";
 
function mergeClassNames(...classes: Array<string | undefined>) {
  return classes.filter(Boolean).join(" ");
}
 
const ClassicBubble = React.forwardRef<HTMLButtonElement, SupportTriggerSlotProps>(
  function ClassicBubbleTrigger(
    { className, isOpen, isTyping: _isTyping, toggle, unreadCount, ...props },
    ref
  ) {
    return (
      <button
        {...props}
        className={mergeClassNames(
          "relative flex size-14 items-center justify-center border border-black bg-black font-medium text-white text-sm shadow-xl transition-transform hover:scale-[1.02]",
          className
        )}
        onClick={toggle}
        ref={ref}
        type="button"
      >
        {isOpen ? "Close" : "Chat"}
        {unreadCount > 0 ? (
          <span className="-right-1 -top-1 absolute flex size-5 items-center justify-center border border-white bg-orange-500 text-[11px]">
            {unreadCount}
          </span>
        ) : null}
      </button>
    );
  }
);
 
<Support slots={{ trigger: ClassicBubble }} />;

Exemplo de bolha 2

Esse mesmo slot pode parecer mais um botão dentro do produto do que uma bolha de chat flutuante.

import { Support, type SupportTriggerSlotProps } from "@fluxolat/react";
import * as React from "react";
 
function mergeClassNames(...classes: Array<string | undefined>) {
  return classes.filter(Boolean).join(" ");
}
 
const PillBubble = React.forwardRef<HTMLButtonElement, SupportTriggerSlotProps>(
  function PillBubble(
    {
      className,
      isOpen: _isOpen,
      isTyping,
      unreadCount: _unreadCount,
      toggle,
      ...props
    },
    ref
  ) {
    return (
      <button
        {...props}
        className={mergeClassNames(
          "flex h-12 items-center gap-2 border border-black bg-white px-4 font-medium text-black text-sm shadow-xl transition-transform hover:scale-[1.01]",
          className
        )}
        onClick={toggle}
        ref={ref}
        type="button"
      >
        <span className="size-2 bg-orange-500" />
        <span>{isTyping ? "Support is typing..." : "Open support"}</span>
      </button>
    );
  }
);
 
<Support slots={{ trigger: PillBubble }} />;

Substituir a primeira tela

Mantenha o fluxo de conversa padrão e mude só a tela inicial.

import { Support, type SupportHomePageSlotProps } from "@fluxolat/react";
 
function CustomHomePage({
  className,
  openConversationHistory,
  quickOptions,
  startConversation,
  website,
}: SupportHomePageSlotProps) {
  return (
    <div className={className}>
      <h2>{website?.name}</h2>
      <p>Rewrite the first screen while keeping the default conversation flow.</p>
 
      {quickOptions.map((option) => (
        <button key={option} onClick={() => startConversation(option)} type="button">
          {option}
        </button>
      ))}
 
      <button onClick={openConversationHistory} type="button">
        View past conversations
      </button>
    </div>
  );
}
 
<Support
  slotProps={{
    content: {
      className: "border shadow-2xl",
    },
  }}
  slots={{ homePage: CustomHomePage }}
/>;

Fluxo

Real support, instantly.

Ask about onboarding, setup, billing, or migration without leaving the product.

Quando parar por aqui

  • o seu widget já está em produção
  • as mudanças de marca cabem em classNames, slotProps ou na troca de um slot
  • você ainda quer o router, a página de conversa e o compositor padrão

Próximo passo

Esta página foi útil?

Abra uma issue de documentação já preenchida para que a equipe possa agir.