mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
feat: add props.onDuplicate
(#9117)
* feat: add `props.onDuplicate` * docs * clarify docs * fix docs
This commit is contained in:
parent
9e49c9254b
commit
c8f4a4cb41
4 changed files with 51 additions and 4 deletions
|
@ -69,8 +69,20 @@ export const actionDuplicateSelection = register({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const nextState = duplicateElements(elements, appState);
|
||||||
|
|
||||||
|
if (app.props.onDuplicate && nextState.elements) {
|
||||||
|
const mappedElements = app.props.onDuplicate(
|
||||||
|
nextState.elements,
|
||||||
|
elements,
|
||||||
|
);
|
||||||
|
if (mappedElements) {
|
||||||
|
nextState.elements = mappedElements;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...duplicateElements(elements, appState),
|
...nextState,
|
||||||
storeAction: StoreAction.CAPTURE,
|
storeAction: StoreAction.CAPTURE,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -92,7 +104,7 @@ export const actionDuplicateSelection = register({
|
||||||
const duplicateElements = (
|
const duplicateElements = (
|
||||||
elements: readonly ExcalidrawElement[],
|
elements: readonly ExcalidrawElement[],
|
||||||
appState: AppState,
|
appState: AppState,
|
||||||
): Partial<ActionResult> => {
|
): Partial<Exclude<ActionResult, false>> => {
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
const groupIdMap = new Map();
|
const groupIdMap = new Map();
|
||||||
|
|
|
@ -3228,7 +3228,14 @@ class App extends React.Component<AppProps, AppState> {
|
||||||
);
|
);
|
||||||
|
|
||||||
const prevElements = this.scene.getElementsIncludingDeleted();
|
const prevElements = this.scene.getElementsIncludingDeleted();
|
||||||
const nextElements = [...prevElements, ...newElements];
|
let nextElements = [...prevElements, ...newElements];
|
||||||
|
|
||||||
|
const mappedNewSceneElements = this.props.onDuplicate?.(
|
||||||
|
nextElements,
|
||||||
|
prevElements,
|
||||||
|
);
|
||||||
|
|
||||||
|
nextElements = mappedNewSceneElements || nextElements;
|
||||||
|
|
||||||
syncMovedIndices(nextElements, arrayToMap(newElements));
|
syncMovedIndices(nextElements, arrayToMap(newElements));
|
||||||
|
|
||||||
|
@ -8442,7 +8449,17 @@ class App extends React.Component<AppProps, AppState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const nextSceneElements = [...nextElements, ...elementsToAppend];
|
let nextSceneElements: ExcalidrawElement[] = [
|
||||||
|
...nextElements,
|
||||||
|
...elementsToAppend,
|
||||||
|
];
|
||||||
|
|
||||||
|
const mappedNewSceneElements = this.props.onDuplicate?.(
|
||||||
|
nextSceneElements,
|
||||||
|
elements,
|
||||||
|
);
|
||||||
|
|
||||||
|
nextSceneElements = mappedNewSceneElements || nextSceneElements;
|
||||||
|
|
||||||
syncMovedIndices(nextSceneElements, arrayToMap(elementsToAppend));
|
syncMovedIndices(nextSceneElements, arrayToMap(elementsToAppend));
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ const ExcalidrawBase = (props: ExcalidrawProps) => {
|
||||||
onPointerDown,
|
onPointerDown,
|
||||||
onPointerUp,
|
onPointerUp,
|
||||||
onScrollChange,
|
onScrollChange,
|
||||||
|
onDuplicate,
|
||||||
children,
|
children,
|
||||||
validateEmbeddable,
|
validateEmbeddable,
|
||||||
renderEmbeddable,
|
renderEmbeddable,
|
||||||
|
@ -136,6 +137,7 @@ const ExcalidrawBase = (props: ExcalidrawProps) => {
|
||||||
onPointerDown={onPointerDown}
|
onPointerDown={onPointerDown}
|
||||||
onPointerUp={onPointerUp}
|
onPointerUp={onPointerUp}
|
||||||
onScrollChange={onScrollChange}
|
onScrollChange={onScrollChange}
|
||||||
|
onDuplicate={onDuplicate}
|
||||||
validateEmbeddable={validateEmbeddable}
|
validateEmbeddable={validateEmbeddable}
|
||||||
renderEmbeddable={renderEmbeddable}
|
renderEmbeddable={renderEmbeddable}
|
||||||
aiEnabled={aiEnabled !== false}
|
aiEnabled={aiEnabled !== false}
|
||||||
|
|
|
@ -512,6 +512,22 @@ export interface ExcalidrawProps {
|
||||||
data: ClipboardData,
|
data: ClipboardData,
|
||||||
event: ClipboardEvent | null,
|
event: ClipboardEvent | null,
|
||||||
) => Promise<boolean> | boolean;
|
) => Promise<boolean> | boolean;
|
||||||
|
/**
|
||||||
|
* Called when element(s) are duplicated so you can listen or modify as
|
||||||
|
* needed.
|
||||||
|
*
|
||||||
|
* Called when duplicating via mouse-drag, keyboard, paste, library insert
|
||||||
|
* etc.
|
||||||
|
*
|
||||||
|
* Returned elements will be used in place of the next elements
|
||||||
|
* (you should return all elements, including deleted, and not mutate
|
||||||
|
* the element if changes are made)
|
||||||
|
*/
|
||||||
|
onDuplicate?: (
|
||||||
|
nextElements: readonly ExcalidrawElement[],
|
||||||
|
/** excludes the duplicated elements */
|
||||||
|
prevElements: readonly ExcalidrawElement[],
|
||||||
|
) => ExcalidrawElement[] | void;
|
||||||
renderTopRightUI?: (
|
renderTopRightUI?: (
|
||||||
isMobile: boolean,
|
isMobile: boolean,
|
||||||
appState: UIAppState,
|
appState: UIAppState,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue