@nextclaw/agent-chat-ui 0.3.1 → 0.3.2

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 (2) hide show
  1. package/dist/index.js +35 -6
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1424,6 +1424,7 @@ var ChatComposerRuntime = class {
1424
1424
  this.snapshot = this.controller.getSnapshot();
1425
1425
  this.config = null;
1426
1426
  this.isComposing = false;
1427
+ this.hasPendingImeComposition = false;
1427
1428
  this.bindRootElement = (node) => {
1428
1429
  this.rootElement = node;
1429
1430
  };
@@ -1472,11 +1473,11 @@ var ChatComposerRuntime = class {
1472
1473
  };
1473
1474
  };
1474
1475
  this.restoreDomAfterCommit = () => {
1475
- if (this.isComposing) return;
1476
+ if (this.shouldSuspendDomSync()) return;
1476
1477
  this.viewController.restoreSelectionIfFocused(this.rootElement, this.selection);
1477
1478
  };
1478
1479
  this.renderSurface = () => {
1479
- if (this.isComposing) return;
1480
+ if (this.shouldSuspendDomSync()) return;
1480
1481
  this.viewController.renderSurface({
1481
1482
  root: this.rootElement,
1482
1483
  snapshot: this.snapshot,
@@ -1487,7 +1488,7 @@ var ChatComposerRuntime = class {
1487
1488
  this.viewController.syncViewport(this.rootElement);
1488
1489
  };
1489
1490
  this.syncSelectionState = () => {
1490
- if (!this.rootElement || this.isComposing) return;
1491
+ if (!this.rootElement || this.shouldSuspendDomSync()) return;
1491
1492
  const nextSnapshot = this.viewController.syncSelectionFromRoot(this.rootElement);
1492
1493
  this.selection = nextSnapshot.selection;
1493
1494
  this.selectedRange = nextSnapshot.selection;
@@ -1495,24 +1496,28 @@ var ChatComposerRuntime = class {
1495
1496
  this.requestRender();
1496
1497
  };
1497
1498
  this.handleBeforeInput = (event) => {
1499
+ this.syncImeGuardFromInputEvent(event.nativeEvent);
1498
1500
  this.viewController.handleBeforeInput({
1499
1501
  event,
1500
1502
  disabled: this.requireConfig().disabled,
1501
- isComposing: this.isComposing,
1503
+ isComposing: this.shouldSuspendDomSync(),
1502
1504
  commitSnapshot: this.commitSnapshot
1503
1505
  });
1504
1506
  };
1505
1507
  this.handleInput = (event) => {
1508
+ this.syncImeGuardFromInputEvent(event.nativeEvent);
1506
1509
  this.viewController.handleInput({
1507
1510
  event,
1508
- isComposing: this.isComposing,
1511
+ isComposing: this.shouldSuspendDomSync(),
1509
1512
  commitSnapshot: this.commitSnapshot
1510
1513
  });
1511
1514
  };
1512
1515
  this.handleCompositionStart = () => {
1516
+ this.hasPendingImeComposition = false;
1513
1517
  this.isComposing = true;
1514
1518
  };
1515
1519
  this.handleCompositionEnd = (event) => {
1520
+ this.hasPendingImeComposition = false;
1516
1521
  this.isComposing = false;
1517
1522
  this.viewController.handleCompositionEnd({
1518
1523
  event,
@@ -1521,7 +1526,8 @@ var ChatComposerRuntime = class {
1521
1526
  };
1522
1527
  this.handleKeyDown = (event) => {
1523
1528
  const config = this.requireConfig();
1524
- if (this.rootElement && !this.isComposing) {
1529
+ this.syncImeGuardFromKeyboardEvent(event);
1530
+ if (this.rootElement && !this.shouldSuspendDomSync()) {
1525
1531
  const nextSnapshot = this.viewController.syncSelectionFromRoot(this.rootElement);
1526
1532
  this.selection = nextSnapshot.selection;
1527
1533
  this.selectedRange = nextSnapshot.selection;
@@ -1551,6 +1557,7 @@ var ChatComposerRuntime = class {
1551
1557
  };
1552
1558
  this.handleBlur = () => {
1553
1559
  const config = this.requireConfig();
1560
+ this.hasPendingImeComposition = false;
1554
1561
  this.isComposing = false;
1555
1562
  this.viewController.handleBlur({
1556
1563
  clearSelectedRange: this.clearSelectedRange,
@@ -1587,6 +1594,28 @@ var ChatComposerRuntime = class {
1587
1594
  this.requestRender = () => {
1588
1595
  this.requireConfig().requestRender();
1589
1596
  };
1597
+ this.shouldSuspendDomSync = () => {
1598
+ return this.isComposing || this.hasPendingImeComposition;
1599
+ };
1600
+ this.syncImeGuardFromKeyboardEvent = (event) => {
1601
+ const { nativeEvent } = event;
1602
+ const keyCode = nativeEvent.keyCode || nativeEvent.which || event.keyCode || event.which;
1603
+ if (nativeEvent.isComposing || event.key === "Process" || event.key === "Unidentified" || keyCode === 229) {
1604
+ this.hasPendingImeComposition = true;
1605
+ return;
1606
+ }
1607
+ this.hasPendingImeComposition = false;
1608
+ };
1609
+ this.syncImeGuardFromInputEvent = (nativeEvent) => {
1610
+ if (nativeEvent.isComposing || this.isCompositionInputType(nativeEvent.inputType)) {
1611
+ this.hasPendingImeComposition = true;
1612
+ return;
1613
+ }
1614
+ this.hasPendingImeComposition = false;
1615
+ };
1616
+ this.isCompositionInputType = (inputType) => {
1617
+ return typeof inputType === "string" && inputType.toLowerCase().includes("composition");
1618
+ };
1590
1619
  this.focusComposerSoon = () => {
1591
1620
  if (typeof requestAnimationFrame === "function") {
1592
1621
  requestAnimationFrame(() => this.focusComposer());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextclaw/agent-chat-ui",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "private": false,
5
5
  "description": "Reusable Nextclaw agent chat UI primitives and default skin.",
6
6
  "type": "module",