Ir para o conteúdo principal

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').value como 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.

python
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'}),
        }
javascript
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.

html
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.

javascript
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.

html
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.

html
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 h1h6, 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.)

bash
npm install markdown-text-editor
javascript
1
2
import MarkdownEditor from 'markdown-text-editor';
new MarkdownEditor('#markdown-editor');

CDN: módulo ES

html
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.

html
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.

javascript
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.

Estrela no GitHub

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 placeholder em JS, o plug-in usará automaticamente o atributo placeholder do 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
javascript
 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.

javascript
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.

javascript
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.

html
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.

javascript
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.

javascript
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.

javascript
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.

javascript
 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.

html
 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 objeto Arquivo será enviado via POST
  • params: 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)

javascript
 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 real
  • image_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:

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 altInput nã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)
javascript
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.

javascript
1
2
3
image: {
  altInput: false // Users can now skip the alt text field
}
3. Baseado em objetos (explícito)
javascript
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.

javascript
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 Markdown
  • hí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:
javascript
 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 ferramentas
aparecem 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 Tachado
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 Escape para 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)

  1. theme opção — substituição explícita passada no objeto de opções
  2. data-theme no <textarea> — definido diretamente no elemento
  3. data-theme em 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)
html
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>
html
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)
javascript
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:

css
 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;
}
javascript
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.

javascript
 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();