npm i rete-context-menu-plugin
Для покращення зручності та повторного використання коду рекомендується створити окремі класи для вузлів:
class NodeA extends ClassicPreset.Node {
constructor(socket: ClassicPreset.Socket) {
super("NodeA");
this.addControl("port", new ClassicPreset.InputControl("text", {}));
this.addOutput("port", new ClassicPreset.Output(socket));
}
}
/// class NodeB extends ...
type Node = NodeA | NodeB;
type Schemes = GetSchemes<Node, Connection<Node, Node>>;
Для простого рішення використовуйте класичний пресет і вкажіть список помічених елементів разом із функцією, яка повертає потрібний вузол
import { ContextMenuExtra, ContextMenuPlugin, Presets as ContextMenuPresets } from "rete-context-menu-plugin";
type AreaExtra = ReactArea2D<Schemes> | ContextMenuExtra;
const contextMenu = new ContextMenuPlugin<Schemes>({
items: ContextMenuPresets.classic.setup([
["NodeA", () => new NodeA(socket)],
["NodeB", () => new NodeB(socket)]
])
});
area.use(contextMenu);
Але цього недостатньо, оскільки рендер плагін відповідає за візуалізацію
Наразі рендерінг контекстного меню можливий за допомогою рендерінг плагінів для React.js, Vue.js, Angular, Svelte та Lit
import { Presets } from "rete-react-plugin"; // або rete-vue-plugin, rete-angular-plugin, rete-svelte-plugin, @retejs/lit-plugin
render.addPreset(Presets.contextMenu.setup());
Щоб отримати вичерпний гайд щодо підключення конкретного рендерінг плагіна до вашої версії стека, дотримуйтеся гайду для React.js, Vue.js, Angular, Svelte або Lit
Натискання на вільному місці відкриває меню, у якому відображаються доступні вузли для створення, або просто натисніть на існуючому вузлі, щоб видалити його.
Щоб указати пункт вузла як підпункт, ви можете використовувати те саме визначення, використовуючи масив замість фабричної функції:
const contextMenu = new ContextMenuPlugin<Schemes>({
items: ContextMenuPresets.classic.setup([
["Math", [
["Number", () => new NumberNode()],
]]
])
})
Всі вузли та з'єднання мають опцію Delete
в їх контекстном меню. Вона відповідно дозволяє видалити вузол, перед тим видаливши його з'єднання, або видалити окремі з'єднання.
Інша опція, яку за замовчуванням ви не побачив на вузлах - це Clone
. Вона відображається для вузлів, які мають метод clone
. До прикладу:
class NodeA extends ClassicPreset.Node {
clone() {
return new NodeA()
}
}
Хоча класичний пресет дозволяє коротко вказати пункти для головного меню та меню для певного вузла, він може не запропонувати достатньої гнучкості. У таких випадках ви можете визначити власні пункти меню:
const contextMenu = new ContextMenuPlugin<Schemes>({
items(context, plugin) {
if (context === 'root') {
return {
searchBar: false,
list: [
{ label: 'Кастомний', key: '1', handler: () => console.log('Кастомний') },
{
label: 'Колекція', key: '1', handler: () => null,
subitems: [
{ label: 'Підпункт', key: '1', handler: () => console.log('Підпункт') }
]
}
]
}
}
return {
searchBar: false,
list: []
}
}
})
де context
- це 'root'
, екземпляр вузла або екземпляр з'єднання
Щоб вручну відкрити контекстне меню, потрібно створити подію типу PointerEvent
з необхідними координатами та викликати метод area.emit()
:
const event = new PointerEvent('contextmenu', {
clientX: x,
clientY: y,
})
await area.emit({ type: 'contextmenu', data: { event, context } })
де
x
, y
- це числові значення (наприклад координати курсору, які ви повинні отримати окремо),context
- може бути 'root'
або екземпляр вузла, з'єднання або іншого виду елдементів вашого редактораПерегляньте повний результат на сторінці прикладу Контекстне меню.