@bbki.ng/bb-msg-history 0.13.1 → 0.14.0

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.
@@ -5,9 +5,6 @@ export declare class BBMsgHistory extends HTMLElement {
5
5
  private _lastAuthor;
6
6
  private _lastGroupTimestamp;
7
7
  private _scrollButtonVisible;
8
- private _userHasScrolledManually;
9
- private _isProgrammaticScroll;
10
- private _lastScrollTop;
11
8
  static get observedAttributes(): string[];
12
9
  constructor();
13
10
  attributeChangedCallback(name: string): void;
package/dist/component.js CHANGED
@@ -13,9 +13,6 @@ export class BBMsgHistory extends HTMLElement {
13
13
  this._userAuthors = new Map();
14
14
  this._lastAuthor = '';
15
15
  this._scrollButtonVisible = false;
16
- this._userHasScrolledManually = false;
17
- this._isProgrammaticScroll = false;
18
- this._lastScrollTop = 0;
19
16
  this.attachShadow({ mode: 'open' });
20
17
  }
21
18
  attributeChangedCallback(name) {
@@ -138,16 +135,10 @@ export class BBMsgHistory extends HTMLElement {
138
135
  }
139
136
  // Smooth scroll to bottom (skip in infinite mode)
140
137
  if (!this.hasAttribute('infinite')) {
141
- // Mark this as a programmatic scroll so the scroll handler ignores it
142
- this._isProgrammaticScroll = true;
143
138
  container.scrollTo({
144
139
  top: container.scrollHeight,
145
140
  behavior: 'smooth',
146
141
  });
147
- // Reset the flag after smooth scroll animation completes (~300ms)
148
- setTimeout(() => {
149
- this._isProgrammaticScroll = false;
150
- }, 300);
151
142
  // Hide scroll button since we're scrolling to bottom
152
143
  if (this._scrollButtonVisible) {
153
144
  this._scrollButtonVisible = false;
@@ -308,12 +299,7 @@ export class BBMsgHistory extends HTMLElement {
308
299
  const scrollButton = this.shadowRoot.querySelector('.scroll-to-bottom');
309
300
  const isInfinite = this.hasAttribute('infinite');
310
301
  if (container && !isInfinite) {
311
- // Mark as programmatic scroll to prevent triggering user scroll detection
312
- this._isProgrammaticScroll = true;
313
302
  container.scrollTop = container.scrollHeight;
314
- requestAnimationFrame(() => {
315
- this._isProgrammaticScroll = false;
316
- });
317
303
  this._setupScrollTracking(container, scrollButton, { skipInitialCheck: true });
318
304
  }
319
305
  if (scrollButton && !isInfinite) {
@@ -349,21 +335,11 @@ export class BBMsgHistory extends HTMLElement {
349
335
  }
350
336
  _setupScrollTracking(container, button, options) {
351
337
  const checkScrollPosition = () => {
352
- // Ignore programmatic scrolls - they don't indicate user intent
353
- if (this._isProgrammaticScroll)
354
- return;
355
- // Mark that user has manually scrolled
356
- if (!this._userHasScrolledManually) {
357
- this._userHasScrolledManually = true;
358
- }
359
- const currentScrollTop = container.scrollTop;
360
- const isScrollingUp = currentScrollTop < this._lastScrollTop;
361
- this._lastScrollTop = currentScrollTop;
362
338
  const threshold = 50; // pixels from bottom
363
339
  const isAtBottom = container.scrollHeight - container.scrollTop - container.clientHeight < threshold;
364
340
  const hasOverflow = container.scrollHeight > container.clientHeight;
365
- // Only show button when: user has scrolled, is not at bottom, is scrolling up
366
- const shouldShow = !isAtBottom && hasOverflow && this._userHasScrolledManually && isScrollingUp;
341
+ // Show button when not at bottom and content has overflow
342
+ const shouldShow = !isAtBottom && hasOverflow;
367
343
  if (shouldShow !== this._scrollButtonVisible) {
368
344
  this._scrollButtonVisible = shouldShow;
369
345
  // Only toggle button visibility if button exists
@@ -378,8 +354,6 @@ export class BBMsgHistory extends HTMLElement {
378
354
  }));
379
355
  }
380
356
  };
381
- // Initialize last scroll position
382
- this._lastScrollTop = container.scrollTop;
383
357
  // Check initial state unless skipped
384
358
  if (!options?.skipInitialCheck) {
385
359
  checkScrollPosition();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bbki.ng/bb-msg-history",
3
- "version": "0.13.1",
3
+ "version": "0.14.0",
4
4
  "description": "A chat-style message history web component",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -23,19 +23,6 @@
23
23
  "dist",
24
24
  "src"
25
25
  ],
26
- "scripts": {
27
- "start": "tsc -w",
28
- "preview": "python3 -m http.server 8000",
29
- "prepare": "tsc && cp dist/index.js dist/index.dev.js && terser dist/index.js --compress --mangle --source-map -o dist/index.js",
30
- "build": "tsc && cp dist/index.js dist/index.dev.js && terser dist/index.js --compress --mangle --source-map -o dist/index.js",
31
- "lint": "eslint src/**/*.ts",
32
- "lint:fix": "eslint src/**/*.ts --fix",
33
- "format": "prettier --write \"src/**/*.ts\"",
34
- "format:check": "prettier --check \"src/**/*.ts\"",
35
- "test": "vitest run",
36
- "test:watch": "vitest",
37
- "release": "release-it"
38
- },
39
26
  "lint-staged": {
40
27
  "*.ts": [
41
28
  "eslint --fix",
@@ -60,5 +47,17 @@
60
47
  "terser": "^5.46.0",
61
48
  "typescript": "^5.9.3",
62
49
  "vitest": "^3.2.4"
50
+ },
51
+ "scripts": {
52
+ "start": "tsc -w",
53
+ "preview": "python3 -m http.server 8000",
54
+ "build": "tsc && cp dist/index.js dist/index.dev.js && terser dist/index.js --compress --mangle --source-map -o dist/index.js",
55
+ "lint": "eslint src/**/*.ts",
56
+ "lint:fix": "eslint src/**/*.ts --fix",
57
+ "format": "prettier --write \"src/**/*.ts\"",
58
+ "format:check": "prettier --check \"src/**/*.ts\"",
59
+ "test": "vitest run",
60
+ "test:watch": "vitest",
61
+ "release": "release-it"
63
62
  }
64
- }
63
+ }
package/src/component.ts CHANGED
@@ -12,9 +12,6 @@ export class BBMsgHistory extends HTMLElement {
12
12
  private _lastAuthor = '';
13
13
  private _lastGroupTimestamp: string | undefined;
14
14
  private _scrollButtonVisible = false;
15
- private _userHasScrolledManually = false;
16
- private _isProgrammaticScroll = false;
17
- private _lastScrollTop = 0;
18
15
 
19
16
  static get observedAttributes() {
20
17
  return ['theme', 'loading', 'hide-scroll-bar', 'infinite', 'hide-scroll-button'];
@@ -176,19 +173,11 @@ export class BBMsgHistory extends HTMLElement {
176
173
 
177
174
  // Smooth scroll to bottom (skip in infinite mode)
178
175
  if (!this.hasAttribute('infinite')) {
179
- // Mark this as a programmatic scroll so the scroll handler ignores it
180
- this._isProgrammaticScroll = true;
181
-
182
176
  container.scrollTo({
183
177
  top: container.scrollHeight,
184
178
  behavior: 'smooth',
185
179
  });
186
180
 
187
- // Reset the flag after smooth scroll animation completes (~300ms)
188
- setTimeout(() => {
189
- this._isProgrammaticScroll = false;
190
- }, 300);
191
-
192
181
  // Hide scroll button since we're scrolling to bottom
193
182
  if (this._scrollButtonVisible) {
194
183
  this._scrollButtonVisible = false;
@@ -386,12 +375,7 @@ export class BBMsgHistory extends HTMLElement {
386
375
  const isInfinite = this.hasAttribute('infinite');
387
376
 
388
377
  if (container && !isInfinite) {
389
- // Mark as programmatic scroll to prevent triggering user scroll detection
390
- this._isProgrammaticScroll = true;
391
378
  container.scrollTop = container.scrollHeight;
392
- requestAnimationFrame(() => {
393
- this._isProgrammaticScroll = false;
394
- });
395
379
  this._setupScrollTracking(container, scrollButton, { skipInitialCheck: true });
396
380
  }
397
381
 
@@ -435,24 +419,12 @@ export class BBMsgHistory extends HTMLElement {
435
419
  options?: { skipInitialCheck?: boolean }
436
420
  ): void {
437
421
  const checkScrollPosition = () => {
438
- // Ignore programmatic scrolls - they don't indicate user intent
439
- if (this._isProgrammaticScroll) return;
440
-
441
- // Mark that user has manually scrolled
442
- if (!this._userHasScrolledManually) {
443
- this._userHasScrolledManually = true;
444
- }
445
-
446
- const currentScrollTop = container.scrollTop;
447
- const isScrollingUp = currentScrollTop < this._lastScrollTop;
448
- this._lastScrollTop = currentScrollTop;
449
-
450
422
  const threshold = 50; // pixels from bottom
451
423
  const isAtBottom =
452
424
  container.scrollHeight - container.scrollTop - container.clientHeight < threshold;
453
425
  const hasOverflow = container.scrollHeight > container.clientHeight;
454
- // Only show button when: user has scrolled, is not at bottom, is scrolling up
455
- const shouldShow = !isAtBottom && hasOverflow && this._userHasScrolledManually && isScrollingUp;
426
+ // Show button when not at bottom and content has overflow
427
+ const shouldShow = !isAtBottom && hasOverflow;
456
428
 
457
429
  if (shouldShow !== this._scrollButtonVisible) {
458
430
  this._scrollButtonVisible = shouldShow;
@@ -472,9 +444,6 @@ export class BBMsgHistory extends HTMLElement {
472
444
  }
473
445
  };
474
446
 
475
- // Initialize last scroll position
476
- this._lastScrollTop = container.scrollTop;
477
-
478
447
  // Check initial state unless skipped
479
448
  if (!options?.skipInitialCheck) {
480
449
  checkScrollPosition();