• 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

8.16
/src/segment/segment-item.component.ts
1
import {
2
    ChangeDetectionStrategy,
3
    Component,
4
    DestroyRef,
5
    ElementRef,
6
    NgZone,
7
    Renderer2,
8
    afterNextRender,
9
    inject,
10
    input,
11
    signal
12
} from '@angular/core';
13
import { IThySegmentItemComponent, THY_SEGMENTED_COMPONENT } from './segment.token';
14
import { assertIconOnly, coerceBooleanProperty } from 'ngx-tethys/util';
15
import { fromEvent } from 'rxjs';
1✔
16
import { SafeAny } from 'ngx-tethys/types';
UNCOV
17
import { ThyIcon } from 'ngx-tethys/icon';
×
UNCOV
18
import { NgClass } from '@angular/common';
×
UNCOV
19
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
×
UNCOV
20

×
UNCOV
21
/**
×
UNCOV
22
 * 分段控制器的选项组件
×
UNCOV
23
 * @name thy-segment-item,[thy-segment-item]
×
UNCOV
24
 */
×
UNCOV
25
@Component({
×
UNCOV
26
    selector: 'thy-segment-item,[thy-segment-item]',
×
UNCOV
27
    templateUrl: './segment-item.component.html',
×
UNCOV
28
    changeDetection: ChangeDetectionStrategy.OnPush,
×
UNCOV
29
    host: {
×
30
        class: 'thy-segment-item',
31
        '[class.disabled]': 'thyDisabled()'
UNCOV
32
    },
×
33
    imports: [NgClass, ThyIcon]
34
})
35
export class ThySegmentItem implements IThySegmentItemComponent {
UNCOV
36
    elementRef = inject(ElementRef);
×
UNCOV
37
    private ngZone = inject(NgZone);
×
UNCOV
38
    private renderer = inject(Renderer2);
×
39
    private parent = inject(THY_SEGMENTED_COMPONENT, { optional: true })!;
40

41
    /**
UNCOV
42
     * 选项的值
×
UNCOV
43
     */
×
UNCOV
44
    readonly thyValue = input<SafeAny>();
×
UNCOV
45

×
46
    /**
47
     * 选项的图标
48
     */
UNCOV
49
    readonly thyIcon = input<string>();
×
50

51
    /**
UNCOV
52
     * 是否禁用该选项
×
53
     */
54
    readonly thyDisabled = input(false, { transform: coerceBooleanProperty });
UNCOV
55

×
UNCOV
56
    public isOnlyIcon = signal(false);
×
UNCOV
57

×
UNCOV
58
    public isWithText = signal(false);
×
UNCOV
59

×
UNCOV
60
    private destroyRef = inject(DestroyRef);
×
61

UNCOV
62
    constructor() {
×
UNCOV
63
        const elementRef = this.elementRef;
×
64
        const ngZone = this.ngZone;
65

66
        ngZone.runOutsideAngular(() =>
67
            fromEvent(elementRef.nativeElement, 'click')
1✔
68
                .pipe(takeUntilDestroyed(this.destroyRef))
1✔
69
                .subscribe((event: Event) => {
70
                    if (
71
                        !this.thyDisabled() &&
72
                        !this.parent.thyDisabled() &&
73
                        this.parent.selectedItem &&
74
                        this.parent.selectedItem !== this
1✔
75
                    ) {
76
                        ngZone.run(() => {
77
                            this.parent.selectedItem.unselect();
78
                            this.parent.changeSelectedItem(this, event);
79
                        });
80
                    }
81
                })
82
        );
83

84
        afterNextRender(() => {
85
            const labelDiv = this.elementRef.nativeElement.children[0];
86
            this.isOnlyIcon.set(assertIconOnly(labelDiv) && this.parent.thyMode() === 'inline');
87
            this.wrapSpanForText(labelDiv.childNodes);
88
        });
89
    }
90

91
    public select(): void {
92
        this.elementRef.nativeElement.classList.add('active');
93
    }
94

95
    public unselect(): void {
96
        this.elementRef.nativeElement.classList.remove('active');
97
    }
98

99
    private wrapSpanForText(nodes: NodeList): void {
100
        nodes.forEach(node => {
101
            if (node.nodeName === '#text') {
102
                const span = this.renderer.createElement('span');
103
                const parent = this.renderer.parentNode(node);
104
                this.renderer.insertBefore(parent, span, node);
105
                this.renderer.appendChild(span, node);
106
            }
107

108
            if (node.nodeName === '#text' || node.nodeName === 'SPAN') {
109
                this.isWithText.set(true);
110
            }
111
        });
112
    }
113
}
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