O componente EditorDragHandle oferece funcionalidade de arrastar e soltar para reordenar blocos do editor usando o pacote @tiptap/extension-drag-handle-vue-3.
Ele estende o componente Button, então você pode passar qualquer propriedade como color, variant, size, etc.
Use a prop icon para personalizar o ícone da alça de arrastar.
<template>
<NEditor v-slot="{ editor }">
<NEditorDragHandle :editor="editor" icon="i-lucide-move" />
</NEditor>
</template>
Use a prop options para personalizar o comportamento de posicionamento usando as opções do Floating UI.
<template>
<NEditor v-slot="{ editor }">
<NEditorDragHandle
:editor="editor"
:options="{
placement: 'left'
}"
/>
</NEditor>
</template>
Use o slot padrão para adicionar um DropdownMenu com ações no nível do bloco, como duplicar, excluir, mover para cima/baixo ou transformar blocos em tipos diferentes.
Escute o evento @node-change para acompanhar o node atualmente sob o cursor e sua posição, e então use editor.chain().setMeta('lockDragHandle', open).run() para travar a posição da alça enquanto o menu está aberto.
mapEditorItems de @nitro/ui/utils/editor para mapear automaticamente os tipos de handler (como duplicate, delete, moveUp, etc.) para os comandos correspondentes do editor, com o devido gerenciamento de estado.Use o slot padrão para adicionar um Button ao lado da alça de arrastar para abrir o EditorSuggestionMenu.
Chame a função de slot onClick para obter a posição atual do node e então use handlers.suggestion?.execute(editor, { pos: node?.pos }).run() para inserir novos blocos naquela posição.
| Prop | Default | Type |
|---|---|---|
as | 'button' | anyThe element or component this component should render as when not a link. |
editor | Editor | |
icon | appConfig.ui.icons.drag | any |
color | 'neutral' | "error" | "neutral" | "primary" | "secondary" | "accent" | "success" | "info" | "warning" |
variant | 'ghost' | "ghost" | "solid" | "outline" | "soft" | "subtle" | "link" |
options | { strategy: 'absolute', placement: 'left-start' } | FloatingUIOptionsThe options for positioning the drag handle. Those are passed to Floating UI and include options for the placement, offset, flip, shift, size, autoPlacement, hide, and inline middleware. |
pluginKey | string | PluginKey<any> | |
nestedOptions | NormalizedNestedOptions | |
onElementDragStart | (e: DragEvent): void | |
onElementDragEnd | (e: DragEvent): void | |
getReferencedVirtualElement | (): VirtualElement | null | |
dragImageProperties | string[] | |
nested | boolean | NestedOptions Enable drag handles for nested content (list items, blockquotes, etc.). When enabled, the drag handle will appear for nested blocks, not just top-level blocks. A rule-based scoring system determines which node to target based on cursor position and configured rules. | |
autofocus | false | true | "true" | "false" | |
disabled | boolean | |
name | string | |
type | 'button' | "reset" | "submit" | "button"The type of the button when not a link. |
label | string | |
activeColor | "error" | "neutral" | "primary" | "secondary" | "accent" | "success" | "info" | "warning" | |
activeVariant | "ghost" | "solid" | "outline" | "soft" | "subtle" | "link" | |
size | 'sm' | "sm" | "xs" | "md" | "lg" | "xl" |
square | boolean Render the button with equal padding on all sides. | |
block | boolean Render the button full width. | |
loadingAuto | boolean Set loading state automatically based on the | |
avatar | AvatarPropsDisplay an avatar on the left side. | |
leading | boolean When | |
leadingIcon | anyDisplay an icon on the left side. | |
trailing | boolean When | |
trailingIcon | anyDisplay an icon on the right side. | |
loading | boolean When | |
loadingIcon | appConfig.ui.icons.loading | anyThe icon when the |
ui | { root?: SlotClass; handle?: SlotClass; } & { base?: SlotClass; label?: SlotClass; leadingIcon?: SlotClass; leadingAvatar?: SlotClass; leadingAvatarSize?: SlotClass; trailingIcon?: SlotClass; } |
| Slot | Type |
|---|---|
default | { ui: object; } |
| Event | Type |
|---|---|
nodeChange | [{ node: JSONContent; pos: number; }] |
hover | [{ node: JSONContent; pos: number; }] |
export default defineAppConfig({
ui: {
editorDragHandle: {
slots: {
root: 'hidden sm:flex items-center justify-center transition-all duration-200 ease-out',
handle: 'cursor-grab px-1'
}
}
}
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nitro/ui/vite'
export default defineConfig({
plugins: [
vue(),
ui({
ui: {
editorDragHandle: {
slots: {
root: 'hidden sm:flex items-center justify-center transition-all duration-200 ease-out',
handle: 'cursor-grab px-1'
}
}
}
})
]
})