JSON Editor

Editor inline de JSON com syntax highlight, indentação automática, virtualização para arquivos grandes e validação em tempo real. Zero dependências externas pesadas — feito sobre `<textarea>` + `<pre>` overlay.

Utilização


index.tsx
import { JsonEditor } from "@convertcompany/ui";

Recursos

  • Syntax highlight de chaves, strings, números, booleans, null e pontuação
  • Indentação automática: Tab/Shift+Tab indenta/desindenta seleções inteiras; Enter preserva indent e abre bloco quando vem depois de { ou [
  • Validação contínua com JSON.parse; expõe via onValidityChange(valid, error)
  • Botão de formatar opcional (JSON.parse + stringify com tabSize)
  • Botão de copiar opcional (integrado com CopyToClipboard)
  • Tema custom via prop theme — sobrescreve classes Tailwind por tipo de token
  • Virtualização: renderiza só as linhas visíveis (~50 por vez). Funciona com arquivos de 1k+ linhas sem travar
  • useDeferredValue: textarea responde imediato; highlight/validação são reagendados pra idle

Exemplos


Com botão de copiar

Read-only (visualização)

Modo somente leitura — esconde o botão de formatar, mantém copy.

Sem line numbers / sem botão de formatar

Versão minimalista. Útil quando você quer o editor embutido sem afterdances visuais.

Compacto (inline)

Para JSON pequeno (1-2 linhas), use minHeight === maxHeight pra fixar a altura.

Com validação visual

Por default, JSON inválido aplica borda vermelha automaticamente. Use onValidityChange para exibir mensagens próprias. Desligue a borda com errorBorder={false} se quiser modo silencioso.

✓ JSON válido

Tema custom — Solarized

A prop theme sobrescreve classes Tailwind por tipo de token. Tokens ausentes caem no tema padrão.

Ou estendendo o tema default:

index.tsx
import { jsonEditorDefaultTheme } from "@convertcompany/ui";

<JsonEditor theme={{ ...jsonEditorDefaultTheme, key: "text-emerald-500" }} />

Stress test — 200 items virtualizados

Editor com ~1.6k linhas. Scroll fluido porque só ~50 linhas estão no DOM a qualquer momento.

200 items • 1204 linhas — virtualizado, scroll fluido.

Tab size customizado

Para indentação de 4 espaços (padrão Python, alguns projetos JS):

index.tsx
<JsonEditor value={value} onChange={setValue} tabSize={4} />

Tokens reconhecidos pelo theme

TokenQuando aplica
keyStrings antes de : (chaves de objeto)
stringDemais strings entre aspas
numberNúmeros (incluindo notação científica como 1.6e-5)
booleantrue / false
nullnull
punctuation{ } [ ] , :
textFallback pra qualquer outro token

Atalhos de teclado

TeclaAção
TabIndenta 2 espaços (ou tabSize). Em seleção multi-linha, indenta todas.
Shift+TabDesindenta. Em seleção multi-linha, desindenta todas.
EnterPreserva indent da linha atual. Após { ou [, adiciona um nível extra.
Format buttonJSON.parse + JSON.stringify(_, null, tabSize) — só ativo quando JSON é válido.

Props

PropriedadeTipo
valueString JSON. Sempre controlado.
string
onChangeCallback ao editar.
(value: string) => void
onValidityChangeCallback chamado quando a validade muda. error é a mensagem do JSON.parse.
(valid: boolean, error?: string) => void
lineNumbersExibe gutter de números à esquerda. Default true.
boolean
errorBorderAplica borda vermelha quando JSON é inválido. Default true.
boolean
copyableRenderiza botão de copiar no canto superior direito. Default false.
boolean
formattableRenderiza botão de formatar (icon-only). Default true.
boolean
themeSobrescreve classes Tailwind por tipo de token.
JsonTheme
tabSizeNúmero de espaços por nível de indent. Default 2.
number
minHeight / maxHeightLimites de altura do editor.
number
string
readOnlyModo somente leitura. Esconde o botão de formatar.
boolean

Exports auxiliares

index.tsx
import {
  JsonEditor,
  tokenizeJson,           // (src: string) => Token[] — tokenizer puro pra reuso
  jsonEditorDefaultTheme, // tema padrão, exportado pra extensão
  type JsonTokenType,
  type JsonTheme,
} from "@convertcompany/ui";