@seedgrid/ai-toolkit 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,17 +1,17 @@
1
- ---
2
- tags: [seedgrid, component, frontend, react, editor, tiptap, api]
3
- fonte: front/seedgrid-fe-components/packages/seedgrid-fe-components/src/inputs/SgTextEditor.tsx
4
- branch: main
5
- commit: ad30fc11de
6
- analisado-em: 2026-10-14
7
- ---
8
-
9
- # SgTextEditor: API
10
-
11
- Import: `import { SgTextEditor, type SgTextEditorProps, type SgTextEditorSaveMeta } from "@seedgrid/fe-components";` (pacote v`2026.7.1`). Contexto: [[SeedGrid/SeedGrid-components/editor/Visao-geral|Visão geral do SgTextEditor]]. Exemplos: [[SeedGrid/SeedGrid-components/editor/Exemplos|Exemplos do SgTextEditor]]. A metodologia da tabela está em [[SeedGrid/SeedGrid-components/inputs-texto/API#Como as tabelas foram montadas|Como as tabelas foram montadas]]. As props RHF seguem o [[SeedGrid/SeedGrid-components/inputs-texto/API#Contrato RhfFieldProps (react-hook-form)|contrato RhfFieldProps]], com o desvio indicado na própria tabela.
12
-
13
- ## Props (21)
14
-
1
+ ---
2
+ tags: [seedgrid, component, frontend, react, editor, tiptap, api]
3
+ fonte: front/seedgrid-fe-components/packages/seedgrid-fe-components/src/inputs/SgTextEditor.tsx
4
+ branch: main
5
+ commit: ad30fc11de
6
+ analisado-em: 2026-10-14
7
+ ---
8
+
9
+ # SgTextEditor: API
10
+
11
+ Import: `import { SgTextEditor, type SgTextEditorProps, type SgTextEditorSaveMeta } from "@seedgrid/fe-components";` (pacote v`2026.7.1`). Contexto: [[SeedGrid/SeedGrid-components/editor/Visao-geral|Visão geral do SgTextEditor]]. Exemplos: [[SeedGrid/SeedGrid-components/editor/Exemplos|Exemplos do SgTextEditor]]. A metodologia da tabela está em [[SeedGrid/SeedGrid-components/inputs-texto/API#Como as tabelas foram montadas|Como as tabelas foram montadas]]. As props RHF seguem o [[SeedGrid/SeedGrid-components/inputs-texto/API#Contrato RhfFieldProps (react-hook-form)|contrato RhfFieldProps]], com o desvio indicado na própria tabela.
12
+
13
+ ## Props (21)
14
+
15
15
  | Prop | Tipo | Padrão | Obrigatória | Descrição |
16
16
  |---|---|---|---|---|
17
17
  | `error` | `string` | — | Não | Erro abaixo do editor. |
@@ -34,92 +34,92 @@ Import: `import { SgTextEditor, type SgTextEditorProps, type SgTextEditorSaveMet
34
34
  | `style` | `CSSProperties` | — | Não | Estilo do wrapper. |
35
35
  | `name` | `string` | — | Não | Nome do campo no react-hook-form. Só tem efeito junto com `control` ou `register` (ver contrato RHF). |
36
36
  | `control` | `any` | — | Não | `Control` do `useForm()`; com `name`, envolve o componente em `<Controller>`. |
37
- | `rules` | `RegisterOptions<any>` | — | Não | Regras de validação do RHF (`RegisterOptions`). |
38
-
39
- ## Tipos exportados
40
-
41
- | Tipo | Forma |
42
- |---|---|
43
- | `SgTextEditorProps` | Tabela acima. |
44
- | `SgTextEditorSaveMeta` | `{ htmlDocument: string; contentHtml: string; cssText: string }` |
45
-
46
- ## Eventos e formatos de retorno
47
-
48
- - **`onChangeHtml(htmlBody)`:**
49
- - Disparado no `onUpdate` do TipTap com `editor.getHTML()`.
50
- - Entrega **só o HTML do corpo**, por exemplo `"<p><strong>SeedGrid</strong> editor</p>"`, sem `<html>`/`<style>`.
51
- - **`onSave(file, meta)`:** acionado pelo botão "Salvar" da toolbar (i18n `components.actions.save`).
52
- - `file` é um `File` `text/html;charset=utf-8`, com nome `fileName ?? "<id>.html"`.
53
- - O conteúdo é um documento completo: `<!doctype html>`, `<html lang="<locale do i18n>">`, `<meta charset>`, `<meta viewport>`, `<style>` com o `cssText` (se houver) e `<body>` com o HTML.
54
- - `meta` traz o mesmo documento como string (`htmlDocument`), além de `contentHtml` e `cssText`.
55
- - **`onLoad(meta)`:** o botão "Carregar HTML" (i18n `components.actions.loadHtml`) abre um `<input type="file" accept="text/html,.html">`. O componente então:
56
- 1. lê o arquivo;
57
- 2. extrai o CSS de `head style` e o `body`;
58
- 3. troca o conteúdo do editor;
59
- 4. chama `onCssTextChange` se o CSS mudou;
60
- 5. chama `onLoad`.
61
- - **`onCssTextChange(css)`:** chamado pela textarea de CSS (`showCssEditor`) e no carregamento de arquivo.
62
-
63
- **Confirmado** (`buildFullHtmlDocument`, `parseHtmlDocument`, `doSave`, `loadFromHtmlString`).
64
-
65
- ## Controlado e não controlado
66
-
67
- - **Controlado:** quando `valueHtml` é `string`. Se o HTML do editor divergir de `valueHtml`, o componente chama `setContent(valueHtml)`.
68
- - **Não controlado:** o conteúdo inicial vem de `defaultValueHtml`.
69
- - **`cssText`:** é sempre lido da prop. Sem `onCssTextChange`, a textarea de CSS não altera nada.
70
-
71
- **Confirmado**.
72
-
73
- ## Integração react-hook-form
74
-
75
- - **Integração:** via `control` + `name` (`<Controller>`). O valor do campo é o HTML do corpo (`field.value` string → `valueHtml`; `onChangeHtml` → `field.onChange`).
76
- - Nesse caminho, o `onChangeHtml` do usuário é substituído por `field.onChange`.
77
- - `rules` são repassadas sem `mergeRequiredRule` (o tipo não tem `required`).
78
-
79
- Teste de contrato: `tests/rhf-components-contract.test.mjs` ("SgTextEditor preserves control integration path"). **Confirmado**.
80
-
81
- ## Ref
82
-
83
- O componente não usa `forwardRef` e não expõe a instância do TipTap (`Editor`). **Confirmado**.
84
-
85
- ## Toolbar e extensões TipTap
86
-
87
- | Recurso | Implementação (`useEditor`) |
88
- |---|---|
89
- | Parágrafo/títulos H1, H2, H3 | `StarterKit` (`codeBlock` habilitado) + `<select>` |
90
- | Fonte (Arial, Georgia, Times, Courier) | `@tiptap/extension-font-family` |
91
- | Tamanho da fonte | `TextStyle` estendido com o atributo `fontSize` (`TextStyleWithSize`) |
92
- | Negrito, itálico, sublinhado, tachado | `StarterKit` + `@tiptap/extension-underline` |
93
- | Cor do texto e realce multicolor | `@tiptap/extension-color`, `@tiptap/extension-highlight` (`multicolor: true`) |
94
- | Sub/sobrescrito | `@tiptap/extension-subscript`, `@tiptap/extension-superscript` |
95
- | Listas, recuo e avanço | `StarterKit` |
96
- | Alinhamento (esquerda, centro, direita, justificado) | `@tiptap/extension-text-align` (`types: ["heading", "paragraph"]`) |
97
- | Link | `@tiptap/extension-link` (`openOnClick: false`, `autolink`, `linkOnPaste`) via `window.prompt` |
98
- | Imagem por URL | `@tiptap/extension-image` (`inline: false`) via `window.prompt` |
99
- | Limpar formatação | `unsetAllMarks().clearNodes()` |
100
-
101
- O editor é criado com `immediatelyRender: false` (seguro para SSR) e `editable: !disabled`. **Confirmado**.
102
-
103
- ## Internacionalização
104
-
105
- As chaves usadas são:
106
- - `components.textEditor.placeholder`, `cssEditorLabel`, `editorAriaLabel`, `help.cssEmbedded`;
107
- - `components.textEditor.prompt.url` e `prompt.imageUrl`;
108
- - `components.textEditor.toolbar.*`: `heading`, `subheading`, `normal`, `heading3`, `defaultFont`, `bold`, `italic`, `underline`, `strike`, `textColor`, `highlightColor`, `bullets`, `numbered`, `indent`, `outdent`, `alignLeft`, `alignCenter`, `alignRight`, `justify`, `link`, `image`, `clear`, `subscript`, `superscript`;
109
- - `components.actions.save` e `components.actions.loadHtml`.
110
-
111
- O `lang` do documento salvo é o `locale` do i18n. **Confirmado**.
112
-
113
- ## Acessibilidade comprovável
114
-
115
- - A área editável tem `id` e `aria-label` (i18n `components.textEditor.editorAriaLabel`).
116
- - Os botões da toolbar (`ToolbarButton`) têm `aria-label`, e os ícones são `aria-hidden`.
117
- - Os `<select>` de estilo, fonte e tamanho **não** têm rótulo associado.
118
- - O rótulo do editor de CSS é um `<label>` sem `htmlFor`.
119
-
120
- **Confirmado**.
121
-
122
- ## Fontes
123
-
124
- - `front/seedgrid-fe-components/packages/seedgrid-fe-components/src/inputs/SgTextEditor.tsx` (`SgTextEditorBase`, `SgTextEditor`, `ToolbarButton`, `TextStyleWithSize`)
125
- - `front/seedgrid-fe-components/packages/seedgrid-fe-components/package.json` (`peerDependencies`)
37
+ | `rules` | `RegisterOptions<any>` | — | Não | Regras de validação do RHF (`RegisterOptions`). |
38
+
39
+ ## Tipos exportados
40
+
41
+ | Tipo | Forma |
42
+ |---|---|
43
+ | `SgTextEditorProps` | Tabela acima. |
44
+ | `SgTextEditorSaveMeta` | `{ htmlDocument: string; contentHtml: string; cssText: string }` |
45
+
46
+ ## Eventos e formatos de retorno
47
+
48
+ - **`onChangeHtml(htmlBody)`:**
49
+ - Disparado no `onUpdate` do TipTap com `editor.getHTML()`.
50
+ - Entrega **só o HTML do corpo**, por exemplo `"<p><strong>SeedGrid</strong> editor</p>"`, sem `<html>`/`<style>`.
51
+ - **`onSave(file, meta)`:** acionado pelo botão "Salvar" da toolbar (i18n `components.actions.save`).
52
+ - `file` é um `File` `text/html;charset=utf-8`, com nome `fileName ?? "<id>.html"`.
53
+ - O conteúdo é um documento completo: `<!doctype html>`, `<html lang="<locale do i18n>">`, `<meta charset>`, `<meta viewport>`, `<style>` com o `cssText` (se houver) e `<body>` com o HTML.
54
+ - `meta` traz o mesmo documento como string (`htmlDocument`), além de `contentHtml` e `cssText`.
55
+ - **`onLoad(meta)`:** o botão "Carregar HTML" (i18n `components.actions.loadHtml`) abre um `<input type="file" accept="text/html,.html">`. O componente então:
56
+ 1. lê o arquivo;
57
+ 2. extrai o CSS de `head style` e o `body`;
58
+ 3. troca o conteúdo do editor;
59
+ 4. chama `onCssTextChange` se o CSS mudou;
60
+ 5. chama `onLoad`.
61
+ - **`onCssTextChange(css)`:** chamado pela textarea de CSS (`showCssEditor`) e no carregamento de arquivo.
62
+
63
+ **Confirmado** (`buildFullHtmlDocument`, `parseHtmlDocument`, `doSave`, `loadFromHtmlString`).
64
+
65
+ ## Controlado e não controlado
66
+
67
+ - **Controlado:** quando `valueHtml` é `string`. Se o HTML do editor divergir de `valueHtml`, o componente chama `setContent(valueHtml)`.
68
+ - **Não controlado:** o conteúdo inicial vem de `defaultValueHtml`.
69
+ - **`cssText`:** é sempre lido da prop. Sem `onCssTextChange`, a textarea de CSS não altera nada.
70
+
71
+ **Confirmado**.
72
+
73
+ ## Integração react-hook-form
74
+
75
+ - **Integração:** via `control` + `name` (`<Controller>`). O valor do campo é o HTML do corpo (`field.value` string → `valueHtml`; `onChangeHtml` → `field.onChange`).
76
+ - Nesse caminho, o `onChangeHtml` do usuário é substituído por `field.onChange`.
77
+ - `rules` são repassadas sem `mergeRequiredRule` (o tipo não tem `required`).
78
+
79
+ Teste de contrato: `tests/rhf-components-contract.test.mjs` ("SgTextEditor preserves control integration path"). **Confirmado**.
80
+
81
+ ## Ref
82
+
83
+ O componente não usa `forwardRef` e não expõe a instância do TipTap (`Editor`). **Confirmado**.
84
+
85
+ ## Toolbar e extensões TipTap
86
+
87
+ | Recurso | Implementação (`useEditor`) |
88
+ |---|---|
89
+ | Parágrafo/títulos H1, H2, H3 | `StarterKit` (`codeBlock` habilitado) + `<select>` |
90
+ | Fonte (Arial, Georgia, Times, Courier) | `@tiptap/extension-font-family` |
91
+ | Tamanho da fonte | `TextStyle` estendido com o atributo `fontSize` (`TextStyleWithSize`) |
92
+ | Negrito, itálico, sublinhado, tachado | `StarterKit` + `@tiptap/extension-underline` |
93
+ | Cor do texto e realce multicolor | `@tiptap/extension-color`, `@tiptap/extension-highlight` (`multicolor: true`) |
94
+ | Sub/sobrescrito | `@tiptap/extension-subscript`, `@tiptap/extension-superscript` |
95
+ | Listas, recuo e avanço | `StarterKit` |
96
+ | Alinhamento (esquerda, centro, direita, justificado) | `@tiptap/extension-text-align` (`types: ["heading", "paragraph"]`) |
97
+ | Link | `@tiptap/extension-link` (`openOnClick: false`, `autolink`, `linkOnPaste`) via `window.prompt` |
98
+ | Imagem por URL | `@tiptap/extension-image` (`inline: false`) via `window.prompt` |
99
+ | Limpar formatação | `unsetAllMarks().clearNodes()` |
100
+
101
+ O editor é criado com `immediatelyRender: false` (seguro para SSR) e `editable: !disabled`. **Confirmado**.
102
+
103
+ ## Internacionalização
104
+
105
+ As chaves usadas são:
106
+ - `components.textEditor.placeholder`, `cssEditorLabel`, `editorAriaLabel`, `help.cssEmbedded`;
107
+ - `components.textEditor.prompt.url` e `prompt.imageUrl`;
108
+ - `components.textEditor.toolbar.*`: `heading`, `subheading`, `normal`, `heading3`, `defaultFont`, `bold`, `italic`, `underline`, `strike`, `textColor`, `highlightColor`, `bullets`, `numbered`, `indent`, `outdent`, `alignLeft`, `alignCenter`, `alignRight`, `justify`, `link`, `image`, `clear`, `subscript`, `superscript`;
109
+ - `components.actions.save` e `components.actions.loadHtml`.
110
+
111
+ O `lang` do documento salvo é o `locale` do i18n. **Confirmado**.
112
+
113
+ ## Acessibilidade comprovável
114
+
115
+ - A área editável tem `id` e `aria-label` (i18n `components.textEditor.editorAriaLabel`).
116
+ - Os botões da toolbar (`ToolbarButton`) têm `aria-label`, e os ícones são `aria-hidden`.
117
+ - Os `<select>` de estilo, fonte e tamanho **não** têm rótulo associado.
118
+ - O rótulo do editor de CSS é um `<label>` sem `htmlFor`.
119
+
120
+ **Confirmado**.
121
+
122
+ ## Fontes
123
+
124
+ - `front/seedgrid-fe-components/packages/seedgrid-fe-components/src/inputs/SgTextEditor.tsx` (`SgTextEditorBase`, `SgTextEditor`, `ToolbarButton`, `TextStyleWithSize`)
125
+ - `front/seedgrid-fe-components/packages/seedgrid-fe-components/package.json` (`peerDependencies`)
@@ -1,86 +1,86 @@
1
- ---
2
- tags: [seedgrid, component, frontend, react, editor, tiptap]
3
- fonte: front/seedgrid-fe-components/packages/seedgrid-fe-components/src/inputs/SgTextEditor.tsx
4
- branch: main
5
- commit: ad30fc11de
6
- analisado-em: 2026-10-14
7
- ---
8
-
9
- # SgTextEditor
10
-
11
- O `SgTextEditor` é o editor de texto rico (HTML) do pacote `@seedgrid/fe-components` (v`2026.7.1`), construído sobre o **TipTap 2**. Referência: [[SeedGrid/SeedGrid-components/editor/API|API do SgTextEditor]]. Código: [[SeedGrid/SeedGrid-components/editor/Exemplos|Exemplos do SgTextEditor]].
12
-
13
- ## Objetivo
14
-
15
- O editor produz e edita **documentos HTML com CSS embutido**. As funções principais, todas **Confirmado**:
16
- - toolbar de formatação (títulos, fontes, tamanhos, cores, listas, alinhamento, link, imagem por URL);
17
- - editor opcional de CSS;
18
- - botões para **salvar** o documento como `File` `.html` e **carregar** um `.html` do disco.
19
-
20
- Usos indicados: modelos de e-mail, termos e contratos, conteúdo de páginas e notas ricas. Para texto simples, use [[SeedGrid/SeedGrid-components/inputs-texto/Visao-geral|SgInputTextArea]]. Essa recomendação está em `aiHints.avoidUseCases` de `SgInputText.meta.ts`. **Confirmado**.
21
-
22
- ## Dependências (peers TipTap)
23
-
24
- `peerDependencies` do pacote (também em `devDependencies`), todas na faixa `^2.9.1`:
25
-
26
- | Pacote | Uso |
27
- |---|---|
28
- | `@tiptap/react` | `useEditor`, `EditorContent` |
29
- | `@tiptap/core` | Tipos/base |
30
- | `@tiptap/pm` | ProseMirror |
31
- | `@tiptap/starter-kit` | Parágrafos, títulos, listas, negrito/itálico/tachado, bloco de código |
32
- | `@tiptap/extension-underline` | Sublinhado |
33
- | `@tiptap/extension-link` | Links |
34
- | `@tiptap/extension-image` | Imagens |
35
- | `@tiptap/extension-text-align` | Alinhamento |
36
- | `@tiptap/extension-text-style` | Base de estilo (estendida com `fontSize`) |
37
- | `@tiptap/extension-color` | Cor do texto |
38
- | `@tiptap/extension-highlight` | Realce |
39
- | `@tiptap/extension-subscript` / `@tiptap/extension-superscript` | Sub/sobrescrito |
40
- | `@tiptap/extension-font-family` | Família da fonte |
41
-
42
- Além disso: `react`, `react-hook-form` (`Controller`) e `lucide-react` (ícones da toolbar). **Confirmado** pelos imports de `SgTextEditor.tsx` e pelo `package.json`.
43
-
44
- **Importante:** o `src/index.ts` reexporta o `SgTextEditor` estaticamente, e o arquivo importa o TipTap no topo. Por isso, **qualquer** importação de `@seedgrid/fe-components` faz o bundler resolver os pacotes `@tiptap/*`, mesmo em aplicações que não usam o editor. Na prática, os peers TipTap são necessários para todo consumidor do pacote. Isso é **Inferência**, pela estrutura dos imports ESM e pelo campo `sideEffects: true`; não foi testado em uma aplicação consumidora.
45
-
46
- ## Composição
47
-
48
- ```mermaid
49
- graph LR
50
- TB[Toolbar: selects + ToolbarButton] --> ED[EditorContent TipTap]
51
- ED -->|onUpdate| CH[onChangeHtml body HTML]
52
- SAVE[Botão Salvar] --> DOC[buildFullHtmlDocument body + cssText] --> F[File .html via onSave]
53
- LOAD[Botão Carregar HTML] --> PARSE[parseHtmlDocument] --> ED
54
- PARSE --> CSS[onCssTextChange]
55
- CSSED[Textarea CSS opcional] --> CSS
56
- ```
57
-
58
- - O corpo editado (`valueHtml`) e o CSS (`cssText`) ficam **separados**. Eles só se juntam no documento salvo.
59
- - O CSS **não** é aplicado ao conteúdo dentro do editor. Ele vai apenas para o `<style>` do arquivo gerado.
60
-
61
- **Confirmado**: o `cssText` só é usado em `buildFullHtmlDocument` e na textarea.
62
-
63
- ## Tema e estilos
64
-
65
- - **Área de edição:** classes `prose max-w-none`. As classes `prose` vêm do plugin de tipografia do Tailwind. Se esse plugin está incluído no CSS compilado do pacote **não foi verificado**.
66
- - **Moldura:** a toolbar e a área usam bordas e `bg-background`.
67
- - **Customização:** `className`, `style`, `borderRadius`, `height` (padrão 320 px).
68
- - **Desabilitado:** `disabled` deixa o conteúdo não editável, com opacidade 60%.
69
-
70
- **Confirmado**, salvo o ponto do `prose`.
71
-
72
- ## Internacionalização
73
-
74
- Todos os rótulos da toolbar, os prompts e o placeholder vêm de `components.textEditor.*`. Ver [[SeedGrid/SeedGrid-components/editor/API#Internacionalização|API]].
75
-
76
- ## Testes
77
-
78
- Só há o teste de contrato por regex (`tests/rhf-components-contract.test.mjs`), que confere o caminho `control`. Não há teste DOM do editor. **Confirmado**.
79
-
80
- ## Limitações e pontos de atenção
81
-
82
- - **Prompts nativos:** link e imagem usam `window.prompt`, sem diálogo próprio e sem upload de arquivo de imagem. **Confirmado**.
83
- - **Instância TipTap:** não há ref nem acesso a ela, então não dá para registrar extensões adicionais. **Confirmado**.
84
- - **RHF:** integração só via `control`. Nesse modo, o `onChangeHtml` do usuário é substituído e deixa de ser chamado. **Confirmado**.
85
- - **Segurança:** o HTML carregado de arquivo vai para o editor sem sanitização explícita. O TipTap descarta o que não corresponde ao schema das extensões, mas o `cssText` extraído é repassado como veio. **Inferência**.
86
- - **Seletor de tamanho de fonte:** é um `<select>` com `defaultValue="16px"`, não controlado, e não reflete o tamanho da seleção atual. **Confirmado**.
1
+ ---
2
+ tags: [seedgrid, component, frontend, react, editor, tiptap]
3
+ fonte: front/seedgrid-fe-components/packages/seedgrid-fe-components/src/inputs/SgTextEditor.tsx
4
+ branch: main
5
+ commit: ad30fc11de
6
+ analisado-em: 2026-10-14
7
+ ---
8
+
9
+ # SgTextEditor
10
+
11
+ O `SgTextEditor` é o editor de texto rico (HTML) do pacote `@seedgrid/fe-components` (v`2026.7.1`), construído sobre o **TipTap 2**. Referência: [[SeedGrid/SeedGrid-components/editor/API|API do SgTextEditor]]. Código: [[SeedGrid/SeedGrid-components/editor/Exemplos|Exemplos do SgTextEditor]].
12
+
13
+ ## Objetivo
14
+
15
+ O editor produz e edita **documentos HTML com CSS embutido**. As funções principais, todas **Confirmado**:
16
+ - toolbar de formatação (títulos, fontes, tamanhos, cores, listas, alinhamento, link, imagem por URL);
17
+ - editor opcional de CSS;
18
+ - botões para **salvar** o documento como `File` `.html` e **carregar** um `.html` do disco.
19
+
20
+ Usos indicados: modelos de e-mail, termos e contratos, conteúdo de páginas e notas ricas. Para texto simples, use [[SeedGrid/SeedGrid-components/inputs-texto/Visao-geral|SgInputTextArea]]. Essa recomendação está em `aiHints.avoidUseCases` de `SgInputText.meta.ts`. **Confirmado**.
21
+
22
+ ## Dependências (peers TipTap)
23
+
24
+ `peerDependencies` do pacote (também em `devDependencies`), todas na faixa `^2.9.1`:
25
+
26
+ | Pacote | Uso |
27
+ |---|---|
28
+ | `@tiptap/react` | `useEditor`, `EditorContent` |
29
+ | `@tiptap/core` | Tipos/base |
30
+ | `@tiptap/pm` | ProseMirror |
31
+ | `@tiptap/starter-kit` | Parágrafos, títulos, listas, negrito/itálico/tachado, bloco de código |
32
+ | `@tiptap/extension-underline` | Sublinhado |
33
+ | `@tiptap/extension-link` | Links |
34
+ | `@tiptap/extension-image` | Imagens |
35
+ | `@tiptap/extension-text-align` | Alinhamento |
36
+ | `@tiptap/extension-text-style` | Base de estilo (estendida com `fontSize`) |
37
+ | `@tiptap/extension-color` | Cor do texto |
38
+ | `@tiptap/extension-highlight` | Realce |
39
+ | `@tiptap/extension-subscript` / `@tiptap/extension-superscript` | Sub/sobrescrito |
40
+ | `@tiptap/extension-font-family` | Família da fonte |
41
+
42
+ Além disso: `react`, `react-hook-form` (`Controller`) e `lucide-react` (ícones da toolbar). **Confirmado** pelos imports de `SgTextEditor.tsx` e pelo `package.json`.
43
+
44
+ **Importante:** o `src/index.ts` reexporta o `SgTextEditor` estaticamente, e o arquivo importa o TipTap no topo. Por isso, **qualquer** importação de `@seedgrid/fe-components` faz o bundler resolver os pacotes `@tiptap/*`, mesmo em aplicações que não usam o editor. Na prática, os peers TipTap são necessários para todo consumidor do pacote. Isso é **Inferência**, pela estrutura dos imports ESM e pelo campo `sideEffects: true`; não foi testado em uma aplicação consumidora.
45
+
46
+ ## Composição
47
+
48
+ ```mermaid
49
+ graph LR
50
+ TB[Toolbar: selects + ToolbarButton] --> ED[EditorContent TipTap]
51
+ ED -->|onUpdate| CH[onChangeHtml body HTML]
52
+ SAVE[Botão Salvar] --> DOC[buildFullHtmlDocument body + cssText] --> F[File .html via onSave]
53
+ LOAD[Botão Carregar HTML] --> PARSE[parseHtmlDocument] --> ED
54
+ PARSE --> CSS[onCssTextChange]
55
+ CSSED[Textarea CSS opcional] --> CSS
56
+ ```
57
+
58
+ - O corpo editado (`valueHtml`) e o CSS (`cssText`) ficam **separados**. Eles só se juntam no documento salvo.
59
+ - O CSS **não** é aplicado ao conteúdo dentro do editor. Ele vai apenas para o `<style>` do arquivo gerado.
60
+
61
+ **Confirmado**: o `cssText` só é usado em `buildFullHtmlDocument` e na textarea.
62
+
63
+ ## Tema e estilos
64
+
65
+ - **Área de edição:** classes `prose max-w-none`. As classes `prose` vêm do plugin de tipografia do Tailwind. Se esse plugin está incluído no CSS compilado do pacote **não foi verificado**.
66
+ - **Moldura:** a toolbar e a área usam bordas e `bg-background`.
67
+ - **Customização:** `className`, `style`, `borderRadius`, `height` (padrão 320 px).
68
+ - **Desabilitado:** `disabled` deixa o conteúdo não editável, com opacidade 60%.
69
+
70
+ **Confirmado**, salvo o ponto do `prose`.
71
+
72
+ ## Internacionalização
73
+
74
+ Todos os rótulos da toolbar, os prompts e o placeholder vêm de `components.textEditor.*`. Ver [[SeedGrid/SeedGrid-components/editor/API#Internacionalização|API]].
75
+
76
+ ## Testes
77
+
78
+ Só há o teste de contrato por regex (`tests/rhf-components-contract.test.mjs`), que confere o caminho `control`. Não há teste DOM do editor. **Confirmado**.
79
+
80
+ ## Limitações e pontos de atenção
81
+
82
+ - **Prompts nativos:** link e imagem usam `window.prompt`, sem diálogo próprio e sem upload de arquivo de imagem. **Confirmado**.
83
+ - **Instância TipTap:** não há ref nem acesso a ela, então não dá para registrar extensões adicionais. **Confirmado**.
84
+ - **RHF:** integração só via `control`. Nesse modo, o `onChangeHtml` do usuário é substituído e deixa de ser chamado. **Confirmado**.
85
+ - **Segurança:** o HTML carregado de arquivo vai para o editor sem sanitização explícita. O TipTap descarta o que não corresponde ao schema das extensões, mas o `cssText` extraído é repassado como veio. **Inferência**.
86
+ - **Seletor de tamanho de fonte:** é um `<select>` com `defaultValue="16px"`, não controlado, e não reflete o tamanho da seleção atual. **Confirmado**.