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-slotdata-statedata-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,slotPropsou na troca de um slot - você ainda quer o router, a página de conversa e o compositor padrão
Próximo passo
- Combine com a sua marca para cores, raio e modo escuro
- Páginas e layouts quando precisar de páginas próprias ou de uma incorporação inline
Esta página foi útil?
Abra uma issue de documentação já preenchida para que a equipe possa agir.

