Componentes React prontos para uso e hooks para gerenciamento de estado
O React SDK (@triglit/react-sdk) fornece componentes React prontos para uso e hooks otimizados para construir interfaces de gerenciamento de workflows. Ele inclui um editor visual completo de workflows, componentes de UI estilizados e suporte completo a TypeScript e i18n.
Confira a documentação oficial em docs.triglit.com.
# pnpm
pnpm add @triglit/react-sdk
# npm
npm install @triglit/react-sdk
# yarn
yarn add @triglit/react-sdkO React SDK requer React 18 ou superior:
{
"peerDependencies": {
"react": "^18 || ^19",
"react-dom": "^18 || ^19"
}
}O SDK requer estilos CSS para funcionar corretamente. Importe o arquivo de estilos no seu projeto:
import '@triglit/react-sdk/styles.css';Onde importar:
- Next.js (App Router):
app/layout.tsxouapp/_app.tsx - Next.js (Pages Router):
pages/_app.tsx - Create React App / Vite:
src/index.tsxousrc/main.tsx
Envolva sua aplicação (ou a parte que usa o SDK) com o TriglitProvider:
import { TriglitProvider } from '@triglit/react-sdk';
import '@triglit/react-sdk/styles.css';
function App() {
return (
<TriglitProvider config={{ apiKey: 'pk_sua_chave_aqui' }}>
{/* Sua aplicação */}
</TriglitProvider>
);
}import { TriglitProvider, WorkflowEditor } from '@triglit/react-sdk';
import '@triglit/react-sdk/styles.css';
function App() {
return (
<TriglitProvider config={{ apiKey: 'pk_...' }}>
<div className="h-screen">
<WorkflowEditor
workflowId="wf_123"
onSave={(versionId) => {
console.log(`Versão ${versionId} salva com sucesso!`);
}}
/>
</div>
</TriglitProvider>
);
}import { TriglitProvider } from '@triglit/react-sdk';
import '@triglit/react-sdk/styles.css';
function App() {
return (
<TriglitProvider
config={{
// Chave de API (obrigatória)
// Se não fornecida, tenta ler de variáveis de ambiente:
// - NEXT_PUBLIC_TRIGLIT_PUBLISHABLE_KEY
// - TRIGLIT_PUBLISHABLE_KEY
apiKey: 'pk_sua_chave_aqui',
// URL base da API (opcional, padrão: https://api.triglit.com)
baseURL: 'https://api.triglit.com',
// Configuração de i18n (opcional)
i18n: {
locale: 'pt-BR', // 'en' (padrão) ou 'pt-BR'
// ou traduções customizadas
translations: {
'workflow.editor.save': 'Salvar',
// ...
},
},
// Callbacks para eventos (opcional)
callbacks: {
onWorkflowVersionCreated: (version) => {
console.log('Versão criada:', version);
},
onWorkflowVersionPublished: (response) => {
console.log('Versão publicada:', response);
},
onWorkflowVersionCreateError: (error) => {
console.error('Erro:', error);
},
// ... outros callbacks
},
}}
>
{/* Sua aplicação */}
</TriglitProvider>
);
}Você pode configurar a chave de API via variável de ambiente:
# Next.js
NEXT_PUBLIC_TRIGLIT_PUBLISHABLE_KEY=pk_...
# Outros frameworks
TRIGLIT_PUBLISHABLE_KEY=pk_...Se a chave for configurada via variável de ambiente, você pode omitir apiKey no config:
<TriglitProvider config={{}}>
{/* SDK usará a variável de ambiente automaticamente */}
</TriglitProvider>Componente principal para editar workflows visualmente:
import { WorkflowEditor } from '@triglit/react-sdk';
<WorkflowEditor
workflowId="wf_123"
initialVersionId="v_456" // opcional
onSave={(versionId) => {
console.log('Salvo:', versionId);
}}
className="custom-class" // opcional
/>Props:
workflowId(string, obrigatório): ID do workflow a ser editadoinitialVersionId(string, opcional): ID da versão inicial a carregaronSave(function, opcional): Callback chamado quando o workflow é salvoclassName(string, opcional): Classe CSS customizadadynamicEnumOptions(function, opcional): Callback para fornecer opções dinâmicas para campos enum marcados como dinâmicos. RecebefieldNameenodeType, retorna array de opções{label: string, value: string}[]ouundefined
Componentes para exibir o status da API:
import {
TriglitLoading,
TriglitError,
TriglitDegraded
} from '@triglit/react-sdk';
// Loading
<TriglitLoading />
// Erro
<TriglitError />
// API degradada
<TriglitDegraded />Campos enum podem ser marcados como dinâmicos no schema do custom node. Quando um campo enum é dinâmico, suas opções são fornecidas em runtime através do callback dynamicEnumOptions:
<WorkflowEditor
workflowId="wf_123"
dynamicEnumOptions={(fieldName, nodeType) => {
// Exemplo: campo "agents" no node "distribute-agent"
if (fieldName === "agents" && nodeType === "distribute-agent") {
// Buscar agentes da sua plataforma
return [
{ label: "João Silva", value: "agent_1" },
{ label: "Maria Santos", value: "agent_2" },
{ label: "Pedro Costa", value: "agent_3" }
];
}
// Retornar undefined se o campo não for dinâmico ou não tiver opções
return undefined;
}}
/>Comportamento:
- Se
dynamicEnumOptionsretornar opções: o campo é renderizado como um select normal com as opções fornecidas - Se
dynamicEnumOptionsretornarundefinedou array vazio: o campo é renderizado como um campo de texto livre (TextInput) - Valores já preenchidos no config são preservados e exibidos
Schema do Custom Node (Backend):
{
"configSchema": {
"agents": {
"type": "enum",
"description": "Lista de agentes para distribuição",
"required": true,
"dynamic": true
}
}
}Componentes individuais do editor (para uso avançado):
import {
WorkflowCanvas,
WorkflowEditorHeader,
WorkflowNodesList,
WorkflowTriggersList,
NodeConfigDialog,
} from '@triglit/react-sdk';Hook principal para acessar o cliente e configuração do SDK:
import { useTriglit } from '@triglit/react-sdk';
function MyComponent() {
const { client, config, i18n, callbacks, apiStatus } = useTriglit();
// client: instância do cliente Triglit
// config: configuração do provider
// i18n: configuração de i18n
// callbacks: callbacks configurados
// apiStatus: status da API ('healthy' | 'degraded' | 'error' | 'loading')
}Hook para gerenciar um workflow:
import { useWorkflow } from '@triglit/react-sdk';
function WorkflowView({ workflowId }: { workflowId: string }) {
const { workflow, isLoading, error } = useWorkflow(workflowId);
if (isLoading) return <div>Carregando...</div>;
if (error) return <div>Erro: {error.message}</div>;
return <div>{workflow?.name}</div>;
}Hook para gerenciar uma versão específica de workflow:
import { useWorkflowVersion } from '@triglit/react-sdk';
function VersionEditor({ versionId }: { versionId: string }) {
const {
version,
isLoading,
updateVersion,
publishVersion,
isUpdating,
isPublishing,
} = useWorkflowVersion(versionId);
const handleSave = () => {
updateVersion({
versionId,
nodes: [...],
edges: [...],
});
};
const handlePublish = () => {
publishVersion(versionId);
};
return (
<div>
<button onClick={handleSave} disabled={isUpdating}>
{isUpdating ? 'Salvando...' : 'Salvar'}
</button>
<button onClick={handlePublish} disabled={isPublishing}>
{isPublishing ? 'Publicando...' : 'Publicar'}
</button>
</div>
);
}Hook para listar versões de um workflow:
import { useWorkflowVersions } from '@triglit/react-sdk';
function VersionsList({ workflowId }: { workflowId: string }) {
const { data, isLoading } = useWorkflowVersions({
workflowId,
pageSize: 10,
});
if (isLoading) return <div>Carregando...</div>;
return (
<ul>
{data?.data.map((version) => (
<li key={version.id}>Versão {version.version}</li>
))}
</ul>
);
}Hook para listar triggers de uma versão:
import { useTriggers } from '@triglit/react-sdk';
function TriggersList({ versionId }: { versionId: string }) {
const { data, isLoading } = useTriggers({
workflowVersionId: versionId,
});
if (isLoading) return <div>Carregando...</div>;
return (
<ul>
{data?.triggers.map((trigger) => (
<li key={trigger.id}>{trigger.type}</li>
))}
</ul>
);
}Hook para gerenciar um trigger específico:
import { useTrigger } from '@triglit/react-sdk';
function TriggerView({ triggerId }: { triggerId: string }) {
const { trigger, isLoading } = useTrigger(triggerId);
if (isLoading) return <div>Carregando...</div>;
return <div>{trigger?.name}</div>;
}Hook para verificar o status da API:
import { useApiStatus } from '@triglit/react-sdk';
function ApiStatusIndicator() {
const status = useApiStatus();
if (status === 'loading') return <div>Conectando...</div>;
if (status === 'error') return <div>Erro na conexão</div>;
if (status === 'degraded') return <div>API com problemas</div>;
return <div>API funcionando normalmente</div>;
}Hook para acessar traduções:
import { useI18n } from '@triglit/react-sdk';
function MyComponent() {
const t = useI18n();
return (
<div>
<button>{t('workflow.editor.save')}</button>
<p>{t('workflow.editor.version', { version: 1 })}</p>
</div>
);
}Hooks para criar, atualizar e deletar recursos:
import {
useCreateWorkflow,
useCreateWorkflowVersion,
useUpdateWorkflowVersion,
usePublishWorkflowVersion,
useCreateTrigger,
useUpdateTrigger,
useDeleteTrigger,
} from '@triglit/react-sdk';
function MyComponent() {
const createWorkflow = useCreateWorkflow();
const createVersion = useCreateWorkflowVersion();
const updateVersion = useUpdateWorkflowVersion();
const publishVersion = usePublishWorkflowVersion();
const createTrigger = useCreateTrigger();
const updateTrigger = useUpdateTrigger();
const deleteTrigger = useDeleteTrigger();
// Usar as mutações...
}O SDK suporta os seguintes locales:
en(Inglês) - padrãopt-BR(Português do Brasil)
<TriglitProvider
config={{
apiKey: 'pk_...',
i18n: {
locale: 'pt-BR', // Usa traduções em português
},
}}
>
{/* Componentes */}
</TriglitProvider>Você pode fornecer traduções customizadas:
<TriglitProvider
config={{
apiKey: 'pk_...',
i18n: {
locale: 'pt-BR',
translations: {
'workflow.editor.save': 'Salvar',
'workflow.editor.publish': 'Publicar',
// ...
},
},
}}
>
{/* Componentes */}
</TriglitProvider>Ou usar uma função de tradução:
<TriglitProvider
config={{
apiKey: 'pk_...',
i18n: {
locale: 'pt-BR',
translations: (key: string) => {
// Sua lógica de tradução customizada
const customTranslations: Record<string, string> = {
'workflow.editor.save': 'Salvar',
// ...
};
return customTranslations[key] || key;
},
},
}}
>
{/* Componentes */}
</TriglitProvider>import { useI18n } from '@triglit/react-sdk';
function MyCustomComponent() {
const t = useI18n();
return (
<div>
<button>{t('workflow.editor.save')}</button>
<p>{t('workflow.editor.version', { version: 2 })}</p>
</div>
);
}O SDK permite configurar callbacks para eventos importantes:
<TriglitProvider
config={{
apiKey: 'pk_...',
callbacks: {
// Callbacks de workflow version
onWorkflowVersionCreated: (version) => {
console.log('Versão criada:', version);
// Exibir notificação, atualizar cache, etc.
},
onWorkflowVersionCreateError: (error) => {
console.error('Erro ao criar versão:', error);
// Exibir erro ao usuário
},
onWorkflowVersionUpdated: (version) => {
console.log('Versão atualizada:', version);
},
onWorkflowVersionUpdateError: (error) => {
console.error('Erro ao atualizar versão:', error);
},
onWorkflowVersionPublished: (response) => {
console.log('Versão publicada:', response);
},
onWorkflowVersionPublishError: (error) => {
console.error('Erro ao publicar versão:', error);
},
// Callbacks de triggers
onTriggerCreated: (trigger) => {
console.log('Trigger criado:', trigger);
},
onTriggerCreateError: (error) => {
console.error('Erro ao criar trigger:', error);
},
onTriggerUpdated: (trigger) => {
console.log('Trigger atualizado:', trigger);
},
onTriggerUpdateError: (error) => {
console.error('Erro ao atualizar trigger:', error);
},
onTriggerDeleted: () => {
console.log('Trigger deletado');
},
onTriggerDeleteError: (error) => {
console.error('Erro ao deletar trigger:', error);
},
// Callbacks de workflows
onWorkflowCreated: (workflow) => {
console.log('Workflow criado:', workflow);
},
onWorkflowCreateError: (error) => {
console.error('Erro ao criar workflow:', error);
},
},
}}
>
{/* Componentes */}
</TriglitProvider>Use callbacks para integrar com sistemas de notificação, logging, analytics ou atualizar estado global da aplicação.
O SDK suporta modo escuro automaticamente. O provider adiciona a classe dark ao elemento raiz:
// O modo escuro é aplicado automaticamente
<TriglitProvider config={{ apiKey: 'pk_...' }}>
{/* Componentes em modo escuro */}
</TriglitProvider>Para usar modo claro, você pode sobrescrever as classes:
<TriglitProvider config={{ apiKey: 'pk_...' }}>
<div className="triglit-root"> {/* Remove a classe dark */}
<WorkflowEditor workflowId="wf_123" />
</div>
</TriglitProvider>Os componentes usam classes CSS com prefixo tg: para evitar conflitos. Você pode customizar os estilos usando CSS:
/* Customizar cores do editor */
.triglit-root {
--tg-primary: #your-color;
--tg-secondary: #your-color;
}O SDK usa React Query internamente. Você pode acessar o QueryClient para configurações avançadas:
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { TriglitProvider } from '@triglit/react-sdk';
const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: 3,
staleTime: 5 * 60 * 1000, // 5 minutos
},
},
});
function App() {
return (
<QueryClientProvider client={queryClient}>
<TriglitProvider config={{ apiKey: 'pk_...' }}>
{/* Sua aplicação */}
</TriglitProvider>
</QueryClientProvider>
);
}Para usar o SDK com Next.js App Router:
// app/workflows/[id]/page.tsx
'use client';
import { TriglitProvider, WorkflowEditor } from '@triglit/react-sdk';
import '@triglit/react-sdk/styles.css';
export default function WorkflowPage({ params }: { params: { id: string } }) {
return (
<TriglitProvider
config={{
apiKey: process.env.NEXT_PUBLIC_TRIGLIT_PUBLISHABLE_KEY!,
}}
>
<WorkflowEditor workflowId={params.id} />
</TriglitProvider>
);
}Você pode construir sua própria UI usando apenas os hooks:
import {
TriglitProvider,
useWorkflow,
useWorkflowVersions,
useWorkflowVersion,
useTriggers,
} from '@triglit/react-sdk';
function CustomWorkflowUI({ workflowId }: { workflowId: string }) {
const { workflow, isLoading: workflowLoading } = useWorkflow(workflowId);
const { data: versions } = useWorkflowVersions({ workflowId });
const currentVersionId = versions?.data?.[0]?.id;
const { version } = useWorkflowVersion(currentVersionId || '', {
enabled: !!currentVersionId,
});
const { data: triggersData } = useTriggers({
workflowVersionId: currentVersionId,
});
if (workflowLoading) return <div>Carregando...</div>;
return (
<div>
<h1>{workflow?.name}</h1>
<div>
<h2>Versões</h2>
{versions?.data?.map((v) => (
<div key={v.id}>Versão {v.version}</div>
))}
</div>
<div>
<h2>Triggers</h2>
{triggersData?.triggers?.map((trigger) => (
<div key={trigger.id}>{trigger.type}</div>
))}
</div>
</div>
);
}
function App() {
return (
<TriglitProvider config={{ apiKey: 'pk_...' }}>
<CustomWorkflowUI workflowId="wf_123" />
</TriglitProvider>
);
}O SDK também exporta utilitários úteis:
import {
convertTriggerConfigToApi,
getTriggerConfigSchemas,
hasCycle,
validateEdges,
validateNode,
} from '@triglit/react-sdk';
// Converter configuração de trigger para formato da API
const apiConfig = convertTriggerConfigToApi('trigger_webhook', visualConfig);
// Obter schemas de configuração de triggers
const schemas = getTriggerConfigSchemas();
// Validar workflow
const isValid = !hasCycle(nodes, edges);
const validEdges = validateEdges(edges, nodes);
const validNode = validateNode(node);import { TriglitProvider, WorkflowEditor } from '@triglit/react-sdk';
import '@triglit/react-sdk/styles.css';
function App() {
return (
<TriglitProvider config={{ apiKey: 'pk_...' }}>
<div className="h-screen">
<WorkflowEditor
workflowId="wf_123"
onSave={(versionId) => {
alert(`Versão ${versionId} salva com sucesso!`);
}}
/>
</div>
</TriglitProvider>
);
}import {
TriglitProvider,
WorkflowEditor,
} from '@triglit/react-sdk';
import '@triglit/react-sdk/styles.css';
import { toast } from 'sonner'; // ou sua biblioteca de toast
function App() {
return (
<TriglitProvider
config={{
apiKey: 'pk_...',
i18n: {
locale: 'pt-BR',
},
callbacks: {
onWorkflowVersionCreated: (version) => {
toast.success('Versão criada com sucesso!');
},
onWorkflowVersionPublished: () => {
toast.success('Versão publicada!');
},
onWorkflowVersionCreateError: (error) => {
toast.error(`Erro: ${error.message}`);
},
},
}}
>
<WorkflowEditor workflowId="wf_123" />
</TriglitProvider>
);
}Certifique-se de importar o CSS:
import '@triglit/react-sdk/styles.css';Verifique se a chave de API está correta e se está usando o tipo correto (pk_ para frontend, sk_ para backend).
Certifique-se de que o TriglitProvider envolve todos os componentes do SDK.
O SDK é totalmente tipado. Se você encontrar erros de tipo, verifique se está usando a versão mais recente:
npm update @triglit/react-sdkSe você receber o erro "useTriglit must be used within a TriglitProvider", certifique-se de que o componente está dentro do TriglitProvider.
Para mais informações, consulte a documentação oficial do Triglit.
MIT
João Pedro contato@triglit.com