@teammates/consolonia 0.3.0 → 0.3.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.
@@ -145,6 +145,10 @@ export declare class ChatView extends Control {
145
145
  private _selAnchor;
146
146
  private _selEnd;
147
147
  private _selecting;
148
+ /** Timer for auto-scrolling the feed during drag-to-select. */
149
+ private _selScrollTimer;
150
+ /** Direction of auto-scroll: -1 = up, 1 = down, 0 = none. */
151
+ private _selScrollDir;
148
152
  /** DrawingContext reference from the last render (for text extraction). */
149
153
  private _ctx;
150
154
  /** Optional widget that replaces the input area (e.g. Interview). */
@@ -250,5 +254,9 @@ export declare class ChatView extends Control {
250
254
  private _renderSelection;
251
255
  /** Clear any active text selection. */
252
256
  clearSelection(): void;
257
+ /** Start interval-based scroll during drag-to-select at feed edges. */
258
+ private _startSelScroll;
259
+ /** Stop auto-scroll timer. */
260
+ private _stopSelScroll;
253
261
  private _autoScrollToBottom;
254
262
  }
@@ -89,6 +89,10 @@ export class ChatView extends Control {
89
89
  _selAnchor = null;
90
90
  _selEnd = null;
91
91
  _selecting = false;
92
+ /** Timer for auto-scrolling the feed during drag-to-select. */
93
+ _selScrollTimer = null;
94
+ /** Direction of auto-scroll: -1 = up, 1 = down, 0 = none. */
95
+ _selScrollDir = 0;
92
96
  /** DrawingContext reference from the last render (for text extraction). */
93
97
  _ctx = null;
94
98
  /** Optional widget that replaces the input area (e.g. Interview). */
@@ -606,15 +610,27 @@ export class ChatView extends Control {
606
610
  return true;
607
611
  }
608
612
  }
609
- // Text selection: extend on move
613
+ // Text selection: extend on move (with auto-scroll at edges)
610
614
  if (me.type === "move" && this._selecting) {
611
615
  this._selEnd = { x: me.x, y: me.y };
616
+ const feedTop = this._feedY;
617
+ const feedBot = this._feedY + this._feedH;
618
+ if (me.y < feedTop) {
619
+ this._startSelScroll(-1);
620
+ }
621
+ else if (me.y >= feedBot) {
622
+ this._startSelScroll(1);
623
+ }
624
+ else {
625
+ this._stopSelScroll();
626
+ }
612
627
  this.invalidate();
613
628
  return true;
614
629
  }
615
630
  // Text selection: finalize on release
616
631
  if (me.type === "release" && this._selecting) {
617
632
  this._selecting = false;
633
+ this._stopSelScroll();
618
634
  // If anchor == end (just a click, no drag), clear selection
619
635
  if (this._selAnchor &&
620
636
  this._selEnd &&
@@ -1082,9 +1098,37 @@ export class ChatView extends Control {
1082
1098
  this._selAnchor = null;
1083
1099
  this._selEnd = null;
1084
1100
  this._selecting = false;
1101
+ this._stopSelScroll();
1085
1102
  this.invalidate();
1086
1103
  }
1087
1104
  // ── Auto-scroll ────────────────────────────────────────────────
1105
+ /** Start interval-based scroll during drag-to-select at feed edges. */
1106
+ _startSelScroll(dir) {
1107
+ if (this._selScrollDir === dir && this._selScrollTimer)
1108
+ return;
1109
+ this._stopSelScroll();
1110
+ this._selScrollDir = dir;
1111
+ this._selScrollTimer = setInterval(() => {
1112
+ this.scrollFeed(this._selScrollDir * 3);
1113
+ // Move selEnd to keep extending the selection while scrolling
1114
+ if (this._selEnd) {
1115
+ this._selEnd = {
1116
+ x: this._selEnd.x,
1117
+ y: this._selScrollDir < 0
1118
+ ? this._feedY
1119
+ : this._feedY + this._feedH - 1,
1120
+ };
1121
+ }
1122
+ }, 80);
1123
+ }
1124
+ /** Stop auto-scroll timer. */
1125
+ _stopSelScroll() {
1126
+ if (this._selScrollTimer) {
1127
+ clearInterval(this._selScrollTimer);
1128
+ this._selScrollTimer = null;
1129
+ }
1130
+ this._selScrollDir = 0;
1131
+ }
1088
1132
  _autoScrollToBottom() {
1089
1133
  // Set scroll to a very large value; it will be clamped during render
1090
1134
  this._feedScrollOffset = Number.MAX_SAFE_INTEGER;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teammates/consolonia",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Terminal UI rendering engine inspired by Consolonia. Pixel-level compositing with ANSI output.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",