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

atinc / ngx-tethys / 68ef226c-f83e-44c1-b8ed-e420a83c5d84

28 May 2025 10:31AM UTC coverage: 10.352% (-80.0%) from 90.316%
68ef226c-f83e-44c1-b8ed-e420a83c5d84

Pull #3460

circleci

pubuzhixing8
chore: xxx
Pull Request #3460: refactor(icon): migrate signal input #TINFR-1476

132 of 6823 branches covered (1.93%)

Branch coverage included in aggregate %.

10 of 14 new or added lines in 1 file covered. (71.43%)

11648 existing lines in 344 files now uncovered.

2078 of 14525 relevant lines covered (14.31%)

6.69 hits per line

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

6.35
/src/tabs/tabs.component.ts
1
import {
2
    AfterContentInit,
3
    ChangeDetectionStrategy,
4
    ChangeDetectorRef,
5
    Component,
6
    ContentChildren,
7
    DestroyRef,
8
    ElementRef,
9
    OnInit,
10
    QueryList,
11
    TemplateRef,
12
    effect,
13
    inject,
14
    input,
15
    output
16
} from '@angular/core';
1✔
17
import { coerceBooleanProperty, isString, ThyBooleanInput } from 'ngx-tethys/util';
UNCOV
18
import { fromEvent } from 'rxjs';
×
UNCOV
19
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
×
UNCOV
20
import { ThyTab } from './tab.component';
×
UNCOV
21
import { ThyActiveTabInfo, ThyTabActiveEvent } from './types';
×
UNCOV
22
import { ThyTabContent } from './tab-content.component';
×
UNCOV
23
import { NgTemplateOutlet } from '@angular/common';
×
UNCOV
24
import { ThyNav, ThyNavItemDirective } from 'ngx-tethys/nav';
×
UNCOV
25

×
UNCOV
26
export type ThyTabsSize = 'lg' | 'md' | 'sm';
×
UNCOV
27

×
UNCOV
28
export type ThyTabsType = 'pulled' | 'tabs' | 'pills' | 'lite';
×
UNCOV
29

×
UNCOV
30
export type ThyTabsPosition = 'top' | 'left';
×
UNCOV
31

×
UNCOV
32
/**
×
UNCOV
33
 * 选项卡切换组件
×
UNCOV
34
 * @name thy-tabs
×
UNCOV
35
 */
×
UNCOV
36
@Component({
×
37
    selector: 'thy-tabs',
38
    templateUrl: './tabs.component.html',
UNCOV
39
    changeDetection: ChangeDetectionStrategy.OnPush,
×
UNCOV
40
    host: {
×
41
        class: 'thy-tabs',
42
        '[class.thy-tabs-top]': `thyPosition() === 'top'`,
43
        '[class.thy-tabs-left]': `thyPosition() === 'left'`,
44
        '[style.overflow]': `transitionStarted ? "hidden" : null`
UNCOV
45
    },
×
UNCOV
46
    imports: [ThyNav, ThyNavItemDirective, NgTemplateOutlet, ThyTabContent]
×
47
})
48
export class ThyTabs implements OnInit, AfterContentInit {
UNCOV
49
    private cd = inject(ChangeDetectorRef);
×
UNCOV
50
    private el = inject(ElementRef);
×
51

52
    @ContentChildren(ThyTab, { descendants: true }) tabs = new QueryList<ThyTab>();
53

UNCOV
54
    private readonly destroyRef = inject(DestroyRef);
×
UNCOV
55

×
UNCOV
56
    /**
×
UNCOV
57
     * 标签类型
×
58
     * @type 'pulled' | 'tabs' | 'pills' | 'lite'
59
     */
60
    readonly thyType = input<ThyTabsType>('tabs');
UNCOV
61

×
62
    /**
63
     * 选项卡的大小
UNCOV
64
     * @type 'lg' | 'md' | 'sm'
×
UNCOV
65
     */
×
66
    readonly thySize = input<ThyTabsSize>('md');
UNCOV
67

×
68
    /**
69
     * 激活的项
UNCOV
70
     */
×
UNCOV
71
    readonly thyActiveTab = input<ThyActiveTabInfo>(0);
×
72

UNCOV
73
    /**
×
UNCOV
74
     * 附加操作
×
UNCOV
75
     */
×
UNCOV
76
    readonly thyExtra = input<TemplateRef<unknown>>(undefined);
×
UNCOV
77

×
UNCOV
78
    /**
×
79
     * 选项卡的位置
80
     * @type 'top' | 'left'
1✔
81
     */
1✔
82
    readonly thyPosition = input<ThyTabsPosition>('top');
83

84
    /**
85
     * 是否使用动画切换 Tabs
86
     */
87
    readonly thyAnimated = input<boolean, ThyBooleanInput>(false, { transform: coerceBooleanProperty });
88

89
    /**
90
     * 响应式,自动计算宽度存放 thyNavItem,并添加更多弹框
91
     */
92
    readonly thyResponsive = input<boolean, ThyBooleanInput>(false, { transform: coerceBooleanProperty });
93

1✔
94
    /**
95
     * 激活的项发生改变时的回调
96
     */
97
    readonly thyActiveTabChange = output<ThyTabActiveEvent>();
98

99
    activeTabIndex: number = 0;
100

101
    activeTabId: string;
102

103
    transitionStarted: boolean = false;
104

105
    constructor() {
106
        effect(() => {
107
            const value = this.thyActiveTab();
108
            if (isString(value)) {
109
                this.activeTabId = value;
110
                this.activeTabIndex = undefined;
111
            } else {
112
                this.activeTabIndex = value;
113
                this.activeTabId = undefined;
114
            }
115
        });
116
    }
117

118
    ngOnInit(): void {
119
        const tabsContent = this.el.nativeElement.querySelector('.thy-tabs-content');
120
        fromEvent(tabsContent, 'transitionend')
121
            .pipe(takeUntilDestroyed(this.destroyRef))
122
            .subscribe(() => {
123
                this.transitionStarted = false;
124
                this.cd.markForCheck();
125
            });
126
    }
127

128
    ngAfterContentInit() {
129
        this.tabs.changes.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(data => {
130
            this.thyAnimated() && (this.transitionStarted = true);
131
            this.activeTabIndex = data.length - 1;
132
            this.cd.markForCheck();
133
        });
134
    }
135

136
    get tabPaneAnimated(): boolean {
137
        return this.thyPosition() === 'top' && this.thyAnimated();
138
    }
139

140
    getTabContentMarginLeft(): string {
141
        if (this.tabPaneAnimated) {
142
            return `${-(this.activeTabIndex || 0) * 100}%`;
143
        }
144
        return '';
145
    }
146

147
    activeTab(tab: ThyTab, index: number) {
148
        if (tab.thyDisabled()) {
149
            return;
150
        }
151
        this.activeTabId = tab.id() || null;
152
        this.thyAnimated() && (this.transitionStarted = this.activeTabIndex !== index);
153
        this.activeTabIndex = index;
154
        const id = tab.id();
155
        const activeTab = id ? id : index;
156
        this.thyActiveTabChange.emit(activeTab);
157
    }
158
}
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

© 2025 Coveralls, Inc