function shapeEditEvtProc(canvas, svgGrp, shapeData, connectorsInnerPosition, textSettings, settingsPnlCreateFn, onTextChange) {
	/** @type {{dispose():void, draw():void}} */
	let textEditor;

	/** @type { {position:(bottomX:number, bottomY:number)=>void, del:()=>void} } */
	let settingsPnl;

	function unSelect() {
		textEditor?.dispose(); textEditor = null;
		settingsPnl?.del(); settingsPnl = null;
	}

	/** @param {string} txt */
	function onTxtChange(txt) {
		shapeData.title = txt;
		onTextChange();
	}

	const settingPnlCreate = settingsPnlCreateFn ?? settingsPnlCreate;
	const shapeProc = shapeEvtProc(canvas, svgGrp, shapeData, connectorsInnerPosition,
		// onEdit
		() => {
			textEditor = textareaCreate(textSettings.el, textSettings.vMid, shapeData.title, onTxtChange, onTxtChange);

			const position = svgGrp.getBoundingClientRect();
			settingsPnl = settingPnlCreate(canvas, svgGrp, position.left + 10, position.top + 10);
		},
		// onUnselect
		unSelect
	);

	if (shapeData.styles) { classAdd(svgGrp, ...shapeData.styles); }

	svgGrp[ShapeSmbl].del = function() {
		shapeProc.del();
		svgGrp.remove();
	};

	return {
		draw: () => {
			shapeProc.drawPosition();

			if (settingsPnl) {
				const position = svgGrp.getBoundingClientRect();
				settingsPnl.position(position.left + 10, position.top + 10);
			}

			if (textEditor) { textEditor.draw(); }
		}
	};
}
provides:
 - shape move
 - connectors
 - copy fn

 - text editor
 - standard edit panel
 - onTextChange callback
@param {CanvasElement} canvas
@param {ShapeElement} svgGrp
@param {ShapeData & { title?: string, styles?: string[]}} shapeData
@param {ConnectorsData} connectorsInnerPosition
@param { {el:SVGTextElement, vMid: number} } textSettings vMid in em
@param {{():void}} onTextChange
@param {SettingsPnlCreateFn} settingsPnlCreateFn