@abydahana/aksara-ui 1.2.2 → 1.2.3
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/aksara.css +2 -1
- package/dist/aksara.d.ts +2 -1
- package/dist/aksara.esm.js +42 -5
- package/dist/aksara.js +42 -5
- package/dist/aksara.min.css +1 -1
- package/dist/aksara.min.js +1 -1
- package/package.json +1 -1
package/dist/aksara.css
CHANGED
|
@@ -23681,7 +23681,8 @@ img,svg,video {
|
|
|
23681
23681
|
background:var(--aksara-surface);
|
|
23682
23682
|
border:1px solid var(--aksara-border-subtle);
|
|
23683
23683
|
border-radius:var(--aksara-radius);
|
|
23684
|
-
box-shadow:var(--aksara-shadow-md)
|
|
23684
|
+
box-shadow:var(--aksara-shadow-md);
|
|
23685
|
+
overscroll-behavior:contain
|
|
23685
23686
|
}
|
|
23686
23687
|
.dropdown-top .dropdown-menu,.dropdown-menu.dropdown-top {
|
|
23687
23688
|
bottom:100%;
|
package/dist/aksara.d.ts
CHANGED
|
@@ -114,7 +114,8 @@ export declare class Dropdown extends Component {
|
|
|
114
114
|
isOpen: boolean;
|
|
115
115
|
originalParent: Node | null;
|
|
116
116
|
originalSibling: Node | null;
|
|
117
|
-
scrollHandler: (() => void) | null;
|
|
117
|
+
scrollHandler: ((event?: Event) => void) | null;
|
|
118
|
+
wheelHandler: ((event: WheelEvent) => void) | null;
|
|
118
119
|
placement: string;
|
|
119
120
|
container: string | HTMLElement;
|
|
120
121
|
offset: number;
|
package/dist/aksara.esm.js
CHANGED
|
@@ -326,6 +326,7 @@ export class Dropdown extends Component {
|
|
|
326
326
|
originalParent;
|
|
327
327
|
originalSibling;
|
|
328
328
|
scrollHandler;
|
|
329
|
+
wheelHandler;
|
|
329
330
|
placement;
|
|
330
331
|
container;
|
|
331
332
|
offset;
|
|
@@ -372,6 +373,7 @@ export class Dropdown extends Component {
|
|
|
372
373
|
this.originalParent = null;
|
|
373
374
|
this.originalSibling = null;
|
|
374
375
|
this.scrollHandler = null;
|
|
376
|
+
this.wheelHandler = null;
|
|
375
377
|
this.updateOptions(options);
|
|
376
378
|
if (this.trigger?.matches(".btn-sm, .input-sm, .form-control-sm, .form-select-sm") ||
|
|
377
379
|
this.element.classList.contains("dropdown-sm")) {
|
|
@@ -427,9 +429,14 @@ export class Dropdown extends Component {
|
|
|
427
429
|
position() {
|
|
428
430
|
if (!this.menu || !this.isOpen || !this.trigger)
|
|
429
431
|
return;
|
|
432
|
+
if (!this.trigger.isConnected || !document.body.contains(this.trigger)) {
|
|
433
|
+
this.hide();
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
430
436
|
this.menu.style.display = "block";
|
|
431
437
|
this.menu.style.position = "absolute";
|
|
432
438
|
this.menu.style.zIndex = "1000";
|
|
439
|
+
this.menu.style.overscrollBehavior = "contain";
|
|
433
440
|
const triggerRect = this.trigger.getBoundingClientRect();
|
|
434
441
|
if (this.trigger.classList.contains("form-select") ||
|
|
435
442
|
this.element.classList.contains("variant-form-select") ||
|
|
@@ -441,10 +448,10 @@ export class Dropdown extends Component {
|
|
|
441
448
|
const gap = this.offset;
|
|
442
449
|
let top;
|
|
443
450
|
let left;
|
|
451
|
+
const spaceBelow = window.innerHeight - triggerRect.bottom;
|
|
452
|
+
const spaceAbove = triggerRect.top;
|
|
444
453
|
let placement = this.placement;
|
|
445
454
|
if (placement === "auto") {
|
|
446
|
-
const spaceBelow = window.innerHeight - triggerRect.bottom;
|
|
447
|
-
const spaceAbove = triggerRect.top;
|
|
448
455
|
placement = spaceBelow >= menuRect.height || spaceBelow >= spaceAbove ? "bottom" : "top";
|
|
449
456
|
}
|
|
450
457
|
this.menu.classList.remove("dropdown-top", "dropdown-bottom", "dropdown-start", "dropdown-end");
|
|
@@ -468,6 +475,11 @@ export class Dropdown extends Component {
|
|
|
468
475
|
}
|
|
469
476
|
const viewportWidth = window.innerWidth;
|
|
470
477
|
left = Math.max(8, Math.min(left, viewportWidth - menuRect.width - 8));
|
|
478
|
+
const availableHeight = Math.max(120, Math.floor(placement === "top" ? spaceAbove - gap - 16 : spaceBelow - gap - 16));
|
|
479
|
+
if (this.menu.scrollHeight > availableHeight || availableHeight < 300) {
|
|
480
|
+
this.menu.style.maxHeight = `${availableHeight}px`;
|
|
481
|
+
this.menu.style.overflowY = "auto";
|
|
482
|
+
}
|
|
471
483
|
this.menu.style.top = `${top + window.scrollY}px`;
|
|
472
484
|
this.menu.style.left = `${left + window.scrollX}px`;
|
|
473
485
|
this.menu.style.bottom = "auto";
|
|
@@ -490,9 +502,30 @@ export class Dropdown extends Component {
|
|
|
490
502
|
this.menu.classList.add("dropdown-open");
|
|
491
503
|
this.trigger?.setAttribute("aria-expanded", "true");
|
|
492
504
|
this.position();
|
|
493
|
-
this.scrollHandler = () =>
|
|
494
|
-
|
|
505
|
+
this.scrollHandler = (event) => {
|
|
506
|
+
if ((this.menu && (this.menu.matches(":hover") || this.menu.contains(document.activeElement))) ||
|
|
507
|
+
(this.trigger && this.trigger.matches(":hover")) ||
|
|
508
|
+
(event?.target && this.menu && (this.menu === event.target || this.menu.contains(event.target)))) {
|
|
509
|
+
return;
|
|
510
|
+
}
|
|
511
|
+
this.position();
|
|
512
|
+
};
|
|
513
|
+
window.addEventListener("scroll", this.scrollHandler, { passive: true, capture: true });
|
|
495
514
|
window.addEventListener("resize", this.scrollHandler);
|
|
515
|
+
this.wheelHandler = (e) => {
|
|
516
|
+
if (!this.menu)
|
|
517
|
+
return;
|
|
518
|
+
const { deltaY } = e;
|
|
519
|
+
if (deltaY === 0)
|
|
520
|
+
return;
|
|
521
|
+
const atTop = this.menu.scrollTop <= 0;
|
|
522
|
+
const atBottom = this.menu.scrollTop + this.menu.clientHeight >= this.menu.scrollHeight - 1;
|
|
523
|
+
if ((deltaY < 0 && atTop) || (deltaY > 0 && atBottom) || this.menu.scrollHeight <= this.menu.clientHeight) {
|
|
524
|
+
e.preventDefault();
|
|
525
|
+
e.stopPropagation();
|
|
526
|
+
}
|
|
527
|
+
};
|
|
528
|
+
this.menu.addEventListener("wheel", this.wheelHandler, { passive: false });
|
|
496
529
|
emit(this.element, "dropdown:show", { instance: this });
|
|
497
530
|
return this;
|
|
498
531
|
}
|
|
@@ -501,10 +534,14 @@ export class Dropdown extends Component {
|
|
|
501
534
|
return this;
|
|
502
535
|
this.isOpen = false;
|
|
503
536
|
if (this.scrollHandler) {
|
|
504
|
-
window.removeEventListener("scroll", this.scrollHandler);
|
|
537
|
+
window.removeEventListener("scroll", this.scrollHandler, { capture: true });
|
|
505
538
|
window.removeEventListener("resize", this.scrollHandler);
|
|
506
539
|
this.scrollHandler = null;
|
|
507
540
|
}
|
|
541
|
+
if (this.wheelHandler && this.menu) {
|
|
542
|
+
this.menu.removeEventListener("wheel", this.wheelHandler);
|
|
543
|
+
this.wheelHandler = null;
|
|
544
|
+
}
|
|
508
545
|
this.menu.classList.remove("dropdown-open", "dropdown-top", "dropdown-bottom", "dropdown-start", "dropdown-end");
|
|
509
546
|
this.trigger?.setAttribute("aria-expanded", "false");
|
|
510
547
|
if (this.originalParent) {
|
package/dist/aksara.js
CHANGED
|
@@ -327,6 +327,7 @@ class Dropdown extends Component {
|
|
|
327
327
|
originalParent;
|
|
328
328
|
originalSibling;
|
|
329
329
|
scrollHandler;
|
|
330
|
+
wheelHandler;
|
|
330
331
|
placement;
|
|
331
332
|
container;
|
|
332
333
|
offset;
|
|
@@ -373,6 +374,7 @@ class Dropdown extends Component {
|
|
|
373
374
|
this.originalParent = null;
|
|
374
375
|
this.originalSibling = null;
|
|
375
376
|
this.scrollHandler = null;
|
|
377
|
+
this.wheelHandler = null;
|
|
376
378
|
this.updateOptions(options);
|
|
377
379
|
if (this.trigger?.matches(".btn-sm, .input-sm, .form-control-sm, .form-select-sm") ||
|
|
378
380
|
this.element.classList.contains("dropdown-sm")) {
|
|
@@ -428,9 +430,14 @@ class Dropdown extends Component {
|
|
|
428
430
|
position() {
|
|
429
431
|
if (!this.menu || !this.isOpen || !this.trigger)
|
|
430
432
|
return;
|
|
433
|
+
if (!this.trigger.isConnected || !document.body.contains(this.trigger)) {
|
|
434
|
+
this.hide();
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
431
437
|
this.menu.style.display = "block";
|
|
432
438
|
this.menu.style.position = "absolute";
|
|
433
439
|
this.menu.style.zIndex = "1000";
|
|
440
|
+
this.menu.style.overscrollBehavior = "contain";
|
|
434
441
|
const triggerRect = this.trigger.getBoundingClientRect();
|
|
435
442
|
if (this.trigger.classList.contains("form-select") ||
|
|
436
443
|
this.element.classList.contains("variant-form-select") ||
|
|
@@ -442,10 +449,10 @@ class Dropdown extends Component {
|
|
|
442
449
|
const gap = this.offset;
|
|
443
450
|
let top;
|
|
444
451
|
let left;
|
|
452
|
+
const spaceBelow = window.innerHeight - triggerRect.bottom;
|
|
453
|
+
const spaceAbove = triggerRect.top;
|
|
445
454
|
let placement = this.placement;
|
|
446
455
|
if (placement === "auto") {
|
|
447
|
-
const spaceBelow = window.innerHeight - triggerRect.bottom;
|
|
448
|
-
const spaceAbove = triggerRect.top;
|
|
449
456
|
placement = spaceBelow >= menuRect.height || spaceBelow >= spaceAbove ? "bottom" : "top";
|
|
450
457
|
}
|
|
451
458
|
this.menu.classList.remove("dropdown-top", "dropdown-bottom", "dropdown-start", "dropdown-end");
|
|
@@ -469,6 +476,11 @@ class Dropdown extends Component {
|
|
|
469
476
|
}
|
|
470
477
|
const viewportWidth = window.innerWidth;
|
|
471
478
|
left = Math.max(8, Math.min(left, viewportWidth - menuRect.width - 8));
|
|
479
|
+
const availableHeight = Math.max(120, Math.floor(placement === "top" ? spaceAbove - gap - 16 : spaceBelow - gap - 16));
|
|
480
|
+
if (this.menu.scrollHeight > availableHeight || availableHeight < 300) {
|
|
481
|
+
this.menu.style.maxHeight = `${availableHeight}px`;
|
|
482
|
+
this.menu.style.overflowY = "auto";
|
|
483
|
+
}
|
|
472
484
|
this.menu.style.top = `${top + window.scrollY}px`;
|
|
473
485
|
this.menu.style.left = `${left + window.scrollX}px`;
|
|
474
486
|
this.menu.style.bottom = "auto";
|
|
@@ -491,9 +503,30 @@ class Dropdown extends Component {
|
|
|
491
503
|
this.menu.classList.add("dropdown-open");
|
|
492
504
|
this.trigger?.setAttribute("aria-expanded", "true");
|
|
493
505
|
this.position();
|
|
494
|
-
this.scrollHandler = () =>
|
|
495
|
-
|
|
506
|
+
this.scrollHandler = (event) => {
|
|
507
|
+
if ((this.menu && (this.menu.matches(":hover") || this.menu.contains(document.activeElement))) ||
|
|
508
|
+
(this.trigger && this.trigger.matches(":hover")) ||
|
|
509
|
+
(event?.target && this.menu && (this.menu === event.target || this.menu.contains(event.target)))) {
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
this.position();
|
|
513
|
+
};
|
|
514
|
+
window.addEventListener("scroll", this.scrollHandler, { passive: true, capture: true });
|
|
496
515
|
window.addEventListener("resize", this.scrollHandler);
|
|
516
|
+
this.wheelHandler = (e) => {
|
|
517
|
+
if (!this.menu)
|
|
518
|
+
return;
|
|
519
|
+
const { deltaY } = e;
|
|
520
|
+
if (deltaY === 0)
|
|
521
|
+
return;
|
|
522
|
+
const atTop = this.menu.scrollTop <= 0;
|
|
523
|
+
const atBottom = this.menu.scrollTop + this.menu.clientHeight >= this.menu.scrollHeight - 1;
|
|
524
|
+
if ((deltaY < 0 && atTop) || (deltaY > 0 && atBottom) || this.menu.scrollHeight <= this.menu.clientHeight) {
|
|
525
|
+
e.preventDefault();
|
|
526
|
+
e.stopPropagation();
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
this.menu.addEventListener("wheel", this.wheelHandler, { passive: false });
|
|
497
530
|
emit(this.element, "dropdown:show", { instance: this });
|
|
498
531
|
return this;
|
|
499
532
|
}
|
|
@@ -502,10 +535,14 @@ class Dropdown extends Component {
|
|
|
502
535
|
return this;
|
|
503
536
|
this.isOpen = false;
|
|
504
537
|
if (this.scrollHandler) {
|
|
505
|
-
window.removeEventListener("scroll", this.scrollHandler);
|
|
538
|
+
window.removeEventListener("scroll", this.scrollHandler, { capture: true });
|
|
506
539
|
window.removeEventListener("resize", this.scrollHandler);
|
|
507
540
|
this.scrollHandler = null;
|
|
508
541
|
}
|
|
542
|
+
if (this.wheelHandler && this.menu) {
|
|
543
|
+
this.menu.removeEventListener("wheel", this.wheelHandler);
|
|
544
|
+
this.wheelHandler = null;
|
|
545
|
+
}
|
|
509
546
|
this.menu.classList.remove("dropdown-open", "dropdown-top", "dropdown-bottom", "dropdown-start", "dropdown-end");
|
|
510
547
|
this.trigger?.setAttribute("aria-expanded", "false");
|
|
511
548
|
if (this.originalParent) {
|