O plug-in Markdown nativo e de alto desempenho para JavaScript
Última atualização:
Plugin de editor de texto Markdown que transforma uma área de texto nativa em um conjunto completo de edição - sem necessidade de sincronização. Modos WYSIWYG e Markdown simples, visualização ao vivo, localização e substituição, suporte RTL, modo escuro. Funciona com Django, Laravel, Rails, Node.js, PHP e qualquer pilha.
A Filosofia: "Nativo Primeiro"
A maioria dos editores quebra o fluxo de trabalho padrão da web. MarkdownEditor adota isso.
Como ele fica diretamente em cima de uma <textarea>, você não precisa aprender uma nova maneira de lidar com dados.
- Não é necessária vinculação de dados: funciona com
<form method="POST">pronto para uso - Acesso padrão: Use
document.getElementById('editor').valuecomo uma entrada normal. - Backend Agnóstico: Funciona com qualquer backend (Python, Node.js, PHP, etc.) como um campo de formulário normal
MarkdownEditor vs EasyMDE/SimpleMDE
A maioria dos editores de markdown JavaScript - EasyMDE, SimpleMDE, editores baseados em CodeMirror - substituem seu <textarea> por um elemento personalizado. Isso significa que o envio do formulário é interrompido, .value não retorna nada e você precisa escrever código extra apenas para ler o conteúdo novamente. MarkdownEditor é diferente do — ele aprimora sua área de texto existente e nunca a substitui.
| Recurso | Editor Markdown | EasyMDE/SimpleMDE |
|---|---|---|
| Textarea nativa preservada | ✅ | ❌ Substituído |
| O envio do formulário funciona como está | ✅ | ❌ Requer JS extra |
Obter/definir valor via .value |
✅ | ❌ API personalizada necessária |
| Modo híbrido WYSIWYG | ✅ | ❌ |
| Localizar e substituir integrado | ✅ | ❌ |
| Suporte RTL | ✅ | ❌ |
| Compatível com CSP (sem JS embutido) | ✅ | ❌ |
| Zero conflitos de CSS | ✅ | ❌ |
| Modo escuro / tema | ✅ | Limitado |
| Tamanho do pacote | ~116 KB | ~ 300 KB + |
Integração de Estrutura
Como MarkdownEditor preserva o <textarea> nativo, ele se integra a todas as estruturas de back-end sem nenhum código extra. Seu servidor recebe o conteúdo do markdown exatamente como receberia de qualquer campo de formulário padrão.
Django
Adicione um class ao seu widget textarea e inicialize o editor - request.POST['content'] funciona sem etapas extras.
1 2 3 4 5 6 7 8 | # forms.py class PostForm(forms.ModelForm): class Meta: model = Post fields = ['content'] widgets = { 'content': forms.Textarea(attrs={'class': 'markdown-editor'}), } |
1 2 | new MarkdownEditor('.markdown-editor'); // request.POST['content'] contains the markdown on submit |
Laravel
Use f.text_area com uma classe - $request->input('content') recebe a redução diretamente.
1 2 | <textarea name="content" class="markdown-editor">{{ old('content') }}</textarea> <script>new MarkdownEditor('.markdown-editor');</script> |
Ruby nos trilhos
Funciona com form_with pronto para uso - params[:content] contém a redução. Para Turbo Drive, use turbo:load em vez de DOMContentLoaded.
1 2 3 4 5 6 | document.addEventListener('turbo:load', () => { document.querySelectorAll('.markdown-editor:not([data-mde-init])').forEach(el => { el.setAttribute('data-mde-init', 'true'); new MarkdownEditor(el); }); }); |
Node.js/Expresso
req.body.content recebe a redução no envio do formulário - sem etapa de sincronização, sem extração personalizada.
1 2 3 | <textarea name="content" class="markdown-editor"></textarea> <script src="https://cdn.jsdelivr.net/npm/markdown-text-editor"></script> <script>new MarkdownEditor('.markdown-editor');</script> |
PHP
$_POST['content'] funciona exatamente como qualquer área de texto padrão - insira-o e o manuseio do formulário existente não requer nenhuma alteração.
1 2 3 4 5 6 | <form method="POST" action="save.php"> <textarea name="content" class="markdown-editor"></textarea> <button type="submit">Save</button> </form> <script src="https://cdn.jsdelivr.net/npm/markdown-text-editor"></script> <script>new MarkdownEditor('.markdown-editor');</script> |
Principais recursos
🖼️ Upload avançado de imagens (otimizado para SEO)
Não sobrecarregue seu banco de dados com strings Base64 pesadas. Configure nossa API para fazer upload de imagens diretamente para seu servidor ou bucket S3. O editor recebe a URL, mantendo seus arquivos Markdown leves e a classificação SEO do seu site alta.
🔀 Modos Híbrido e Simples
Dê aos seus usuários o melhor dos dois mundos. Alterne entre um modo Híbrido Visual (WYSIWYG) para facilitar a formatação e um modo Plain Markdown para edição de sintaxe bruta e sem distrações.
🌍 Global-Ready com suporte RTL
Suporte nativo completo para idiomas da direita para a esquerda (RTL). Perfeito para projetos que exigem suporte para árabe, urdu ou farsi com alinhamento automático da direção do texto.
⚡ Desempenho em escala
- Leve: ocupa um espaço minúsculo de aproximadamente 116 KB que não retarda o carregamento da página
- Suporte para documentos grandes: otimizado para lidar com milhares de linhas de texto sem atraso de entrada ou congelamento do navegador
- Renderização inteligente: atualizações de visualização eliminadas, cálculos de estilo em cache e manipulação de teclado sem conflitos entre continuação e recuo de lista - então Tab e Enter sempre fazem exatamente uma coisa
♿ Acessível por padrão
O suporte ARIA completo está integrado e não requer configuração extra. A barra de ferramentas é um marco role="toolbar" adequado, o painel de visualização é rotulado como role="region", todos os ícones SVG estão ocultos dos leitores de tela, a alternância de visualização expõe seu estado ligado/desligado via aria-pressed e os botões da barra de ferramentas desabilitados usam disabled e aria-disabled para que a tecnologia assistiva nunca seja enganada. Os modais retornam o foco para o botão de disparo quando fechados.
🛡️ Zero conflitos de CSS
Todos os estilos de editor têm escopo total para o elemento .markdown-editor-wrapper. A simulação global do Tailwind (redefinições de elemento para h1 – h6, a, button, etc.) é excluída, para que o editor possa conviver com Bootstrap, Tailwind ou qualquer outra estrutura CSS na mesma página sem quebrar um único estilo.
🔒 Visualização segura do XSS
A visualização renderizada é higienizada por meio de DOMPurify antes de ser gravada no DOM. Tags de script, manipuladores de eventos in-line e URLs maliciosos em entradas de markdown criadas são removidos automaticamente – sem necessidade de configuração.
Demonstração do Editor de Markdown
Implementação Rápida
1. Instalação
NPM (pacotes: Vite, webpack, Rollup, etc.)
npm install markdown-text-editor |
1 2 | import MarkdownEditor from 'markdown-text-editor'; new MarkdownEditor('#markdown-editor'); |
CDN: módulo ES
1 2 3 4 | <script type="module"> import MarkdownEditor from 'https://cdn.jsdelivr.net/npm/markdown-text-editor/dist/markdown-text-editor.es.js'; new MarkdownEditor('#markdown-editor'); </script> |
CDN: etiqueta de script global (IIFE)
Nenhuma importação necessária – MarkdownEditor está disponível automaticamente como uma variável global.
1 2 3 4 5 6 7 8 9 | <form action="/api/save" method="POST"> <textarea id="markdown-editor" name="content"># Hello World</textarea> <button type="submit">Save Content</button> </form> <script src="https://cdn.jsdelivr.net/npm/markdown-text-editor"></script> <script> new MarkdownEditor('#markdown-editor'); </script> |
2. Configuração e inicialização
Passe um objeto de opções para personalizar o editor. Todas as opções são opcionais — omita qualquer uma para usar o valor padrão.
1 2 3 4 | const editor = new MarkdownEditor('#markdown-editor', { placeholder: 'Write your markdown...', toolbar: ['heading', 'bold', 'italic', 'strikethrough', 'ul', 'ol', 'checklist', 'blockquote', 'link', 'preview'], }); |
Gostando do Editor Markdown?
Demora 2 segundos e ajuda o projeto a crescer. Faz parte do Frutjam, uma biblioteca gratuita de componentes CSS do Tailwind – uma estrela também ajuda.
4. Configuração e personalização
Você pode personalizar totalmente o comportamento e a interface do editor passando um objeto options. Se você omitir uma opção, o valor padrão será usado.
| Propriedade | Tipo | Padrão | Propósito |
|---|---|---|---|
mode |
string |
'plain' |
Define a visualização inicial. Use híbrido para uma experiência WYSIWYG ou simples para sintaxe bruta. |
placeholder |
string |
'Write...' |
Texto mostrado quando o editor está vazio. |
toolbar |
array |
[...] |
Define quais ferramentas aparecem e em que ordem. |
footer |
false | object |
tudo visível | Controla a barra de status mostrada abaixo do editor. Defina como false para ocultá-lo completamente ou passe um objeto para alternar estatísticas individuais. |
theme |
string |
herdado | Define explicitamente o tema do editor (claro, escuro, snowberry, darkberry). Se omitido, o editor herda data-theme do elemento ancestral mais próximo ou do próprio <textarea>. |
minHeight |
number |
200 |
Altura mínima em pixels para a qual o editor diminuirá quando o conteúdo for curto. Pareia com maxHeight para definir o intervalo de crescimento automático. |
maxHeight |
number |
500 |
Altura máxima em pixels que o editor pode atingir fora do modo de tela cheia. Quando o conteúdo exceder essa altura, uma barra de rolagem aparecerá dentro do editor. O editor também possui uma alça de arrastar para que os usuários possam redimensioná-lo manualmente além desse limite. |
onChange |
function |
undefined |
Retorno de chamada disparado em cada alteração de conteúdo – digitação, ações na barra de ferramentas, desfazer/refazer e continuação de lista. Recebe a string de redução atual como seu único argumento. |
🛠 Personalização da barra de ferramentas
A barra de ferramentas é modular. Você pode criar uma experiência mínima ou um conjunto de recursos completo modificando o array.
Ferramentas disponíveis
| Categoria | Chaves de ferramentas |
|---|---|
| Tipografia | heading, bold, italic, strikethrough, blockquote |
| Listas | ul (bala), ol (numerado), checklist |
| Código | code (em linha), codeblock (bloco cercado) |
| Inserções | hr (regra horizontal), table (modelo de tabela) |
| Mídia | link, image |
| Edição | undo, redo, indent, outdent |
| Visualizar | preview |
💡 Dicas de implementação:
- Reordenação: os botões aparecem na ordem exata em que você os listou na matriz
- Removendo: basta omitir qualquer chave (como
image) do array para desabilitar totalmente esse recurso para o usuário - Fallback nativo: se você não fornecer um
placeholderem JS, o plug-in usará automaticamente o atributoplaceholderdo seu HTML<textarea>
📊 Rodapé (barra de status)
O rodapé fica abaixo do editor e mostra line, column do cursor, a contagem de caracteres do documento e, opcionalmente, a contagem de palavras - todos atualizados em tempo real. É visível por padrão e cada estatística pode ser alternada de forma independente.
| Chave | Tipo | Padrão | Descrição |
|---|---|---|---|
line |
boolean |
true |
Mostra o número da linha atual. |
col |
boolean |
true |
Mostrar o número da coluna atual. |
chars |
boolean |
true |
Mostrar a contagem total de caracteres. |
words |
boolean |
false |
Mostre a contagem total de palavras. Desativado por padrão — defina como true para ativar. |
Exemplos de uso
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | // Default — line, col, and chars visible new MarkdownEditor('#editor'); // Disable the footer entirely new MarkdownEditor('#editor', { footer: false }); // Hide only character count new MarkdownEditor('#editor', { footer: { chars: false } }); // Hide line and column, keep character count new MarkdownEditor('#editor', { footer: { line: false, col: false } }); // Show only line number new MarkdownEditor('#editor', { footer: { col: false, chars: false } }); // Enable word count alongside the defaults new MarkdownEditor('#editor', { footer: { words: true } }); // Show word count only new MarkdownEditor('#editor', { footer: { line: false, col: false, chars: false, words: true } }); |
5. Obtendo, configurando e enviando conteúdo
Um dos principais pontos fortes do MarkdownEditor é que ele mantém a <textarea> subjacente perfeitamente sincronizada. Esteja você usando uma estrutura JavaScript moderna ou um backend tradicional como Django, PHP ou Laravel, o fluxo de trabalho permanece simples e nativo.
1. O jeito nativo (recomendado)
Como o editor aprimora uma área de texto padrão, você pode usar métodos DOM familiares. Esta é a maneira mais rápida de interagir com seus dados sem aprender uma nova API.
1 2 3 4 5 | // Retrieve content via ID const markdown = document.getElementById('markdown-editor').value; // Set content via ID (The editor UI updates automatically) document.getElementById('markdown-editor').value = "# New Heading Content"; |
2. Usando uma referência de variável
Se você tiver uma referência ao elemento textarea, poderá usá-lo diretamente - não é necessária nenhuma API específica da biblioteca.
1 2 3 4 5 6 7 | const textarea = document.getElementById('markdown-editor'); // Retrieve content const markdown = textarea.value; // Set content (the editor UI reflects this immediately) textarea.value = "## Updated via JS"; |
3. Configuração e leitura de conteúdo
A maneira recomendada de definir o conteúdo inicial é diretamente no HTML <textarea> — isso funciona naturalmente com todos os frameworks backend (Django, Laravel, Rails, PHP, etc.) e o editor o renderiza automaticamente no init.
1 2 | <!-- Recommended: set content server-side --> <textarea id="markdown-editor"># Hello World</textarea> |
Para ler ou atualizar conteúdo em tempo de execução, use o valor nativo textarea. Chame editor.render() após uma atualização para atualizar a visualização e a camada híbrida.
1 2 3 4 5 6 7 8 | const textarea = document.getElementById('markdown-editor'); // Read const markdown = textarea.value; // Update at runtime textarea.value = '# New content'; editor.render(); |
4. Desmontando o editor — destroy()
Chame editor.destroy() para remover o wrapper DOM do editor e restaurar o <textarea> original para sua posição no documento. Útil em aplicativos de página única ao desmontar uma visualização.
1 2 3 4 | const editor = new MarkdownEditor('#markdown-editor'); // Remove the editor and restore the plain textarea editor.destroy(); |
Reagindo às mudanças com onChange
Passe um retorno de chamada onChange para ser notificado sobre cada alteração de conteúdo. Recebe a string de redução atual.
1 2 3 4 5 | const editor = new MarkdownEditor('#markdown-editor', { onChange(value) { console.log('Content changed:', value.length, 'characters'); } }); |
Rascunho de salvamento automático com localStorage
Use onChange para salvar um rascunho a cada pressionamento de tecla. Restaure-o preenchendo previamente a área de texto antes de inicializar o editor.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | const DRAFT_KEY = 'my-page-draft'; // Restore saved draft before init (only if textarea starts empty) const textarea = document.getElementById('markdown-editor'); const saved = localStorage.getItem(DRAFT_KEY); if (saved && !textarea.value) textarea.value = saved; // Save on every change const editor = new MarkdownEditor('#markdown-editor', { onChange(value) { localStorage.setItem(DRAFT_KEY, value); } }); // Clear draft after successful form submission document.querySelector('form').addEventListener('submit', () => { localStorage.removeItem(DRAFT_KEY); }); |
4. Envio automático de formulário sem esforço
Como o MarkdownEditor é construído diretamente no <textarea> nativo, ele é compatível com todos os frameworks de back-end (Django, Laravel, PHP, Ruby on Rails, etc.) imediatamente.
É aqui que brilha a filosofia “Native-First”. Você não precisa sincronizar os dados manualmente antes de enviar um formulário. O navegador trata o editor exatamente como um campo de entrada padrão.
1 2 3 4 5 6 7 8 9 10 11 12 | <form method="POST" action="/api/submit"> <textarea id="markdown-editor" name="content" class="h-48" rows="5"> # Initial Content </textarea> <button type="submit">Submit to Server</button> </form> <script> // Just initialize it. That's it. new MarkdownEditor('#markdown-editor'); </script> |
Nota: inicialização do plugin MarkdownEditor obrigatória
Basta usar um <form> HTML padrão. O atributo name na textarea é o que seu servidor usará para identificar o conteúdo.
🚀 Por que é uma virada de jogo para back-ends
Como o editor preserva o comportamento nativo do <textarea>, seu servidor trata os dados como uma string padrão. Não há necessidade de nenhuma lógica extra - nenhuma preventDefault() e nenhuma construção manual de FormData.
💡 Por que este é um "recurso matador":
A maioria dos editores (como Quill, Editor.js, simpleMDE, easyMDE) salva dados em estruturas JSON complexas. Se um desenvolvedor usar isso, ele terá que reescrever o esquema do banco de dados e a lógica de renderização.
Com o MarkdownEditor, um desenvolvedor pode pegar um site antigo, substituir uma <textarea> simples pelo seu editor, e o backend nem saberá que ele mudou. Ele apenas recebe o mesmo texto bruto de sempre, mas o usuário obtém uma experiência 10 vezes melhor.
| Estrutura / Linguagem | Como acessar o conteúdo do Markdown |
|---|---|
| PHP | $_POST['content'] |
| Django | request.POST.get('content') |
| Node.js (Express) | req.body.content |
| Laravel | $request->input('content') |
| Ruby on Rails | params[:content] |
Opções de configuração
🖼️ Upload avançado de imagens
Lidar com uploads de imagens nativamente - em vez de depender de strings Base64 lentas e com muita memória - é uma vitória significativa tanto para o desempenho quanto para o SEO.
Opções de configuração
A ferramenta de imagem suporta uma configuração fileInput para lidar com uploads diretos do servidor.
accept: Defina uma matriz de formatos de imagem permitidos (por exemplo, 'webp', 'avif')uploadUrl: Especifique o endpoint de backend para onde o objetoArquivoserá enviado viaPOSTparams: objeto opcional para enviar dados adicionais (como tokens CSRF, IDs de usuário ou nomes de pastas) junto com o arquivo de imagem
Exemplo de uso (configuração completa)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | const options = { placeholder: 'Start writing...', toolbar: [ 'link', { image: { fileInput: { accept: ['webp', 'avif'], // restrict the image upload format uploadUrl: '/api/upload', // Your upload endpoint params: { _token: 'your_csrf_token_here', // Essential for Laravel/Django folder: 'blog_posts' } }, // Supports boolean: true/false OR object: { required: true } altInput: { required: true } } }, 'preview' ], } const editor = new MarkdownEditor('#markdown-editor', options); |
📡 Detalhes de integração do servidor
1. O Pedido
O editor envia uma solicitação POST como multipart/form-data. Por padrão, inclui:
image_file: o objeto de arquivo realimage_alt: o texto alternativo inserido pelo usuário- ... além de quaisquer dados personalizados definidos no objeto
params
2. A resposta necessária
Para confirmar o sucesso do upload e inserir a imagem no editor, seu servidor deve retornar a seguinte estrutura JSON:
1 2 3 4 | { "success": true, "image_path": "https://cdn.yourdomain.com/uploads/image.webp" } |
Observação: certifique-se de usar a chave image_path para o URL da imagem enviada.
Validação de texto alternativo de imagem (altInput)
Para garantir que seu conteúdo permaneça acessível e otimizado para SEO, MarkdownEditor impõe a validação de texto alternativo por padrão. Você pode configurar esse comportamento usando uma abreviação booleana ou um objeto detalhado.
- Comportamento padrão: se
altInputnão estiver definido, o padrão é{ require: true } - Aplicar acessibilidade: os usuários serão impedidos de inserir uma imagem até que uma descrição alternativa seja fornecida
Exemplos de configuração:
1. Padrão (nenhuma configuração necessária)
1 2 3 4 | // Alt text is REQUIRED by default image: { fileInput: { uploadUrl: '/api/upload' } } |
2. Abreviação (desativar validação)
Se você quiser permitir imagens sem descrições, basta definir o booleano como false.
1 2 3 | image: { altInput: false // Users can now skip the alt text field } |
3. Baseado em objetos (explícito)
1 2 3 4 5 | image: { altInput: { required: false // Disables alt text validation — users can skip the alt field } } |
Uso de imagem padrão (sem fileInput):
Se fileInput não estiver configurado, o editor usará como padrão um modal simples baseado em URL. Isso é ideal se seus usuários estiverem vinculando principalmente a hosts de imagens externos.
1 2 3 4 5 6 7 8 | const options = { toolbar: [ 'link', 'image', 'preview' ], } const editor = new MarkdownEditor('#markdown-editor', options); |
💡 Por que usar parâmetros?
Em frameworks como Laravel ou Django, você não pode fazer upload de arquivos sem um token CSRF. Ao adicionar _token ao objeto params, sua solicitação passará perfeitamente pelo middleware de segurança do backend, mantendo a filosofia "Zero Logic" para seus controladores do lado do servidor.
🔀 Modos de edição
MarkdownEditor oferece duas maneiras distintas de escrever e formatar seu conteúdo. Você pode alternar entre uma visualização tradicional focada na sintaxe ou uma experiência moderna com foco no visual.
Configuração
Você pode definir o modo de inicialização usando a propriedade mode durante a inicialização.
plain(Padrão): um ambiente Markdown limpo e de alto desempenho onde a sintaxe (como**bold**ou# header) é visível. Ideal para desenvolvedores e puristas do Markdownhíbrido: uma experiência inspirada em WYSIWYG que renderiza a formatação (negrito, itálico, títulos) em tempo real enquanto você digita, mantendo a estrutura Markdown subjacente.
Implementação:
1 2 3 4 5 6 7 8 9 10 11 12 | // Default initialization (Plain Mode) new MarkdownEditor('#markdown-editor'); // Explicit Plain Mode new MarkdownEditor('#markdown-editor', { mode: 'plain' }); // Hybrid (Visual) Mode new MarkdownEditor('#markdown-editor', { mode: 'hybrid' }); |
Visualização do modo híbrido e simples:
Modo Híbrido
A formatação visual é renderizada em tempo real enquanto você digita.
Modo Simples (Padrão)
Concentra-se na sintaxe bruta do Markdown para uma experiência leve.
| Configuração | Propriedade/Ferramenta | Descrição |
|---|---|---|
| Objeto de opções | placeholder |
Define o texto do espaço reservado para a área de texto (opcional, pois você também pode usar o atributo textarea HTML padrão) |
mode: 'hybrid' |
Permite uma experiência inspirada em WYSIWYG que renderiza a formatação (negrito, itálico, títulos) em tempo real enquanto você digita | |
barra de ferramentas: determina quais ferramentasaparecem na barra de ferramentas e sua ordem. |
heading |
Abre um menu suspenso para selecionar o nível de título H1–H6 |
bold |
Ativa a formatação de texto em negrito. | |
italic |
Ativa a formatação de texto em itálico. | |
strikethrough |
Permite tachado de texto. | |
ol |
(Lista ordenada): Converte texto em formato de lista numerada. | |
ul |
(Lista não ordenada): converte o texto em uma lista com marcadores. | |
checklist |
Adiciona caixas de seleção ao seu texto, tornando-o excelente para tarefas, listas de tarefas ou acompanhamento do status de conclusão. | |
blockquote |
Destaque o texto citado ou enfatizado. | |
code |
Quebra o texto selecionado em crases únicos para código embutido. Clicar novamente remove os crases. | |
codeblock |
Quebra o texto selecionado em um bloco de código protegido com crase triplo. Clicar novamente remove as cercas. | |
hr |
Insere uma regra horizontal --- na posição do cursor em sua própria linha. |
|
table |
Insere um modelo inicial de tabela de descontos 2x3 na posição do cursor. | |
image |
Permite inserir imagens via sintaxe de markdown. | |
link |
Permite adicionar hiperlinks ao seu texto. | |
undo |
Para reverter as últimas alterações. | |
redo |
Para reaplicar as últimas alterações desfeitas. | |
indent |
Para aumentar o nível de recuo. | |
outdent |
Para diminuir o nível de recuo. | |
preview |
Alterna uma visualização lado a lado em tela cheia. As caixas de seleção no painel de visualização são clicáveis e atualizam a fonte de redução instantaneamente. Pressione Escape para sair da tela cheia. | |
| Recurso avançado de upload de imagens: permite configurar uploads de imagens para seu próprio servidor e definir o caminho da imagem por meio de uma API. Isso melhora o desempenho e o SEO. |
fileInput |
accept: matriz de tipos de arquivos de imagem permitidos (por exemplo, 'webp', 'avif').uploadUrl: endpoint de back-end para onde o arquivo é enviado via POST.params: objeto opcional para dados extras (tokens CSRF, IDs de usuário, nomes de pastas)
|
altInput |
required: false: Desativa a validação de entrada de texto alternativo (o padrão é verdadeiro) |
⌨️ Atalhos de teclado
Ações comuns de formatação podem ser acionadas diretamente no teclado, sem tocar na barra de ferramentas. Cada atalho também é mostrado na dica de ferramenta do botão da barra de ferramentas correspondente.
| Atalho | Ação |
|---|---|
Ctrl + B / ⌘ B |
Alternar Negrito |
Ctrl + I / ⌘ I |
Alternar Itálico |
Ctrl + K / ⌘ K |
Inserir link |
Ctrl + ` / ⌘ ` |
Alternar Código embutido |
Ctrl + Shift + S / ⌘ ⇧ S |
Alternar |
Ctrl + Z / ⌘ Z |
Desfazer |
Ctrl + Shift + Z / ⌘ ⇧ Z |
Refazer |
Tab |
Recuar linhas selecionadas |
Shift + Tab |
Recuar linhas selecionadas |
Ctrl + F / ⌘ F |
Abra o painel Localizar |
Ctrl + H / ⌘ H |
Abra o painel Localizar e Substituir |
Escape |
Fechar painel Localizar / Sair da visualização em tela cheia |
🔍 Encontre e encontre Substituir
Um painel integrado de localização e substituição está disponível dentro do editor – nenhuma extensão de navegador ou ferramenta separada é necessária.
- Pressione
Ctrl + F(ou⌘ F) para abrir o painel Localizar - Pressione
Ctrl + H(ou⌘ H) para abrir a janela Localizar e localizar. Substituir painel - A pesquisa não diferencia maiúsculas de minúsculas e mostra um contador de correspondências ao vivo (por exemplo, 3 de 12)
- Navegue pelas correspondências com os botões ▲ / ▼ ou
Enter/Shift + Enter - Replace substitui a correspondência realçada atual; Replace All substitui todas as ocorrências de uma só vez
- Pressione
Escapepara fechar o painel e retornar o foco ao editor
O painel flutua no canto superior direito da área de conteúdo do editor e não interrompe a escrita.
🌙 Tema
MarkdownEditor herda automaticamente seu tema da página ao redor – nenhuma configuração é necessária. O editor lê data-theme do ancestral mais próximo na inicialização, para que ele permaneça sincronizado com o tema do seu site imediatamente.
Como o tema é resolvido (ordem de prioridade)
themeopção — substituição explícita passada no objeto de opçõesdata-themeno<textarea>— definido diretamente no elementodata-themeem qualquer ancestral - por ex.<html>,<body>ou um wrapper<div>
Temas disponíveis
'light' (padrão), 'dark', 'snowberry', 'darkberry'
Opção 1 – herdar de <html> ou qualquer ancestral (configuração zero)
1 2 3 4 5 6 | <html data-theme="dark"> ... <textarea id="markdown-editor"></textarea> <script> new MarkdownEditor('#markdown-editor'); // picks up dark automatically </script> |
Opção 2 – definir data-theme diretamente no <textarea>
1 2 3 4 | <textarea id="markdown-editor" data-theme="dark"></textarea> <script> new MarkdownEditor('#markdown-editor'); </script> |
Opção 3 – opção theme explícita (substitui tudo)
1 2 3 | new MarkdownEditor('#markdown-editor', { theme: 'dark' }); |
🎨 Tema personalizado por meio de variáveis CSS
Você pode personalizar totalmente a aparência do editor substituindo suas variáveis CSS no elemento .markdown-editor-wrapper ou em qualquer seletor [data-theme]. Todas as cores usam o espaço de cores OKLCH para obter resultados perceptualmente uniformes.
| Variável | Propósito | Padrão claro | Padrão escuro |
|---|---|---|---|
--color-base |
Plano de fundo do editor | oklch(100% 0 0) |
oklch(10.9% 0 0) |
--color-on-base |
Cor do texto principal | oklch(22% 0 0) |
oklch(98% 0 0) |
--color-primary |
Acento primário (barra de ferramentas ativa, links) | oklch(51.1% .262 277) |
oklch(66.4% .184 286) |
--color-on-primary |
Texto em superfícies de cores primárias | oklch(96.2% .018 272) |
oklch(10% .01 270) |
--color-secondary |
Sotaque secundário | oklch(59.1% .293 323) |
oklch(65% .18 220) |
--color-accent |
Realçar acento (código embutido, itálico) | oklch(54.1% .281 293) |
oklch(75% .18 50) |
--color-neutral |
Superfícies neutras (bordas, divisórias) | oklch(15% 0 0) |
oklch(85% 0 0) |
--color-error |
Cor do estado de erro | oklch(57.7% .245 27) |
oklch(60% .22 30) |
--border-radius |
Arredondamento dos cantos da moldura do editor | 0.25rem |
|
Exemplo de tema personalizado
Substitua qualquer variável em .markdown-editor-wrapper após a inicialização do editor ou defina um bloco [data-theme] personalizado em sua folha de estilo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /* Override individual variables */ .markdown-editor-wrapper { --color-primary: oklch(60% 0.2 30); /* orange accent */ --border-radius: 0.5rem; } /* Or define a full custom theme */ [data-theme="brand"] .markdown-editor-wrapper, .markdown-editor-wrapper[data-theme="brand"] { --color-base: oklch(15% 0.01 250); --color-on-base: oklch(95% 0 0); --color-primary: oklch(65% 0.22 145); /* green */ --color-on-primary: oklch(10% 0 0); --color-accent: oklch(75% 0.18 60); --color-neutral: oklch(80% 0 0); --border-radius: 0.75rem; } |
new MarkdownEditor('#markdown-editor', { theme: 'brand' }); |
- Visualização em tempo real: veja seu markdown renderizado instantaneamente enquanto você digita.
- Destaque de sintaxe: legibilidade aprimorada com código claro e formatação remarcada.
- Fácil integração: integre-se perfeitamente a qualquer projeto web com configuração mínima.
- Barra de ferramentas personalizável: configure e reordene dinamicamente as opções da barra de ferramentas, como negrito, itálico e muito mais.
Características
🔌 Integração de formulário nativo
Funciona exatamente como um <textarea> padrão. Sem APIs complexas – basta usar o atributo value ou name. Ele "simplesmente funciona" com envios de formulários HTML padrão em PHP, Django ou Node.js.
🖼️ Upload avançado de imagens
Configure uploads de servidores nativos via API. Evite strings Base64 pesadas para garantir carregamentos de página mais rápidos e SEO superior hospedando imagens em seu próprio CDN.
🔀 Modos Híbrido e Simples
Alterne entre uma experiência híbrida (WYSIWYG) para edição visual ou o modo Plain Markdown para uma sensação de codificação tradicional.
🚀 Alto desempenho
Um pequeno pacote de ~116 KB otimizado para "Conteúdo Pesado". Lida com documentos e arquivos grandes sem qualquer atraso de entrada ou queda de desempenho.
🌍 Suporte RTL integrado
Suporte nativo para idiomas da direita para a esquerda, como árabe, urdu e farsi. Perfeito para criar aplicativos acessíveis globalmente.
🌙 Tema Adaptativo
Inclui suporte automático ao Modo Escuro. Ele sincroniza com as configurações do sistema ou com a biblioteca Frutjam UI para uma experiência visual perfeita.
📝 Edição Inteligente
Continuação de lista automática no estilo GitHub para listas ordenadas, listas não ordenadas e listas de verificação - pressione Enter e o editor continua o padrão. As caixas de seleção no painel de visualização podem ser clicadas e sincronizadas instantaneamente com a fonte de redução.
📱 Totalmente responsivo
Uma interface de usuário fluida e voltada para dispositivos móveis que se adapta perfeitamente a desktops, tablets e smartphones para edição em qualquer lugar.
📦 Suporte universal
Compatível com ESM, UMD, CommonJS e IIFE. Funciona imediatamente via CDN (<script src>), npm ou qualquer bundler (Vite, webpack, Rollup) — nenhuma configuração extra é necessária.
♿ Acessível por padrão
Suporte ARIA completo integrado - ponto de referência da barra de ferramentas, região de visualização rotulada, botões fáceis de ler na tela, aria-pressionado no botão de visualização, disabled e aria-disabled em ferramentas inativas e restauração correta do foco quando os modais fecham.
🛡️ Zero conflitos de CSS
Os estilos do editor têm escopo total para .markdown-editor-wrapper. A comprovação global do Tailwind é excluída para que o editor viva com segurança ao lado do Bootstrap, Tailwind ou qualquer outra estrutura sem quebrar seus estilos.
⌨️ Atalhos de teclado
Ctrl+B, Ctrl+I, Ctrl+K, Ctrl+`, Ctrl+Shift+S — ações comuns de formatação sem tocar no mouse. Cada atalho é mostrado na dica de ferramenta do botão da barra de ferramentas.
🔍 Encontre e encontre Substituir
Pressione Ctrl+F para localizar ou Ctrl+H para abrir localizar & substituir. Pesquisa sem distinção entre maiúsculas e minúsculas com contador de correspondências ao vivo, navegação seguinte/anterior, substituição única e substituição de todas — sem sair do editor.
Exemplo de configuração completa
Use este exemplo abrangente para inicializar o MarkdownEditor com todos os recursos principais, incluindo ordem personalizada da barra de ferramentas e gerenciamento avançado de upload de imagens.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | const editor = new MarkdownEditor('#markdown-editor', { mode: 'hybrid', placeholder: 'Start writing...', footer: { line: true, col: true, chars: true, words: true, }, onChange(value) { console.log('Content updated:', value.length, 'characters'); }, toolbar: [ 'heading', 'bold', 'italic', 'strikethrough', 'blockquote', 'ul', 'ol', 'checklist', 'code', 'codeblock', 'hr', 'table', { image: { fileInput: { accept: ['webp', 'avif', 'png'], uploadUrl: '/api/upload' } } }, 'link', 'undo', 'redo', 'indent', 'outdent', 'preview' ], }); // Read content natively const markdown = document.getElementById('markdown-editor').value; // Update content programmatically (dispatch input to keep preview in sync) // const ta = document.getElementById('markdown-editor'); // ta.value = '# New content'; // ta.dispatchEvent(new Event('input', { bubbles: true })); // destroy() when the view unmounts (SPAs) // editor.destroy(); |