@excalidraw/element 0.18.0-816c81c → 0.18.0-81ab857

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/dev/index.js +125 -30
  2. package/dist/dev/index.js.map +2 -2
  3. package/dist/prod/index.js +11 -10
  4. package/dist/types/element/src/selection.d.ts +5 -1
  5. package/dist/types/element/src/textElement.d.ts +1 -1
  6. package/dist/types/element/src/textWrapping.d.ts +26 -0
  7. package/dist/types/excalidraw/actions/actionAddToLibrary.d.ts +3 -3
  8. package/dist/types/excalidraw/actions/actionBoundText.d.ts +3 -3
  9. package/dist/types/excalidraw/actions/actionCanvas.d.ts +12 -12
  10. package/dist/types/excalidraw/actions/actionClipboard.d.ts +2 -2
  11. package/dist/types/excalidraw/actions/actionCropEditor.d.ts +1 -1
  12. package/dist/types/excalidraw/actions/actionDeleteSelected.d.ts +3 -3
  13. package/dist/types/excalidraw/actions/actionElementLink.d.ts +1 -1
  14. package/dist/types/excalidraw/actions/actionElementLock.d.ts +2 -2
  15. package/dist/types/excalidraw/actions/actionEmbeddable.d.ts +1 -1
  16. package/dist/types/excalidraw/actions/actionExport.d.ts +2 -2
  17. package/dist/types/excalidraw/actions/actionFrame.d.ts +4 -4
  18. package/dist/types/excalidraw/actions/actionGroup.d.ts +3 -3
  19. package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +1 -1
  20. package/dist/types/excalidraw/actions/actionLink.d.ts +1 -1
  21. package/dist/types/excalidraw/actions/actionMenu.d.ts +1 -1
  22. package/dist/types/excalidraw/actions/actionProperties.d.ts +4 -4
  23. package/dist/types/excalidraw/actions/actionSelectAll.d.ts +1 -1
  24. package/dist/types/excalidraw/actions/actionStyles.d.ts +2 -1
  25. package/dist/types/excalidraw/actions/actionTextAutoResize.d.ts +3 -3
  26. package/dist/types/excalidraw/actions/actionToggleArrowBinding.d.ts +1 -1
  27. package/dist/types/excalidraw/actions/actionToggleGridMode.d.ts +1 -1
  28. package/dist/types/excalidraw/actions/actionToggleMidpointSnapping.d.ts +1 -1
  29. package/dist/types/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +1 -1
  30. package/dist/types/excalidraw/actions/actionToggleSearchMenu.d.ts +1 -1
  31. package/dist/types/excalidraw/actions/actionToggleStats.d.ts +1 -1
  32. package/dist/types/excalidraw/actions/actionToggleViewMode.d.ts +1 -1
  33. package/dist/types/excalidraw/actions/actionToggleZenMode.d.ts +1 -1
  34. package/dist/types/excalidraw/components/App.d.ts +10 -0
  35. package/dist/types/excalidraw/components/Range.d.ts +10 -4
  36. package/dist/types/excalidraw/components/canvases/InteractiveCanvas.d.ts +1 -0
  37. package/dist/types/excalidraw/data/blob.d.ts +2 -2
  38. package/dist/types/excalidraw/data/json.d.ts +1 -1
  39. package/dist/types/excalidraw/textAutoResizeHandle.d.ts +15 -0
  40. package/dist/types/excalidraw/types.d.ts +2 -2
  41. package/dist/types/excalidraw/wysiwyg/textWysiwyg.d.ts +5 -1
  42. package/dist/types/math/src/point.d.ts +1 -1
  43. package/package.json +3 -3
package/dist/dev/index.js CHANGED
@@ -4316,91 +4316,168 @@ var parseTokens = (line2) => {
4316
4316
  return line2.normalize("NFC").split(breakLineRegex).filter(Boolean);
4317
4317
  };
4318
4318
  var wrapText = (text, font, maxWidth) => {
4319
+ return getWrappedTextLines(text, font, maxWidth).map((line2) => line2.text).join("\n");
4320
+ };
4321
+ var getHardLineBreaks = (text) => {
4322
+ let offset = 0;
4323
+ return text.split("\n").map((line2) => {
4324
+ const start = offset;
4325
+ const end = start + line2.length;
4326
+ offset = end + 1;
4327
+ return {
4328
+ text: line2,
4329
+ start,
4330
+ end
4331
+ };
4332
+ });
4333
+ };
4334
+ var getWrappedTextLines = (text, font, maxWidth) => {
4319
4335
  if (!Number.isFinite(maxWidth) || maxWidth < 0) {
4320
- return text;
4336
+ return getHardLineBreaks(text);
4321
4337
  }
4322
4338
  const lines = [];
4323
- const originalLines = text.split("\n");
4324
- for (const originalLine of originalLines) {
4325
- const currentLineWidth = getLineWidth(originalLine, font);
4326
- if (currentLineWidth <= maxWidth) {
4327
- lines.push(originalLine);
4328
- continue;
4339
+ let offset = 0;
4340
+ for (const originalLine of text.split("\n")) {
4341
+ const originalLineWidth = getLineWidth(originalLine, font);
4342
+ if (originalLineWidth <= maxWidth) {
4343
+ lines.push({
4344
+ text: originalLine,
4345
+ start: offset,
4346
+ end: offset + originalLine.length
4347
+ });
4348
+ } else {
4349
+ lines.push(...wrapLine(originalLine, font, maxWidth, offset));
4329
4350
  }
4330
- const wrappedLine = wrapLine(originalLine, font, maxWidth);
4331
- lines.push(...wrappedLine);
4351
+ offset += originalLine.length + 1;
4332
4352
  }
4333
- return lines.join("\n");
4353
+ return lines;
4334
4354
  };
4335
- var wrapLine = (line2, font, maxWidth) => {
4355
+ var wrapLine = (line2, font, maxWidth, lineStart) => {
4336
4356
  const lines = [];
4337
4357
  const tokens = parseTokens(line2);
4338
- const tokenIterator = tokens[Symbol.iterator]();
4339
4358
  let currentLine = "";
4359
+ let currentLineStart = lineStart;
4360
+ let currentLineEnd = lineStart;
4340
4361
  let currentLineWidth = 0;
4341
- let iterator = tokenIterator.next();
4342
- while (!iterator.done) {
4343
- const token = iterator.value;
4362
+ let tokenOffset = lineStart;
4363
+ let tokenIndex = 0;
4364
+ while (tokenIndex < tokens.length) {
4365
+ const token = tokens[tokenIndex];
4366
+ const tokenStart = tokenOffset;
4367
+ const tokenEnd = tokenStart + token.length;
4344
4368
  const testLine = currentLine + token;
4345
4369
  const testLineWidth = isSingleCharacter(token) ? currentLineWidth + charWidth.calculate(token, font) : getLineWidth(testLine, font);
4346
4370
  if (/\s/.test(token) || testLineWidth <= maxWidth) {
4371
+ if (!currentLine) {
4372
+ currentLineStart = tokenStart;
4373
+ }
4347
4374
  currentLine = testLine;
4375
+ currentLineEnd = tokenEnd;
4348
4376
  currentLineWidth = testLineWidth;
4349
- iterator = tokenIterator.next();
4377
+ tokenOffset = tokenEnd;
4378
+ tokenIndex++;
4350
4379
  continue;
4351
4380
  }
4352
4381
  if (!currentLine) {
4353
- const wrappedWord = wrapWord(token, font, maxWidth);
4354
- const trailingLine = wrappedWord[wrappedWord.length - 1] ?? "";
4382
+ const wrappedWord = wrapWord(token, font, maxWidth, tokenStart);
4383
+ const trailingLine = wrappedWord[wrappedWord.length - 1] ?? {
4384
+ text: "",
4385
+ start: tokenStart,
4386
+ end: tokenStart
4387
+ };
4355
4388
  const precedingLines = wrappedWord.slice(0, -1);
4356
4389
  lines.push(...precedingLines);
4357
- currentLine = trailingLine;
4358
- currentLineWidth = getLineWidth(trailingLine, font);
4359
- iterator = tokenIterator.next();
4390
+ currentLine = trailingLine.text;
4391
+ currentLineStart = trailingLine.start;
4392
+ currentLineEnd = trailingLine.end;
4393
+ currentLineWidth = getLineWidth(trailingLine.text, font);
4394
+ tokenOffset = tokenEnd;
4395
+ tokenIndex++;
4360
4396
  } else {
4361
- lines.push(currentLine.trimEnd());
4397
+ lines.push(
4398
+ trimLineEndAtSoftBreak(currentLine, currentLineStart, currentLineEnd)
4399
+ );
4362
4400
  currentLine = "";
4401
+ currentLineStart = tokenStart;
4402
+ currentLineEnd = tokenStart;
4363
4403
  currentLineWidth = 0;
4364
4404
  }
4365
4405
  }
4366
4406
  if (currentLine) {
4367
- const trailingLine = trimLine(currentLine, font, maxWidth);
4407
+ const trailingLine = trimLine(
4408
+ currentLine,
4409
+ currentLineStart,
4410
+ currentLineEnd,
4411
+ font,
4412
+ maxWidth
4413
+ );
4368
4414
  lines.push(trailingLine);
4369
4415
  }
4370
4416
  return lines;
4371
4417
  };
4372
- var wrapWord = (word, font, maxWidth) => {
4418
+ var wrapWord = (word, font, maxWidth, wordStart) => {
4373
4419
  if (getEmojiRegex().test(word)) {
4374
- return [word];
4420
+ return [
4421
+ {
4422
+ text: word,
4423
+ start: wordStart,
4424
+ end: wordStart + word.length
4425
+ }
4426
+ ];
4375
4427
  }
4376
4428
  satisfiesWordInvariant(word);
4377
4429
  const lines = [];
4378
4430
  const chars = Array.from(word);
4379
4431
  let currentLine = "";
4432
+ let currentLineStart = wordStart;
4433
+ let currentLineEnd = wordStart;
4380
4434
  let currentLineWidth = 0;
4435
+ let offset = wordStart;
4381
4436
  for (const char of chars) {
4437
+ const charStart = offset;
4438
+ const charEnd = charStart + char.length;
4382
4439
  const _charWidth = charWidth.calculate(char, font);
4383
4440
  const testLineWidth = currentLineWidth + _charWidth;
4384
4441
  if (testLineWidth <= maxWidth) {
4442
+ if (!currentLine) {
4443
+ currentLineStart = charStart;
4444
+ }
4385
4445
  currentLine = currentLine + char;
4446
+ currentLineEnd = charEnd;
4386
4447
  currentLineWidth = testLineWidth;
4448
+ offset = charEnd;
4387
4449
  continue;
4388
4450
  }
4389
4451
  if (currentLine) {
4390
- lines.push(currentLine);
4452
+ lines.push({
4453
+ text: currentLine,
4454
+ start: currentLineStart,
4455
+ end: currentLineEnd
4456
+ });
4391
4457
  }
4392
4458
  currentLine = char;
4459
+ currentLineStart = charStart;
4460
+ currentLineEnd = charEnd;
4393
4461
  currentLineWidth = _charWidth;
4462
+ offset = charEnd;
4394
4463
  }
4395
4464
  if (currentLine) {
4396
- lines.push(currentLine);
4465
+ lines.push({
4466
+ text: currentLine,
4467
+ start: currentLineStart,
4468
+ end: currentLineEnd
4469
+ });
4397
4470
  }
4398
4471
  return lines;
4399
4472
  };
4400
- var trimLine = (line2, font, maxWidth) => {
4473
+ var trimLine = (line2, start, end, font, maxWidth) => {
4401
4474
  const shouldTrimWhitespaces = getLineWidth(line2, font) > maxWidth;
4402
4475
  if (!shouldTrimWhitespaces) {
4403
- return line2;
4476
+ return {
4477
+ text: line2,
4478
+ start,
4479
+ end
4480
+ };
4404
4481
  }
4405
4482
  let [, trimmedLine, whitespaces] = line2.match(/^(.+?)(\s+)$/) ?? [
4406
4483
  line2,
@@ -4417,7 +4494,19 @@ var trimLine = (line2, font, maxWidth) => {
4417
4494
  trimmedLine = trimmedLine + whitespace;
4418
4495
  trimmedLineWidth = testLineWidth;
4419
4496
  }
4420
- return trimmedLine;
4497
+ return {
4498
+ text: trimmedLine,
4499
+ start,
4500
+ end: end - (line2.length - trimmedLine.length)
4501
+ };
4502
+ };
4503
+ var trimLineEndAtSoftBreak = (line2, start, end) => {
4504
+ const trimmedLine = line2.trimEnd();
4505
+ return {
4506
+ text: trimmedLine,
4507
+ start,
4508
+ end: end - (line2.length - trimmedLine.length)
4509
+ };
4421
4510
  };
4422
4511
  var isSingleCharacter = (maybeSingleCharacter) => {
4423
4512
  return maybeSingleCharacter.codePointAt(0) !== void 0 && maybeSingleCharacter.codePointAt(1) === void 0;
@@ -11230,6 +11319,10 @@ var getSelectionStateForElements = (targetElements, allElements, appState) => {
11230
11319
  )
11231
11320
  };
11232
11321
  };
11322
+ var getActiveTextElement = (selectedElements, appState) => {
11323
+ const activeTextElement = appState.editingTextElement || selectedElements.length === 1 && isTextElement(selectedElements[0]) && selectedElements[0];
11324
+ return activeTextElement || null;
11325
+ };
11233
11326
 
11234
11327
  // src/frame.ts
11235
11328
  var bindElementsToFramesAfterDuplication = (nextElements, origElements, origIdToDuplicateId) => {
@@ -21881,6 +21974,7 @@ export {
21881
21974
  frameAndChildrenSelectedTogether,
21882
21975
  generateLinearCollisionShape,
21883
21976
  generateRoughOptions,
21977
+ getActiveTextElement,
21884
21978
  getAllHoveredElementAtPoint,
21885
21979
  getApproxMinLineHeight,
21886
21980
  getApproxMinLineWidth,
@@ -21989,6 +22083,7 @@ export {
21989
22083
  getVisibleAndNonSelectedElements,
21990
22084
  getVisibleElements,
21991
22085
  getVisibleSceneBounds,
22086
+ getWrappedTextLines,
21992
22087
  groupByFrameLikes,
21993
22088
  groupsAreAtLeastIntersectingTheFrame,
21994
22089
  groupsAreCompletelyOutOfFrame,