• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

atinc / ngx-tethys / 0bbb2cec-209e-4d8a-b1b3-6bc54e05daa6

04 Sep 2023 08:40AM UTC coverage: 15.616% (-74.6%) from 90.2%
0bbb2cec-209e-4d8a-b1b3-6bc54e05daa6

Pull #2829

circleci

cmm-va
fix: add test
Pull Request #2829: fix: add tabIndex

300 of 6386 branches covered (0.0%)

Branch coverage included in aggregate %.

78 of 78 new or added lines in 26 files covered. (100.0%)

2849 of 13779 relevant lines covered (20.68%)

83.41 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

11.63
/src/dropdown/dropdown-submenu.component.ts
1
import { UnsubscribeMixin } from 'ngx-tethys/core';
2
import { getElementOffset } from 'ngx-tethys/util';
3
import { takeUntil } from 'rxjs/operators';
4

5
import { ChangeDetectionStrategy, Component, ElementRef, Input, OnDestroy, OnInit } from '@angular/core';
6

7
import { ThyDropdownMenuItemDirective } from './dropdown-menu-item.directive';
1✔
8

9
export type ThyDropdownSubmenuDirection = 'left' | 'right' | 'auto';
10

11
type InnerDropdownSubmenuDirection = ThyDropdownSubmenuDirection | 'leftBottom' | 'rightBottom';
12

13
const SUBMENU_CLASS_PREFIX = 'dropdown-submenu';
1✔
14

15
/**
×
16
 * 下拉子菜单
17
 * @name thy-dropdown-submenu,[thyDropdownSubmenu]
18
 * @order 40
×
19
 */
×
20
@Component({
×
21
    selector: '[thyDropdownSubmenu],thy-dropdown-submenu',
×
22
    template: '<ng-content></ng-content>',
23
    host: {
24
        class: 'dropdown-submenu'
×
25
    },
×
26
    changeDetection: ChangeDetectionStrategy.OnPush,
×
27
    standalone: true
28
})
29
export class ThyDropdownSubmenuComponent extends UnsubscribeMixin implements OnInit, OnDestroy {
30
    private direction: InnerDropdownSubmenuDirection = 'right';
×
31

×
32
    /**
×
33
     * 菜单方向
×
34
     * @type left | right | auto
×
35
     * @default right
36
     */
37
    @Input() set thyDirection(value: ThyDropdownSubmenuDirection) {
×
38
        this.direction = value;
39
    }
×
40

41
    constructor(private dropdownMenuItem: ThyDropdownMenuItemDirective, private elementRef: ElementRef<HTMLElement>) {
×
42
        super();
43
    }
44

45
    ngOnInit(): void {
×
46
        let direction = this.direction || 'right';
47
        this.updateClassByDirection(direction);
48
        this.dropdownMenuItem
×
49
            .bindMouseenterEvent()
×
50
            .pipe(takeUntil(this.ngUnsubscribe$))
×
51
            .subscribe(() => {
×
52
                if (this.direction === 'auto') {
×
53
                    const element = this.dropdownMenuItem.getElement();
54
                    const offset = getElementOffset(element);
×
55
                    if (document.documentElement.clientWidth < offset.left + offset.width + offset.width) {
×
56
                        direction = 'left';
57
                    } else {
58
                        direction = 'right';
×
59
                    }
60
                    this.updateClassByDirection(direction);
61
                }
62
                this.updateVerticalDirection(direction);
63
            });
×
64
    }
65

1✔
66
    private updateClassByDirection(direction: InnerDropdownSubmenuDirection) {
67
        this.dropdownMenuItem.updateClass([`${SUBMENU_CLASS_PREFIX}-${direction}`]);
68
    }
69

1✔
70
    private updateVerticalDirection(direction: InnerDropdownSubmenuDirection) {
71
        const submenuItems = this.elementRef.nativeElement.querySelectorAll('.dropdown-menu-item');
72
        if (submenuItems.length) {
73
            let submenuItemHeight = 0;
1✔
74
            submenuItems.forEach(item => (submenuItemHeight += item.clientHeight));
75
            if (
76
                document.documentElement.clientHeight - this.dropdownMenuItem.getElement().getBoundingClientRect().bottom <
77
                submenuItemHeight
78
            ) {
79
                direction = direction === 'left' ? 'leftBottom' : 'rightBottom';
80
                this.updateClassByDirection(direction);
81
            } else {
82
                this.updateClassByDirection(direction);
83
            }
84
        }
85
    }
86

87
    ngOnDestroy() {
88
        super.ngOnDestroy();
89
    }
90
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc