Vitral 0.2
Formulário

Editor

Texto rico com motor próprio e sem dependências: títulos, listas, tabelas, imagens, links e atalhos de Markdown, ligado como HTML sanitizado.

Importação

main.ts
import { Editor } from '@vitral/vue';

Padrão

Release notes

This editor writes semantic HTML, keeps undo history and understands Markdown as you type. Try ## , - or **bold**.

  • Paste from Word or Google Docs

  • Select text and press Ctrl+K for a link

Nothing pasted can run a script: only what the schema knows survives.

Texto formatado. Alt+F10 vai para a barra de ferramentas e Esc volta. Atalhos Markdown como # e - funcionam no início da linha.
<script setup lang="ts">import { Editor, Label, StackPanel } from '@vitral/vue';import { ref } from 'vue'; const article = ref(    '<h2>Release notes</h2><p>This editor writes <strong>semantic HTML</strong>, keeps <em>undo</em> history and understands <code>Markdown</code> as you type. Try <code>## </code>, <code>- </code> or <code>**bold**</code>.</p>' +        '<ul data-type="taskList"><li data-type="taskItem" data-checked="true"><p>Paste from Word or Google Docs</p></li><li data-type="taskItem" data-checked="false"><p>Select text and press Ctrl+K for a link</p></li></ul>' +        '<blockquote><p>Nothing pasted can run a script: only what the schema knows survives.</p></blockquote>');</script> <template>    <StackPanel spacing="0.375rem" style="width: 100%">        <Label for="ed-article">Article</Label>        <Editor id="ed-article" v-model="article" placeholder="Write something…" />    </StackPanel></template>

Barra de ferramentas personalizada

`toolbar` recebe grupos de nomes de itens; o slot `toolbar` substitui a barra por peças suas.

Only the basics here.

Texto formatado. Alt+F10 vai para a barra de ferramentas e Esc volta. Atalhos Markdown como # e - funcionam no início da linha.


Texto formatado. Alt+F10 vai para a barra de ferramentas e Esc volta. Atalhos Markdown como # e - funcionam no início da linha.
<script setup lang="ts">import { Editor, EditorButton, EditorToolbar, EditorToolbarGroup, StackPanel } from '@vitral/vue';import { ref } from 'vue'; const note = ref('<p>Only the basics here.</p>');</script> <template>    <StackPanel spacing="1rem" style="width: 100%">        <Editor v-model="note" :toolbar="[['bold', 'italic', 'strike'], ['bulletList', 'orderedList'], ['link', 'undo', 'redo']]" aria-label="Note" />        <Editor aria-label="Minimal" placeholder="The toolbar slot">            <template #toolbar>                <EditorToolbar>                    <EditorToolbarGroup>                        <EditorButton command="heading2" />                        <EditorButton command="bold" />                        <EditorButton command="italic" />                    </EditorToolbarGroup>                    <EditorToolbarGroup>                        <EditorButton command="clear" show-label />                    </EditorToolbarGroup>                </EditorToolbar>            </template>        </Editor>    </StackPanel></template>

Menu de barra e ações de bloco

Digite `/` no começo de uma palavra e os blocos são oferecidos, filtrados enquanto você digita; Enter ou um clique insere um. Ao lado do bloco em que está o cursor há uma alça, que abre duplicar, mover, transformar em texto e excluir. `slash-menu` e `block-menu` recebem entradas suas, ou `false` para nenhuma.

Type a slash on the empty line under this one.


Texto formatado. Alt+F10 vai para a barra de ferramentas e Esc volta. Atalhos Markdown como # e - funcionam no início da linha.

This one offers three commands of its own.


Texto formatado. Alt+F10 vai para a barra de ferramentas e Esc volta. Atalhos Markdown como # e - funcionam no início da linha.
<script setup lang="ts">import { Editor, StackPanel } from '@vitral/vue';import { ref } from 'vue'; const blocks = ref('<p>Type a slash on the empty line under this one.</p><p></p>');const custom = ref('<p>This one offers three commands of its own.</p><p></p>'); // A slash command is data: a name, a line about it, and either a command the// editor knows or a `run` of your own.const slashCommands = [    { id: 'heading2', label: 'Section', description: 'A heading for a section', icon: 'heading2', command: ['toggleHeading', 2] as const },    { id: 'taskList', label: 'Checklist', description: 'Things to tick off', icon: 'listChecks', command: ['toggleTaskList'] as const },    {        id: 'today',        label: "Today's date",        description: 'Puts the date in, as text',        icon: 'calendar',        keywords: ['date', 'now'],        run: (editor: { run: (name: string, ...args: unknown[]) => boolean }) => editor.run('insertText', new Date().toLocaleDateString())    }];</script> <template>    <StackPanel spacing="1rem" style="width: 100%">        <Editor v-model="blocks" aria-label="Slash menu example" :toolbar="[['blockType'], ['bold', 'italic']]" />        <Editor            v-model="custom"            aria-label="Own slash commands"            :toolbar="false"            :slash-menu="slashCommands"            :block-menu="[{ id: 'delete', label: 'Delete', icon: 'trash', run: (editor) => editor.run('deleteBlock') }]"        />    </StackPanel></template>

Barra de ferramentas flutuante

`bubble-menu` mostra uma barra de ferramentas sobre o texto selecionado; com `:toolbar="false"`, ela é a única.

Select some of this text: a floating toolbar appears over it, with bold, italic, a link and a colour.

Texto formatado. Alt+F10 vai para a barra de ferramentas e Esc volta. Atalhos Markdown como # e - funcionam no início da linha.
<script setup lang="ts">import { Editor } from '@vitral/vue';import { ref } from 'vue'; const bubble = ref('<p>Select some of this text: a floating toolbar appears over it, with bold, italic, a link and a colour.</p>');</script> <template>    <Editor v-model="bubble" :toolbar="false" bubble-menu aria-label="Bubble toolbar example" style="width: 100%" /></template>

Somente leitura

Terms

Read-only text can still be selected and copied, and links open.

  1. First

  2. Second

Texto formatado. Alt+F10 vai para a barra de ferramentas e Esc volta. Atalhos Markdown como # e - funcionam no início da linha.
<script setup lang="ts">import { Editor } from '@vitral/vue';import { ref } from 'vue'; const terms = ref(    '<h3>Terms</h3><p>Read-only text can still be <mark data-color="yellow">selected and copied</mark>, and <a href="https://example.com" target="_blank">links</a> open.</p><ol><li><p>First</p></li><li><p>Second</p></li></ol>');</script> <template>    <Editor v-model="terms" readonly :toolbar="false" aria-label="Terms" style="width: 100%" /></template>

Com contagem e limite

`max-length` interrompe a digitação e a colagem no limite; a contagem descreve o texto.

Keep it short.

Texto formatado. Alt+F10 vai para a barra de ferramentas e Esc volta. Atalhos Markdown como # e - funcionam no início da linha.
<script setup lang="ts">import { Editor, Label, StackPanel } from '@vitral/vue';import { ref } from 'vue'; const bio = ref('<p>Keep it short.</p>');</script> <template>    <StackPanel spacing="0.375rem" style="width: 100%">        <Label for="ed-bio">Bio</Label>        <Editor id="ed-bio" v-model="bio" :max-length="140" :toolbar="[['bold', 'italic', 'link']]" />    </StackPanel></template>

Saída em HTML e JSON

Type here and watch both formats change.

Texto formatado. Alt+F10 vai para a barra de ferramentas e Esc volta. Atalhos Markdown como # e - funcionam no início da linha.
<p>Type here and watch <strong>both</strong> formats change.</p>
null
<script setup lang="ts">import { Editor, type EditorJSON } from '@vitral/vue';import { ref } from 'vue'; const output = ref('<p>Type here and watch <strong>both</strong> formats change.</p>');const outputJson = ref<EditorJSON | null>(null);</script> <template>    <Editor v-model="output" v-model:json="outputJson" aria-label="Output example" :toolbar="[['blockType'], ['bold', 'italic', 'color', 'highlight'], ['bulletList', 'link']]" style="width: 100%" />    <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); gap: 1rem; width: 100%">        <pre class="demo-output" aria-label="HTML" tabindex="0" style="margin: 0; max-height: 16rem; overflow: auto; white-space: pre-wrap; font-size: 0.75rem">{{ output }}</pre>        <pre class="demo-output" aria-label="JSON" tabindex="0" style="margin: 0; max-height: 16rem; overflow: auto; font-size: 0.75rem">{{ JSON.stringify(outputJson, null, 2) }}</pre>    </div></template>

Composto por partes

`Editor.Root`, `Editor.Toolbar`, `Editor.Button`, `Editor.Content`, `Editor.BubbleMenu`, `Editor.Footer` e `Editor.Count`, também exportados como `EditorRoot`, `EditorToolbar`… compartilham um só editor; `useEditor()` chega até ele a partir dos seus próprios componentes.

This one is built from parts, with a toolbar of its own and a word count.

Texto formatado. Alt+F10 vai para a barra de ferramentas e Esc volta. Atalhos Markdown como # e - funcionam no início da linha.
<script setup lang="ts">import { Editor } from '@vitral/vue';import { ref } from 'vue'; const composed = ref('<p>This one is built from parts, with a toolbar of its own and a word count.</p>');const words = ref(0);</script> <template>    <Editor.Root v-model="composed" placeholder="Parts…" aria-label="Composed editor" style="width: 100%" @text-change="words = $event.textValue.split(/\s+/).filter(Boolean).length">        <Editor.Toolbar>            <Editor.ToolbarGroup>                <Editor.BlockSelect :options="['paragraph', 'heading1', 'heading2']" />            </Editor.ToolbarGroup>            <Editor.ToolbarGroup>                <Editor.Button command="bold" />                <Editor.Button command="italic" />                <Editor.ColorPicker kind="highlight" />                <Editor.Button command="link" />            </Editor.ToolbarGroup>            <Editor.ToolbarGroup>                <Editor.Button command="taskList" />                <Editor.ImageButton />                <Editor.TableMenu />            </Editor.ToolbarGroup>        </Editor.Toolbar>        <Editor.Content />        <Editor.BubbleMenu :items="['bold', 'italic', 'link']" />        <Editor.Footer>            <span style="margin-inline-end: auto">Edited words: {{ words }}</span>            <Editor.Count :words="false" />        </Editor.Footer>    </Editor.Root></template>

API

Lido de packages/vue/src/components/Editor/types.ts, então diz o que o componente aceita de fato.

Props

NomeTipoDescrição
placeholderstring—
readonlybooleanO texto pode ser lido, selecionado e copiado, não alterado.
disabledboolean—
invalidboolean—
variantInputVariantO padrão é o `inputVariant` do plugin.
maxLengthnumberO máximo de caracteres que o texto pode ter; digitar e colar param aí.
autofocusbooleanDá foco ao texto, com o cursor no fim, ao montar.
colorsstring[]Nomes de cores da paleta que os seletores de cor e de destaque oferecem, em ordem. O padrão é a paleta inteira.
historyDelaynumberMilissegundos dentro dos quais digitação seguida conta como um só passo de desfazer. O padrão é 500.
slashMenuboolean | SlashCommand[]O menu que uma `/` abre no início de uma palavra: `true` para os blocos que o editor conhece, os comandos a oferecer, ou `false` para nenhum. O padrão é true.
blockMenuboolean | BlockAction[]A alça ao lado do bloco em que está o cursor: `true` para as ações de sempre, as ações a oferecer, ou `false` para nenhuma. O padrão é true.
toolbarboolean | EditorToolbarItem[][]A barra de ferramentas: `false` para nenhuma, ou grupos de nomes de itens, como em `[['bold', 'italic'], ['link']]`. O slot `toolbar` a substitui por completo.
bubbleMenuboolean | EditorToolbarItem[]Uma barra de ferramentas flutuante sobre o texto selecionado; `true` para os botões padrão, ou os itens a mostrar.
showCountbooleanMostra a contagem de palavras e caracteres abaixo do texto. Ligado por padrão quando há `maxLength`.
showWordCountbooleanMostra a contagem de palavras ao lado da de caracteres. O padrão é true.

Mais pt, dt e unstyled de BaseProps; veja pass-through e modo sem estilo.

Emits

EventoPayloadDescrição
update:modelValuevalue: string—
update:jsonvalue: EditorJSON—
text-changeevent: EditorTextChangeEventO conteúdo mudou.
selection-changeevent: EditorSelectionChangeEvent—
focusevent: FocusEvent—
blurevent: FocusEvent—
loadevent: { instance: unknown }O editor está pronto; `instance` é o editor sem framework por trás do componente.

Slots

NomeProps do slotDescrição
toolbar—Substitui a barra de ferramentas. Monte uma com `EditorToolbar`, `EditorButton` e as outras partes.
footer—Substitui o conteúdo do rodapé (a contagem).