@drghaliasri/butex 5.4.6 → 5.5.1

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.
package/dist/index.mjs CHANGED
@@ -2603,7 +2603,8 @@ ${BUTEX_FONT_FACE_CSS}
2603
2603
  transition: box-shadow 0.15s ease, border-color 0.15s ease;
2604
2604
  }
2605
2605
 
2606
- .surface:focus {
2606
+ .surface:focus,
2607
+ .surface.surface--typing-focus {
2607
2608
  border-color: var(--butex-focus-border, rgba(13, 148, 136, 0.45));
2608
2609
  box-shadow: 0 0 0 3px var(--butex-focus-shadow, rgba(13, 148, 136, 0.12));
2609
2610
  }
@@ -5750,7 +5751,7 @@ function buildNodeBody(node, buildChain, side, digitForm = "western", uiLocale =
5750
5751
 
5751
5752
  // src/editor/runtime.ts
5752
5753
  function createEditorRuntime(options) {
5753
- const { surfaceEl } = options;
5754
+ const { surfaceEl, inputEl } = options;
5754
5755
  const buttonElements = options.buttonElements ?? {};
5755
5756
  const outsidePointerIgnoreSelectors = options.outsidePointerIgnoreSelectors ?? [];
5756
5757
  let session = options.initialSession ?? createStarterSession();
@@ -5764,6 +5765,23 @@ function createEditorRuntime(options) {
5764
5765
  let dragSelecting = false;
5765
5766
  let dragChainId = null;
5766
5767
  let dragChanged = false;
5768
+ let composingInput = false;
5769
+ let pendingCompositionText = null;
5770
+ function resetInputElement() {
5771
+ if (!inputEl) {
5772
+ return;
5773
+ }
5774
+ inputEl.value = "";
5775
+ }
5776
+ function focusInput() {
5777
+ if (!inputEl) {
5778
+ surfaceEl.focus();
5779
+ return;
5780
+ }
5781
+ inputEl.focus({ preventScroll: true });
5782
+ const end = inputEl.value.length;
5783
+ inputEl.setSelectionRange(end, end);
5784
+ }
5767
5785
  function notifySessionChange() {
5768
5786
  options.onSessionChange?.(session);
5769
5787
  }
@@ -6028,7 +6046,7 @@ function createEditorRuntime(options) {
6028
6046
  event.preventDefault();
6029
6047
  event.stopPropagation();
6030
6048
  startDragSelection(chainId, index);
6031
- surfaceEl.focus();
6049
+ focusInput();
6032
6050
  });
6033
6051
  slot.addEventListener("click", (event) => {
6034
6052
  if (dragChanged) {
@@ -6038,7 +6056,7 @@ function createEditorRuntime(options) {
6038
6056
  return;
6039
6057
  }
6040
6058
  applyTransient((prev) => setCaret(prev, chainId, index));
6041
- surfaceEl.focus();
6059
+ focusInput();
6042
6060
  });
6043
6061
  if (session.caret.chainId === chainId && session.caret.index === index) {
6044
6062
  const caret = document.createElement("span");
@@ -6070,7 +6088,7 @@ function createEditorRuntime(options) {
6070
6088
  event.preventDefault();
6071
6089
  event.stopPropagation();
6072
6090
  startDragSelection(chainId, indexInChain);
6073
- surfaceEl.focus();
6091
+ focusInput();
6074
6092
  });
6075
6093
  nodeEl.addEventListener("click", (event) => {
6076
6094
  if (dragChanged) {
@@ -6081,7 +6099,7 @@ function createEditorRuntime(options) {
6081
6099
  }
6082
6100
  event.stopPropagation();
6083
6101
  applyTransient((prev) => selectNode(prev, node.id));
6084
- surfaceEl.focus();
6102
+ focusInput();
6085
6103
  });
6086
6104
  const body = document.createElement("span");
6087
6105
  body.className = "node-body";
@@ -6116,7 +6134,7 @@ function createEditorRuntime(options) {
6116
6134
  const activeTree = session[activeTreeKey(session.activeSide)];
6117
6135
  surfaceEl.appendChild(buildChain(activeTree));
6118
6136
  if (initialKeyboardFocusPending) {
6119
- requestAnimationFrame(() => surfaceEl.focus());
6137
+ requestAnimationFrame(focusInput);
6120
6138
  initialKeyboardFocusPending = false;
6121
6139
  }
6122
6140
  notifySessionChange();
@@ -6154,7 +6172,7 @@ function createEditorRuntime(options) {
6154
6172
  }
6155
6173
  session = restored;
6156
6174
  render();
6157
- surfaceEl.focus();
6175
+ focusInput();
6158
6176
  }
6159
6177
  function performRedo() {
6160
6178
  const restored = restoreRedo(undoRedo, session);
@@ -6163,9 +6181,12 @@ function createEditorRuntime(options) {
6163
6181
  }
6164
6182
  session = restored;
6165
6183
  render();
6166
- surfaceEl.focus();
6184
+ focusInput();
6167
6185
  }
6168
6186
  function onKeyDown(event) {
6187
+ if (event.isComposing || event.key === "Process" || event.keyCode === 229) {
6188
+ return;
6189
+ }
6169
6190
  const shortcutMod = event.ctrlKey || event.metaKey;
6170
6191
  const keyLower = typeof event.key === "string" ? event.key.toLowerCase() : "";
6171
6192
  if (shortcutMod && !event.altKey && keyLower === "z") {
@@ -6264,6 +6285,70 @@ function createEditorRuntime(options) {
6264
6285
  applyStructural((prev) => insertChar(prev, char));
6265
6286
  }
6266
6287
  }
6288
+ function onBeforeInput(event) {
6289
+ if (composingInput || event.isComposing) {
6290
+ return;
6291
+ }
6292
+ if (event.inputType === "deleteContentBackward") {
6293
+ event.preventDefault();
6294
+ applyStructural((prev) => deleteBackward(prev));
6295
+ resetInputElement();
6296
+ return;
6297
+ }
6298
+ if (event.inputType === "deleteContentForward") {
6299
+ event.preventDefault();
6300
+ applyStructural((prev) => deleteForward(prev));
6301
+ resetInputElement();
6302
+ }
6303
+ }
6304
+ function onInput(event) {
6305
+ if (!inputEl || composingInput) {
6306
+ return;
6307
+ }
6308
+ const inputEvent = event;
6309
+ const text = inputEvent.data ?? inputEl.value;
6310
+ resetInputElement();
6311
+ if (pendingCompositionText !== null && (inputEvent.inputType === "insertFromComposition" || text === pendingCompositionText)) {
6312
+ pendingCompositionText = null;
6313
+ return;
6314
+ }
6315
+ pendingCompositionText = null;
6316
+ if (inputEvent.inputType === "deleteContentBackward") {
6317
+ applyStructural((prev) => deleteBackward(prev));
6318
+ return;
6319
+ }
6320
+ if (inputEvent.inputType === "deleteContentForward") {
6321
+ applyStructural((prev) => deleteForward(prev));
6322
+ return;
6323
+ }
6324
+ if (text) {
6325
+ applyStructural((prev) => pasteText(prev, text));
6326
+ }
6327
+ }
6328
+ function onCompositionStart() {
6329
+ composingInput = true;
6330
+ }
6331
+ function onCompositionEnd(event) {
6332
+ if (!inputEl) {
6333
+ return;
6334
+ }
6335
+ composingInput = false;
6336
+ const text = event.data || inputEl.value;
6337
+ resetInputElement();
6338
+ if (text) {
6339
+ applyStructural((prev) => pasteText(prev, text));
6340
+ }
6341
+ pendingCompositionText = text || null;
6342
+ window.setTimeout(() => {
6343
+ pendingCompositionText = null;
6344
+ }, 0);
6345
+ }
6346
+ function onInputFocus() {
6347
+ surfaceEl.classList.add("surface--typing-focus");
6348
+ }
6349
+ function onInputBlur() {
6350
+ surfaceEl.classList.remove("surface--typing-focus");
6351
+ }
6267
6352
  function isShortcutOnlyEvent(event) {
6268
6353
  if (!(event.ctrlKey || event.metaKey) || event.altKey) {
6269
6354
  return false;
@@ -6313,7 +6398,7 @@ function createEditorRuntime(options) {
6313
6398
  }
6314
6399
  event.preventDefault();
6315
6400
  startDragSelection(resolved.chainId, resolved.slotIndex);
6316
- surfaceEl.focus();
6401
+ focusInput();
6317
6402
  }
6318
6403
  function onSurfaceClick(event) {
6319
6404
  if (dragChanged) {
@@ -6330,7 +6415,7 @@ function createEditorRuntime(options) {
6330
6415
  } else {
6331
6416
  clearSelectionAndNodeHighlights();
6332
6417
  }
6333
- surfaceEl.focus();
6418
+ focusInput();
6334
6419
  }
6335
6420
  function onDocumentPointerDown(event) {
6336
6421
  const target = event.target;
@@ -6346,6 +6431,13 @@ function createEditorRuntime(options) {
6346
6431
  clearSelectionAndNodeHighlights();
6347
6432
  }
6348
6433
  surfaceEl.addEventListener("keydown", onKeyDown);
6434
+ inputEl?.addEventListener("keydown", onKeyDown);
6435
+ inputEl?.addEventListener("beforeinput", onBeforeInput);
6436
+ inputEl?.addEventListener("input", onInput);
6437
+ inputEl?.addEventListener("compositionstart", onCompositionStart);
6438
+ inputEl?.addEventListener("compositionend", onCompositionEnd);
6439
+ inputEl?.addEventListener("focus", onInputFocus);
6440
+ inputEl?.addEventListener("blur", onInputBlur);
6349
6441
  document.addEventListener("keydown", onDocumentKeyDown);
6350
6442
  document.addEventListener("mouseup", endDragSelection);
6351
6443
  document.addEventListener("mouseleave", endDragSelection);
@@ -6357,6 +6449,13 @@ function createEditorRuntime(options) {
6357
6449
  render,
6358
6450
  destroy: () => {
6359
6451
  surfaceEl.removeEventListener("keydown", onKeyDown);
6452
+ inputEl?.removeEventListener("keydown", onKeyDown);
6453
+ inputEl?.removeEventListener("beforeinput", onBeforeInput);
6454
+ inputEl?.removeEventListener("input", onInput);
6455
+ inputEl?.removeEventListener("compositionstart", onCompositionStart);
6456
+ inputEl?.removeEventListener("compositionend", onCompositionEnd);
6457
+ inputEl?.removeEventListener("focus", onInputFocus);
6458
+ inputEl?.removeEventListener("blur", onInputBlur);
6360
6459
  document.removeEventListener("keydown", onDocumentKeyDown);
6361
6460
  document.removeEventListener("mouseup", endDragSelection);
6362
6461
  document.removeEventListener("mouseleave", endDragSelection);
@@ -6377,6 +6476,7 @@ function createEditorRuntime(options) {
6377
6476
  uiLocale = locale;
6378
6477
  render();
6379
6478
  },
6479
+ focusInput,
6380
6480
  performUndo,
6381
6481
  performRedo,
6382
6482
  performCopy,
@@ -6384,27 +6484,27 @@ function createEditorRuntime(options) {
6384
6484
  performPaste,
6385
6485
  toggleSide: () => {
6386
6486
  applyTransient((prev) => switchSide(prev));
6387
- surfaceEl.focus();
6487
+ focusInput();
6388
6488
  },
6389
6489
  toggleSplitLeafTyping: () => {
6390
6490
  applyStructural((prev) => setSplitLeafTyping(prev, !prev.splitLeafTyping));
6391
- surfaceEl.focus();
6491
+ focusInput();
6392
6492
  },
6393
6493
  toggleArabicReverseNumberTyping: () => {
6394
6494
  applyStructural((prev) => setArabicReverseNumberTyping(prev, !prev.arabicReverseNumberTyping));
6395
- surfaceEl.focus();
6495
+ focusInput();
6396
6496
  },
6397
6497
  toggleTakweenCharacterFont: () => {
6398
6498
  applyTransient((prev) => toggleTakweenCharacterFont(prev));
6399
- surfaceEl.focus();
6499
+ focusInput();
6400
6500
  },
6401
6501
  setCurrentCharacterFont: (fontId) => {
6402
6502
  applyTransient((prev) => setCurrentCharacterFont(prev, fontId));
6403
- surfaceEl.focus();
6503
+ focusInput();
6404
6504
  },
6405
6505
  setCurrentDigitForm: (digitForm) => {
6406
6506
  applyStructural((prev) => setCurrentDigitForm(prev, digitForm));
6407
- surfaceEl.focus();
6507
+ focusInput();
6408
6508
  },
6409
6509
  insertDelimiterByKind: (kind) => {
6410
6510
  if (kind === "paren") {
@@ -6414,79 +6514,79 @@ function createEditorRuntime(options) {
6414
6514
  } else {
6415
6515
  applyStructural((prev) => insertDelimiterPair(prev, "\\left\\{", "\\right\\}"));
6416
6516
  }
6417
- surfaceEl.focus();
6517
+ focusInput();
6418
6518
  },
6419
6519
  insertFraction: () => {
6420
6520
  applyStructural((prev) => insertFraction(prev));
6421
- surfaceEl.focus();
6521
+ focusInput();
6422
6522
  },
6423
6523
  insertFirstDerivative: () => {
6424
6524
  applyStructural((prev) => insertFirstDerivative(prev));
6425
- surfaceEl.focus();
6525
+ focusInput();
6426
6526
  },
6427
6527
  insertSecondDerivative: () => {
6428
6528
  applyStructural((prev) => insertSecondDerivative(prev));
6429
- surfaceEl.focus();
6529
+ focusInput();
6430
6530
  },
6431
6531
  insertMatrixEnv: (style, rows, columns) => {
6432
6532
  applyStructural((prev) => insertMatrixEnv(prev, style, rows, columns));
6433
- surfaceEl.focus();
6533
+ focusInput();
6434
6534
  },
6435
6535
  insertArrayEnv: (rows, columns) => {
6436
6536
  applyStructural((prev) => insertArrayEnv(prev, rows, columns));
6437
- surfaceEl.focus();
6537
+ focusInput();
6438
6538
  },
6439
6539
  insertAlignedEnv: (rows, columns) => {
6440
6540
  applyStructural((prev) => insertAlignedEnv(prev, rows, columns));
6441
- surfaceEl.focus();
6541
+ focusInput();
6442
6542
  },
6443
6543
  insertSqrt: () => {
6444
6544
  applyStructural((prev) => insertSqrt(prev));
6445
- surfaceEl.focus();
6545
+ focusInput();
6446
6546
  },
6447
6547
  insertOverset: () => {
6448
6548
  applyStructural((prev) => insertOverset(prev));
6449
- surfaceEl.focus();
6549
+ focusInput();
6450
6550
  },
6451
6551
  insertUnderset: () => {
6452
6552
  applyStructural((prev) => insertUnderset(prev));
6453
- surfaceEl.focus();
6553
+ focusInput();
6454
6554
  },
6455
6555
  insertLimitsSeriesTemplate: (commandId) => {
6456
6556
  applyStructural((prev) => insertLimitsSeriesTemplate(prev, commandId));
6457
- surfaceEl.focus();
6557
+ focusInput();
6458
6558
  },
6459
6559
  insertAccentPair: () => {
6460
6560
  applyStructural((prev) => insertAccentPair(prev));
6461
- surfaceEl.focus();
6561
+ focusInput();
6462
6562
  },
6463
6563
  insertAccent: (accentId) => {
6464
6564
  applyStructural((prev) => insertAccent(prev, accentId));
6465
- surfaceEl.focus();
6565
+ focusInput();
6466
6566
  },
6467
6567
  insertAtomicCommand: (commandId) => {
6468
6568
  applyStructural((prev) => insertAtomicCommand(prev, commandId));
6469
- surfaceEl.focus();
6569
+ focusInput();
6470
6570
  },
6471
6571
  insertAtomicOperatorCommand: (commandId) => {
6472
6572
  applyStructural((prev) => insertAtomicOperatorCommand(prev, commandId));
6473
- surfaceEl.focus();
6573
+ focusInput();
6474
6574
  },
6475
6575
  addSup: () => {
6476
6576
  applyStructural((prev) => addSup(prev));
6477
- surfaceEl.focus();
6577
+ focusInput();
6478
6578
  },
6479
6579
  addSub: () => {
6480
6580
  applyStructural((prev) => addSub(prev));
6481
- surfaceEl.focus();
6581
+ focusInput();
6482
6582
  },
6483
6583
  removeSup: () => {
6484
6584
  applyStructural((prev) => removeSup(prev));
6485
- surfaceEl.focus();
6585
+ focusInput();
6486
6586
  },
6487
6587
  removeSub: () => {
6488
6588
  applyStructural((prev) => removeSub(prev));
6489
- surfaceEl.focus();
6589
+ focusInput();
6490
6590
  },
6491
6591
  setMatrixEnvStyle: (style) => {
6492
6592
  applyStructural((prev) => setMatrixEnvStyle(prev, style));
@@ -6508,7 +6608,7 @@ function createEditorRuntime(options) {
6508
6608
  },
6509
6609
  deleteStructure: () => {
6510
6610
  applyStructural((prev) => deleteStructure(prev));
6511
- surfaceEl.focus();
6611
+ focusInput();
6512
6612
  }
6513
6613
  };
6514
6614
  render();