From 8d1a92579b28baee43a048830521ed029657c02e Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 25 Apr 2025 19:14:55 +0200 Subject: [PATCH] refactor: use CellEditorHandler plugin in selected-features examples This plugin allows you to edit cell labels, a feature enabled in related examples using Graph. Also improve JSDoc CellEditorHandler. --- .../core/src/view/mixins/EventsMixin.type.ts | 7 +- .../src/view/plugins/CellEditorHandler.ts | 91 +++++++++---------- .../js-example-selected-features/src/index.js | 2 + .../ts-example-selected-features/src/main.ts | 2 + 4 files changed, 52 insertions(+), 50 deletions(-) diff --git a/packages/core/src/view/mixins/EventsMixin.type.ts b/packages/core/src/view/mixins/EventsMixin.type.ts index f7b98e2606..6189f062f7 100644 --- a/packages/core/src/view/mixins/EventsMixin.type.ts +++ b/packages/core/src/view/mixins/EventsMixin.type.ts @@ -53,9 +53,10 @@ declare module '../AbstractGraph' { invokesStopCellEditing: boolean; /** - * If `true`, pressing the enter key without pressing control or shift will stop - * editing and accept the new value. This is used in {@link CellEditorHandler} to stop - * cell editing. Note: You can always use F2 and escape to stop editing. + * If `true`, pressing the enter key without pressing control or shift will stop editing and accept the new value. + * This is used in {@link CellEditorHandler} to stop cell editing. + * + * Note: The F2 (accept change) and escape keys (undo change) can always be used to stop editing. * @default false */ enterStopsCellEditing: boolean; diff --git a/packages/core/src/view/plugins/CellEditorHandler.ts b/packages/core/src/view/plugins/CellEditorHandler.ts index 202654af15..8ba3542a4c 100644 --- a/packages/core/src/view/plugins/CellEditorHandler.ts +++ b/packages/core/src/view/plugins/CellEditorHandler.ts @@ -53,22 +53,24 @@ import type { GraphPlugin } from '../../types'; import type TooltipHandler from './TooltipHandler'; /** - * In-place editor for the graph. To control this editor, use - * {@link AbstractGraph.invokesStopCellEditing}, {@link AbstractGraph.enterStopsCellEditing} and - * {@link AbstractGraph.escapeEnabled}. If {@link AbstractGraph.enterStopsCellEditing} is true then - * ctrl-enter or shift-enter can be used to create a linefeed. The F2 and - * escape keys can always be used to stop editing. + * In-place editor for the graph. * - * To customize the location of the textbox in the graph, override - * as follows: + * To control this editor, use: + * - {@link AbstractGraph.invokesStopCellEditing} + * - {@link AbstractGraph.enterStopsCellEditing} + * - {@link AbstractGraph.escapeEnabled} + * + * If {@link AbstractGraph.enterStopsCellEditing} is `true` then ctrl-enter or shift-enter can be used to create a linefeed. + * + * The F2 (accept change) and escape keys (undo change) can always be used to stop editing. + * + * To customize the location of the textbox in the graph, override {@link getEditorBounds} as follows: * * ```javascript - * graph.cellEditor.getEditorBounds = (state)=> - * { - * let result = getEditorBounds.apply(this, arguments); + * graph.cellEditor.getEditorBounds = (state) => { + * const result = super.getEditorBounds(state); * - * if (this.graph.getDataModel().isEdge(state.cell)) - * { + * if (this.graph.getDataModel().isEdge(state.cell)) { * result.x = state.getCenterX() - result.width / 2; * result.y = state.getCenterY() - result.height / 2; * } @@ -77,74 +79,69 @@ import type TooltipHandler from './TooltipHandler'; * }; * ``` * - * Note that this hook is only called if is false. If is true, - * then {@link Shape#getLabelBounds} is used to compute the current bounds of the textbox. - * - * The textarea uses the mxCellEditor CSS class. You can modify this class in - * your custom CSS. Note: You should modify the CSS after loading the client - * in the page. + * Note that this hook is only called if {@link autoSize} is `false`. + * If {@link autoSize} is `true`, then {@link Shape.getLabelBounds} is used to compute the current bounds of the textbox. * + * The textarea uses the `mxCellEditor` CSS class. You can modify this class in your custom CSS. + * Example: * * To only allow numeric input in the in-place editor, use the following code. * * ```javascript - * let text = graph.cellEditor.textarea; + * const text = graph.cellEditor.textarea; * - * mxEvent.addListener(text, 'keydown', function (evt) - * { + * InternalEvent.addListener(text, 'keydown', function (evt) { * if (!(evt.keyCode >= 48 && evt.keyCode <= 57) && - * !(evt.keyCode >= 96 && evt.keyCode <= 105)) - * { - * mxEvent.consume(evt); + * !(evt.keyCode >= 96 && evt.keyCode <= 105)) { + * InternalEvent.consume(evt); * } * }); * ``` * - * Placeholder: + * ### Placeholder * - * To implement a placeholder for cells without a label, use the - * variable. + * To implement a placeholder for cells without a label, use the {@link emptyLabelText} variable. * - * Resize in Chrome: * - * Resize of the textarea is disabled by default. If you want to enable - * this feature extend and set this.textarea.style.resize = ''. + * ### Resize the textarea + * + * Resize of the textarea is disabled by default. + * If you want to enable this feature extend {@link init} and set `this.textarea.style.resize = ''`. + * + * + * ### Editing on key press * * To start editing on a key press event, the container of the graph * should have focus or a focusable parent should be used to add the * key press handler as follows. * * ```javascript - * mxEvent.addListener(graph.container, 'keypress', mxUtils.bind(this, (evt)=> - * { - * if (!graph.isEditing() && !graph.isSelectionEmpty() && evt.which !== 0 && - * !mxEvent.isAltDown(evt) && !mxEvent.isControlDown(evt) && !mxEvent.isMetaDown(evt)) - * { + * InternalEvent.addListener(graph.container, 'keypress', (evt) => { + * if (!graph.isEditing() && !graph.isSelectionEmpty() && evt.which !== 0 + * && !eventUtils.isAltDown(evt) + * && !eventUtils.isControlDown(evt) + * && !eventUtils.isMetaDown(evt)) { * graph.startEditing(); * - * if (Client.IS_FF) - * { + * if (Client.IS_FF) { * graph.cellEditor.textarea.value = String.fromCharCode(evt.which); * } * } - * })); + * }); * ``` * - * To allow focus for a DIV, and hence to receive key press events, some browsers - * require it to have a valid tabindex attribute. In this case the following - * code may be used to keep the container focused. + * To allow focus for a DIV, and hence to receive key press events, some browsers require it to have a valid tabindex attribute. + * In this case the following code may be used to keep the container focused. * * ```javascript - * let graphFireMouseEvent = graph.fireMouseEvent; - * graph.fireMouseEvent = (evtName, me, sender)=> - * { - * if (evtName == mxEvent.MOUSE_DOWN) - * { + * const graphFireMouseEvent = graph.fireMouseEvent; + * graph.fireMouseEvent = (evtName, me, sender) => { + * if (evtName == mxEvent.MOUSE_DOWN) { * this.container.focus(); * } * - * graphFireMouseEvent.apply(this, arguments); + * graphFireMouseEvent.apply(this, [evtName, me, sender]); * }; * ``` * diff --git a/packages/js-example-selected-features/src/index.js b/packages/js-example-selected-features/src/index.js index fe82e29d41..fb1c227ff4 100644 --- a/packages/js-example-selected-features/src/index.js +++ b/packages/js-example-selected-features/src/index.js @@ -18,6 +18,7 @@ import '@maxgraph/core/css/common.css'; // required by RubberBandHandler import './style.css'; import { BaseGraph, + CellEditorHandler, constants, DomHelpers, EdgeMarker, @@ -80,6 +81,7 @@ const initializeGraph = (container) => { const graph = new CustomGraph({ container, plugins: [ + CellEditorHandler, // Enables in-place editing of cell labels PanningHandler, // Enables panning with the mouse RubberBandHandler, // Enables rubber band selection SelectionCellsHandler, // Enables management of selected cells diff --git a/packages/ts-example-selected-features/src/main.ts b/packages/ts-example-selected-features/src/main.ts index aee4ee63bb..52adbd3c46 100644 --- a/packages/ts-example-selected-features/src/main.ts +++ b/packages/ts-example-selected-features/src/main.ts @@ -18,6 +18,7 @@ import '@maxgraph/core/css/common.css'; // required by RubberBandHandler import './style.css'; import { BaseGraph, + CellEditorHandler, CellRenderer, constants, EdgeMarker, @@ -61,6 +62,7 @@ const initializeGraph = (container: HTMLElement) => { const graph = new CustomGraph({ container, plugins: [ + CellEditorHandler, // Enables in-place editing of cell labels FitPlugin, // Enables the fitCenter method PanningHandler, // Enables panning with the mouse RubberBandHandler, // Enables rubber band selection