diff --git a/src/components/App.tsx b/src/components/App.tsx index 2a7b99a87..9003f8ff3 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -452,6 +452,16 @@ class App extends React.Component { width, height, }); + + this.scene.addCallback(() => { + const customElementConfig = getCustomElementConfig( + this.props.customElementsConfig, + customElement.customType, + ); + if (customElementConfig && customElementConfig.onCreate) { + customElementConfig.onCreate(customElement); + } + }); this.scene.replaceAllElements([ ...this.scene.getElementsIncludingDeleted(), customElement, diff --git a/src/constants.ts b/src/constants.ts index d8e3bffb0..aea189b06 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -160,6 +160,7 @@ export const DEFAULT_CUSTOM_ELEMENT_CONFIG: Required = { width: 40, height: 40, stackedOnTop: false, + onCreate: () => {}, }; export const MQ_MAX_WIDTH_PORTRAIT = 730; export const MQ_MAX_WIDTH_LANDSCAPE = 1000; diff --git a/src/packages/excalidraw/example/App.js b/src/packages/excalidraw/example/App.js index 64f71af68..7def20a25 100644 --- a/src/packages/excalidraw/example/App.js +++ b/src/packages/excalidraw/example/App.js @@ -194,6 +194,10 @@ export default function App() { ); }; + const onCreate = (element) => { + setTimeout(() => addTextArea(element), 0); + }; + const getCustomElementsConfig = () => { return [ { @@ -217,6 +221,7 @@ export default function App() { `)}`, transformHandles: false, stackedOnTop: true, + onCreate, }, { type: "custom", @@ -244,36 +249,39 @@ export default function App() { ]; }; + const addTextArea = (element) => { + const { x: viewPortX, y: viewPortY } = sceneCoordsToViewportCoords( + { + sceneX: element.x, + sceneY: element.y, + }, + excalidrawRef.current.getAppState(), + ); + const textarea = document.createElement("textarea"); + Object.assign(textarea.style, { + position: "absolute", + display: "inline-block", + left: `${viewPortX + element.width / 2}px`, + top: `${viewPortY + element.height / 2}px`, + height: `${100}px`, + width: `${100}px`, + zIndex: 10, + className: "comment-textarea", + whiteSpace: "pre-wrap", + fontSize: "13px", + }); + textarea.placeholder = "Start typing your comments"; + + textarea.onblur = () => { + textarea.remove(); + }; + excalidrawWrapperRef.current.querySelector(".excalidraw").append(textarea); + textarea.focus(); + }; + const onElementClick = (element) => { if (element.type === "custom" && element.customType === "comment") { - const { x: viewPortX, y: viewPortY } = sceneCoordsToViewportCoords( - { - sceneX: element.x, - sceneY: element.y, - }, - excalidrawRef.current.getAppState(), - ); - const textarea = document.createElement("textarea"); - Object.assign(textarea.style, { - position: "absolute", - display: "inline-block", - left: `${viewPortX + element.width / 2}px`, - top: `${viewPortY + element.height / 2}px`, - height: `${100}px`, - width: `${100}px`, - zIndex: 10, - className: "comment-textarea", - whiteSpace: "pre-wrap", - fontSize: "13px", - }); - textarea.placeholder = "Start typing your comments"; - textarea.onblur = () => { - textarea.remove(); - }; - excalidrawWrapperRef.current - .querySelector(".excalidraw") - .append(textarea); - textarea.focus(); + addTextArea(element); } }; return ( diff --git a/src/types.ts b/src/types.ts index e42c98a68..9198c39fd 100644 --- a/src/types.ts +++ b/src/types.ts @@ -232,6 +232,7 @@ export type CustomElementConfig = { width?: number; height?: number; stackedOnTop: boolean; + onCreate?: (element: ExcalidrawElement) => void; }; export interface ExcalidrawProps { onChange?: (