@leve.ai/chat
v1.0.35
Published
Sistema de chat multiplataforma com suporte a WebSocket para Web e React Native
Maintainers
Readme
@leve.ai/chat
Sistema de chat multiplataforma com suporte a WebSocket para Web e React Native.
📦 Instalação
npm install @leve.ai/chat @leve.ai/socket-client
# ou
yarn add @leve.ai/chat @leve.ai/socket-client
# ou
pnpm add @leve.ai/chat @leve.ai/socket-client🚀 Uso
Web (React, Next.js, Vite, etc.)
import { ChatWidget } from '@leve.ai/chat/web'
import { ChatProvider } from '@leve.ai/chat/shared'
// O CSS é importado automaticamente!
function App() {
return (
<ChatProvider
user={{ id: 'user123', name: 'João' }}
socketUrl="https://seu-servidor.com"
socketApiKey="sua-api-key"
socketNamespace="chat"
autoShowOnMessage={true}
>
<YourApp />
<ChatWidget
theme={{
primaryColor: '#3b82f6' // Personalize a cor primária!
}}
/>
</ChatProvider>
)
}Nota sobre estilos: Os estilos são importados automaticamente quando você importa os componentes. Se houver problemas de conflito de CSS, veja o Guia de Isolamento de CSS.
Personalização de cores: Você pode customizar as cores do chat usando a prop
theme. Veja mais detalhes na seção de Personalização de Cores.
React Native (Expo, RN CLI)
import { ChatWidget } from '@leve.ai/chat/native'
import { ChatProvider } from '@leve.ai/chat/shared'
function App() {
return (
<ChatProvider
user={{ id: 'user123', name: 'João' }}
socketUrl="https://seu-servidor.com"
socketApiKey="sua-api-key"
socketNamespace="chat"
autoShowOnMessage={true}
>
<YourApp />
<ChatWidget />
</ChatProvider>
)
}✨ Metro Bundler Compatível: A partir da v1.0.9, a biblioteca funciona nativamente com Metro bundler sem necessidade de configuração adicional. Para mais detalhes, veja METRO_COMPATIBILITY.md.
Apenas Hooks/Lógica (UI Customizado)
import { useChat, useOrderRooms } from '@leve.ai/chat/shared'
function CustomChatUI() {
const { messages, sendMessage } = useChat()
const { openOrderChat } = useOrderRooms({
orderIds: ['order1', 'order2'],
enabled: true
})
// Criar seu próprio UI
return (
<div>
{messages.map(msg => (
<div key={msg.id}>{msg.content}</div>
))}
</div>
)
}📚 API Reference
ChatProvider
Provider principal do sistema de chat.
Props:
children: ReactNode- Componentes filhosautoShowOnMessage?: boolean- Mostrar widget automaticamente ao receber mensagem (default:true)
<ChatProvider autoShowOnMessage={false}>
{/* seu app */}
</ChatProvider>useChat()
Hook principal para gerenciar o chat.
Retorno:
{
// Estado
messages: Message[]
currentRoom: string | null
isConnected: boolean
connectionStatus: ConnectionStatus
isWidgetVisible: boolean
unreadCount: number
users: User[]
isLoading: boolean
error: string | null
rooms: ChatRoom[]
currentView: 'rooms' | 'chat'
// Ações
sendMessage: (content: string, type?: MessageType) => Promise<void>
markAsRead: (messageId: string) => void
markAllAsRead: () => void
clearMessages: () => void
joinRoom: (roomId: string) => Promise<void>
leaveRoom: () => void
showWidget: () => void
hideWidget: () => void
toggleWidget: () => void
// Gerenciamento de Salas
addRoom: (room: ChatRoom) => void
removeRoom: (roomId: string) => void
updateRoom: (roomId: string, updates: Partial<ChatRoom>) => void
// Socket
socket: Socket | null
authenticated: boolean
subscribe: (channel: string) => void
unsubscribe: (channel: string) => void
}Exemplo:
const { messages, sendMessage, isConnected } = useChat()
const handleSend = async () => {
await sendMessage('Olá!', MessageType.TEXT)
}useOrderRooms(options)
Hook para gerenciar múltiplas salas de pedidos.
Params:
{
orderIds: string[] // IDs dos pedidos
enabled?: boolean // Ativar auto-subscribe (default: true)
}Retorno:
{
subscribeToOrderRooms: (orderIds: string[]) => void
unsubscribeFromOrderRooms: () => void
openOrderChat: (orderId: string) => Promise<void>
getOrderRoomId: (orderId: string) => string
subscribedRooms: string[]
getOrderUnreadCount: (orderId: string) => number
getTotalUnreadCount: () => number
getAllOrdersUnreadCount: () => Record<string, number>
}Exemplo:
const {
openOrderChat,
getOrderUnreadCount
} = useOrderRooms({
orderIds: orders.map(o => o.id),
enabled: true
})
// Abrir chat de pedido específico
const handleOpenChat = (orderId: string) => {
openOrderChat(orderId)
}
// Pegar contador de não lidas
const unread = getOrderUnreadCount('order123')useChatWidget()
Hook simplificado para controle do widget.
Retorno:
{
isVisible: boolean
unreadCount: number
isConnected: boolean
isLoading: boolean
currentRoom: string | null
showWidget: () => void
hideWidget: () => void
toggleWidget: () => void
hasUnreadMessages: boolean
}Exemplo:
function HeaderChatButton() {
const { showWidget, unreadCount, hasUnreadMessages } = useChatWidget()
return (
<button onClick={showWidget} className="relative">
<MessageCircle />
{hasUnreadMessages && (
<span className="badge">{unreadCount}</span>
)}
</button>
)
}🎨 Componentes
Web Components
ChatWidget
Widget completo de chat com todas as funcionalidades.
Props:
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'- Posição do widget (default:'bottom-right')maxHeight?: number- Altura máxima em pixels (default:500)maxWidth?: number- Largura máxima em pixels (default:380)zIndex?: number- z-index do widget (default:9999)className?: string- Classes CSS adicionaiswidgetClassName?: string- Classes CSS para o container do widgettheme?: ChatTheme- Objeto de personalização de cores (veja Personalização de Cores)
import { ChatWidget } from '@leve.ai/chat/web'
<ChatWidget
position="bottom-right"
maxHeight={600}
maxWidth={400}
zIndex={10000}
/>🎨 Personalização de Cores
O ChatWidget aceita uma prop theme para customizar as cores primárias:
Props do theme:
primaryColor?: string- Cor primária principal (default:'#fa5534')primaryColorHover?: string- Cor ao passar o mouse (default:'#e04829')primaryColorLight?: string- Cor primária mais clara (default:'rgba(250, 85, 52, 0.9)')
<ChatWidget
theme={{
primaryColor: '#3b82f6', // Azul
primaryColorHover: '#2563eb', // Azul escuro
primaryColorLight: 'rgba(59, 130, 246, 0.9)'
}}
/>Exemplos de temas:
// Tema Verde
<ChatWidget
theme={{
primaryColor: '#10b981',
primaryColorHover: '#059669',
primaryColorLight: 'rgba(16, 185, 129, 0.9)'
}}
/>
// Tema Roxo
<ChatWidget
theme={{
primaryColor: '#8b5cf6',
primaryColorHover: '#7c3aed',
primaryColorLight: 'rgba(139, 92, 246, 0.9)'
}}
/>
// Tema usando cores da sua marca
<ChatWidget
theme={{
primaryColor: '#ff6b35',
primaryColorHover: '#ff5722',
primaryColorLight: 'rgba(255, 107, 53, 0.9)'
}}
/>As cores serão aplicadas em:
- Botão flutuante do chat
- Header do widget
- Bolhas de mensagens enviadas
- Botão de enviar
- Ícones e destaques
ChatMessages
Apenas a área de mensagens.
import { ChatMessages } from '@leve.ai/chat/web'
<ChatMessages />ChatInput
Apenas o input de envio.
import { ChatInput } from '@leve.ai/chat/web'
<ChatInput />ChatRoomsList
Apenas a lista de salas.
import { ChatRoomsList } from '@leve.ai/chat/web'
<ChatRoomsList />React Native Components
Mesmos componentes, porém adaptados para React Native:
import {
ChatWidget,
ChatMessages,
ChatInput,
ChatRoomsList
} from '@leve.ai/chat/native'🔧 TypeScript
Todos os tipos são exportados do /shared:
import type {
Message,
ChatRoom,
User,
MessageType,
ConnectionStatus,
ChatState,
ChatContextType,
ChatTheme,
ChatWidgetProps
} from '@leve.ai/chat/shared'Tipo ChatTheme:
interface ChatTheme {
primaryColor?: string
primaryColorHover?: string
primaryColorLight?: string
}🎯 Casos de Uso
Chat em Página de Pedidos
import { useOrderRooms } from '@leve.ai/chat/shared'
function OrdersPage() {
const { data: orders } = useOrders()
const {
openOrderChat,
getAllOrdersUnreadCount
} = useOrderRooms({
orderIds: orders?.map(o => o.id) || [],
enabled: !!orders
})
const unreadByOrder = getAllOrdersUnreadCount()
return (
<div>
{orders?.map(order => (
<div key={order.id}>
<h3>{order.id}</h3>
<button onClick={() => openOrderChat(order.id)}>
Chat {unreadByOrder[order.id] > 0 && `(${unreadByOrder[order.id]})`}
</button>
</div>
))}
</div>
)
}Botão de Chat no Header
import { useChatWidget } from '@leve.ai/chat/shared'
function Header() {
const { showWidget, unreadCount, hasUnreadMessages } = useChatWidget()
return (
<header>
<button onClick={showWidget} className="relative">
<MessageCircle />
{hasUnreadMessages && (
<span className="absolute -top-1 -right-1 bg-red-500 text-white rounded-full px-1.5 py-0.5 text-xs">
{unreadCount}
</span>
)}
</button>
</header>
)
}UI Totalmente Customizado
import { useChat } from '@leve.ai/chat/shared'
function MyCustomChat() {
const { messages, sendMessage, currentRoom } = useChat()
return (
<div className="my-custom-chat">
<div className="messages">
{messages.map(msg => (
<div key={msg.id} className="message">
<span>{msg.senderName}:</span>
<span>{msg.content}</span>
</div>
))}
</div>
<input
onKeyPress={(e) => {
if (e.key === 'Enter') {
sendMessage(e.currentTarget.value)
e.currentTarget.value = ''
}
}}
/>
</div>
)
}📦 Estrutura de Imports
@leve.ai/chat
├── /web → Componentes Web (TailwindCSS)
├── /native → Componentes React Native (StyleSheet)
└── /shared → Hooks, Context, Types (compartilhados)Tree-shaking: Apenas o código importado será incluído no bundle final.
⚙️ Configuração
🎨 Estilos e CSS
O chat usa Tailwind CSS com prefixo lv- e isolamento de estilos para evitar conflitos com seu projeto.
Todas as classes são prefixadas automaticamente:
flex→lv-flexbg-primary→lv-bg-primarytext-white→lv-text-white
Problemas com estilos? Veja o guia completo:
Web (TailwindCSS)
Se estiver usando TailwindCSS no seu projeto, você pode:
Opção 1: Ignorar o pacote no seu Tailwind (recomendado)
module.exports = {
content: [
"./src/**/*.{js,ts,jsx,tsx}",
"!./node_modules/@leve.ai/**/*", // ← Ignora o pacote
],
}Opção 2: Incluir o pacote (não recomendado)
module.exports = {
content: [
"./src/**/*.{js,ts,jsx,tsx}",
"./node_modules/@leve.ai/chat/dist/web/**/*.{js,mjs}"
],
}React Native (Ícones)
Instale os ícones para React Native:
npm install lucide-react-native🔗 Peer Dependencies
react: ^18.0.0 || ^19.0.0react-dom: ^18.0.0 || ^19.0.0 (Web only)react-native: >=0.70.0 (Native only)@leve.ai/socket-client: ^1.0.0
📄 Licença
MIT © Leve.ai
🔧 Desenvolvimento
Para desenvolver e testar a biblioteca localmente, veja o Guia de Desenvolvimento.
Quick Start:
# Link para testes locais
npm run link:bun # ou link:yarn / link:npm
# Build com watch mode
npm run build:watch
# Usar helper script
./dev-link.sh link bun🤝 Contribuindo
Contribuições são bem-vindas! Por favor, abra uma issue ou PR.
📮 Suporte
- 📧 Email: [email protected]
- 📖 Docs: https://docs.leve.ai
- 🐛 Issues: https://github.com/leveai/chat/issues
