npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@torredeveloper-br/torresign

v1.0.0-beta.3

Published

Editor visual de documentos A4 para React — biblioteca de componentes TorreDeveloper

Readme

TorreSign UI

Editor visual de documentos A4 para React

versão licença react

TorreSign UI é uma biblioteca React que entrega um editor visual completo para criação de documentos no formato A4. Incorpore o componente na sua aplicação e ofereça ao usuário final a capacidade de montar layouts de documentos livremente, sem precisar construir essa infraestrutura do zero.

A biblioteca é agnóstica ao domínio — pode ser usada para certificados, laudos técnicos, declarações, contratos, diplomas, relatórios ou qualquer documento formal que exija identidade visual personalizada.


Sumário


Instalação

npm install @torredeveloper-br/torresign

Requisitos:

  • React >= 18.0.0
  • react-dom >= 18.0.0

Uso básico

import { ModeloEditor } from '@torredeveloper-br/torresign'
import '@torredeveloper-br/torresign/dist/torresign.css'

export default function App() {
  return (
    <div style={{ position: 'fixed', inset: 0 }}>
      <ModeloEditor
        onSalvar={(modelo) => console.log('modelo salvo:', modelo)}
        onVoltar={() => console.log('voltou')}
      />
    </div>
  )
}

Props

| Prop | Tipo | Obrigatório | Descrição | |---|---|---|---| | modeloInicial | object | Não | Modelo JSON para edição de documento existente | | onSalvar | function | Não | Callback chamado ao salvar — recebe o modelo completo | | onVoltar | function | Não | Callback chamado ao clicar em Voltar | | onUploadBackground | function | Não | Callback para upload de imagem de fundo — deve retornar a URL | | onListarBackgrounds | function | Não | Callback para listar backgrounds disponíveis — deve retornar array [{ path, url, nome }] | | onSelecionarBackground | function | Não | Callback chamado ao selecionar um background da biblioteca | | backgrounds | array | Não | Lista inicial de backgrounds [{ path, url, nome }] | | logoUrl | string | Não | URL da imagem de logo exibida no header do documento | | PreviewComponent | component | Não | Componente React customizado para o preview | | previewData | object | Não | Dados para preencher o preview — chave: id do campo, valor: dado | | tema | object | Não | Objeto de cores para personalização visual da interface |


Elementos disponíveis

Campos de entrada

| Elemento | Tipo | Descrição | |---|---|---| | Texto | TEXTO | Título (subtipo: 'titulo') ou campo de entrada (subtipo: 'input') | | Número | NUMERO | Campo numérico | | Data | DATA | Campo de data com formato configurável | | Lista | SELECT | Campo de seleção com opções customizáveis | | Imagem | IMAGEM | Upload e posicionamento livre de imagem |

Autenticidade

| Elemento | Tipo | Descrição | |---|---|---| | QR Code | QR_CODE | QR Code gerado automaticamente | | Assinatura | ASSINATURA | Campo para imagem de assinatura manuscrita ou selo digital |

Elementos gráficos

| Elemento | Tipo | Descrição | |---|---|---| | Linha | LINHA | Linha separadora horizontal, vertical ou diagonal | | Retângulo | RETANGULO | Elemento visual de destaque com borda configurável |


Formato do modelo JSON

O modelo retornado pelo onSalvar segue esta estrutura:

{
  "id": "abc123",
  "nome": "Meu Modelo",
  "orientacao": "retrato",
  "A4_WIDTH": 210,
  "A4_HEIGHT": 297,
  "background_url": null,
  "background_ativo": false,
  "header": {
    "nome_empresa": "Minha Empresa",
    "subtitulo": "Subtítulo",
    "cor_inicio": "#ffffff",
    "cor_fim": "#cccccc",
    "opacidade": 0.6,
    "mostrar_logo": true,
    "mostrar_nome": true,
    "mostrar_subtitulo": true,
    "logo_alinhamento": "esquerda",
    "nome_alinhamento": "esquerda",
    "subtitulo_alinhamento": "esquerda",
    "nome_tamanho": 14,
    "subtitulo_tamanho": 11,
    "nome_fonte": "serif",
    "subtitulo_fonte": "serif",
    "nome_cor": "#333333",
    "subtitulo_cor": "#333333"
  },
  "campos": [
    {
      "id": "campo-nome",
      "tipo": "TEXTO",
      "subtipo": "input",
      "nome": "Nome Completo",
      "x": 40,
      "y": 120,
      "width": 300,
      "height": 40,
      "obrigatorio": true,
      "deletavel": false,
      "coluna": 1,
      "tamanhoFonte": 11,
      "fonteFamilia": "'Montserrat', sans-serif",
      "corTexto": "#2d2d2d",
      "placeholder": "Digite o nome..."
    }
  ]
}

Atributos de campo

| Atributo | Tipo | Descrição | |---|---|---| | id | string | Identificador único do campo | | tipo | string | Tipo do campo — ver tabela de elementos | | subtipo | string | Para TEXTO: 'input' ou 'titulo' | | nome | string | Rótulo exibido no documento | | x | number | Posição horizontal em pixels no canvas | | y | number | Posição vertical em pixels no canvas | | width | number | Largura em pixels | | height | number | Altura em pixels | | obrigatorio | boolean | Indica se o campo é obrigatório no preenchimento | | deletavel | boolean | Indica se o campo pode ser deletado pelo usuário no editor | | coluna | number | Número da coluna de reflow — campos com a mesma coluna se alinham verticalmente | | grupoLinha | string | ID do grupo — campos do mesmo grupo se alinham horizontalmente | | tamanhoFonte | number | Tamanho da fonte em pixels | | fonteFamilia | string | Família da fonte CSS | | corTexto | string | Cor do texto em hex | | placeholder | string | Texto de exemplo exibido no preview |


Callbacks

onSalvar(modelo)

Chamado ao clicar em Salvar ou via atalho Ctrl+S. Recebe o modelo JSON completo.

<ModeloEditor
  onSalvar={(modelo) => {
    // salvar no seu banco de dados
    await api.salvarModelo(modelo)
  }}
/>

onUploadBackground(arquivo)

Chamado ao fazer upload de uma imagem de fundo. Deve retornar a URL da imagem após o upload.

<ModeloEditor
  onUploadBackground={async (arquivo) => {
    const url = await storage.upload(arquivo)
    return url
  }}
/>

onListarBackgrounds()

Chamado ao atualizar a biblioteca de backgrounds. Deve retornar um array de objetos.

<ModeloEditor
  onListarBackgrounds={async () => {
    const lista = await storage.listar('backgrounds/')
    return lista.map(item => ({
      path: item.path,
      url: item.url,
      nome: item.nome
    }))
  }}
/>

Tema

Personalize as cores da interface passando um objeto tema:

const meuTema = {
  primaria: '#6b4b6e',
  secundaria: '#5a6844',
  clara: '#f0ede8',
  borda: '#e0ddd8',
  fundo: '#f5f3ef'
}

<ModeloEditor tema={meuTema} />

Preview customizado

Por padrão o TorreSign UI exibe um preview interno do modelo. Para substituir por um componente próprio — por exemplo o componente de emissão real da sua aplicação — passe a prop PreviewComponent:

import MeuPreview from './MeuPreview'

<ModeloEditor
  PreviewComponent={MeuPreview}
  previewData={{
    'campo-nome': 'João da Silva',
    'campo-data': '01/03/2025'
  }}
/>

O PreviewComponent recebe as seguintes props:

| Prop | Tipo | Descrição | |---|---|---| | modelo | object | Modelo JSON completo | | dadosCertificado | object | Dados para preencher os campos | | numeroCertificado | string | Número de registro do documento |


Atalhos de teclado

| Atalho | Ação | |---|---| | Ctrl+S | Salvar modelo | | Ctrl+C | Copiar campo selecionado | | Ctrl+V | Colar campo | | Ctrl+D | Duplicar campo selecionado | | Ctrl+Z | Desfazer última ação | | Delete | Deletar campo selecionado |


O que a biblioteca não faz

O TorreSign UI é exclusivamente o editor visual. As responsabilidades abaixo pertencem à aplicação integradora:

  • Persistência do modelo — salvar e carregar do banco de dados
  • Upload e armazenamento de imagens e backgrounds
  • Geração de PDF a partir do modelo
  • Emissão de documentos e controle de numeração
  • Autenticação e controle de acesso
  • QR Code de validação e consulta pública

Licença

Este projeto é licenciado sob a Business Source License 1.1.

Uso livre para projetos pessoais e open source sem fins lucrativos. Para uso comercial, adquira uma licença em torredeveloper.dev ou entre em contato pelo e-mail [email protected].


TorreDeveloper · Wander Lucio Torre Chagas