mirror of
https://github.com/excalidraw/excalidraw
synced 2025-07-25 13:58:22 +08:00
feat: expose applyTo
options, don't commit empty text element (#9744)
* Expose applyTo options, skip re-draw for empty text * Don't commit empty text elements
This commit is contained in:
@ -27,6 +27,8 @@ import {
|
||||
isImageElement,
|
||||
} from "./index";
|
||||
|
||||
import type { ApplyToOptions } from "./delta";
|
||||
|
||||
import type {
|
||||
ExcalidrawElement,
|
||||
OrderedExcalidrawElement,
|
||||
@ -570,9 +572,15 @@ export class StoreDelta {
|
||||
delta: StoreDelta,
|
||||
elements: SceneElementsMap,
|
||||
appState: AppState,
|
||||
options: ApplyToOptions = {
|
||||
excludedProperties: new Set(),
|
||||
},
|
||||
): [SceneElementsMap, AppState, boolean] {
|
||||
const [nextElements, elementsContainVisibleChange] =
|
||||
delta.elements.applyTo(elements);
|
||||
const [nextElements, elementsContainVisibleChange] = delta.elements.applyTo(
|
||||
elements,
|
||||
StoreSnapshot.empty().elements,
|
||||
options,
|
||||
);
|
||||
|
||||
const [nextAppState, appStateContainsVisibleChange] =
|
||||
delta.appState.applyTo(appState, nextElements);
|
||||
|
@ -4925,7 +4925,17 @@ class App extends React.Component<AppProps, AppState> {
|
||||
}),
|
||||
onSubmit: withBatchedUpdates(({ viaKeyboard, nextOriginalText }) => {
|
||||
const isDeleted = !nextOriginalText.trim();
|
||||
updateElement(nextOriginalText, isDeleted);
|
||||
|
||||
if (isDeleted && !isExistingElement) {
|
||||
// let's just remove the element from the scene, as it's an empty just created text element
|
||||
this.scene.replaceAllElements(
|
||||
this.scene
|
||||
.getElementsIncludingDeleted()
|
||||
.filter((x) => x.id !== element.id),
|
||||
);
|
||||
} else {
|
||||
updateElement(nextOriginalText, isDeleted);
|
||||
}
|
||||
// select the created text element only if submitting via keyboard
|
||||
// (when submitting via click it should act as signal to deselect)
|
||||
if (!isDeleted && viaKeyboard) {
|
||||
@ -4954,9 +4964,10 @@ class App extends React.Component<AppProps, AppState> {
|
||||
element,
|
||||
]);
|
||||
}
|
||||
if (!isDeleted || isExistingElement) {
|
||||
this.store.scheduleCapture();
|
||||
}
|
||||
|
||||
// we need to record either way, whether the text element was added or removed
|
||||
// since we need to sync this delta to other clients, otherwise it would end up with inconsistencies
|
||||
this.store.scheduleCapture();
|
||||
|
||||
flushSync(() => {
|
||||
this.setState({
|
||||
|
@ -704,7 +704,7 @@ describe("textWysiwyg", () => {
|
||||
rectangle.x + rectangle.width / 2,
|
||||
rectangle.y + rectangle.height / 2,
|
||||
);
|
||||
expect(h.elements.length).toBe(3);
|
||||
expect(h.elements.length).toBe(2);
|
||||
|
||||
text = h.elements[1] as ExcalidrawTextElementWithContainer;
|
||||
expect(text.type).toBe("text");
|
||||
@ -1198,7 +1198,7 @@ describe("textWysiwyg", () => {
|
||||
updateTextEditor(editor, " ");
|
||||
Keyboard.exitTextEditor(editor);
|
||||
expect(rectangle.boundElements).toStrictEqual([]);
|
||||
expect(h.elements[1].isDeleted).toBe(true);
|
||||
expect(h.elements[1]).toBeUndefined();
|
||||
});
|
||||
|
||||
it("should restore original container height and clear cache once text is unbind", async () => {
|
||||
|
Reference in New Issue
Block a user