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

atinc / ngx-tethys / d9ae709b-3c27-4b69-b125-b8b80b54f90b

pending completion
d9ae709b-3c27-4b69-b125-b8b80b54f90b

Pull #2757

circleci

mengshuicmq
fix: fix code review
Pull Request #2757: feat(color-picker): color-picker support disabled (#INFR-8645)

98 of 6315 branches covered (1.55%)

Branch coverage included in aggregate %.

1 of 1 new or added line in 1 file covered. (100.0%)

2392 of 13661 relevant lines covered (17.51%)

83.12 hits per line

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

6.67
/src/flexible-text/flexible-text.component.ts
1
import { ContentObserver } from '@angular/cdk/observers';
2
import { AfterContentInit, Component, ElementRef, Input, NgZone, OnDestroy, OnInit, TemplateRef, ViewContainerRef } from '@angular/core';
3
import { InputNumber, ThyPlacement } from 'ngx-tethys/core';
4
import { TooltipService } from 'ngx-tethys/tooltip';
5
import { isUndefinedOrNull } from 'ngx-tethys/util';
6
import { useHostRenderer } from '@tethys/cdk/dom';
7
import { from, Observable, Subject, Subscription } from 'rxjs';
8
import { debounceTime, take, takeUntil } from 'rxjs/operators';
9

10
/**
11
 * 文本提示组件,支持组件 thy-flexible-text 和指令 [thyFlexibleText] 两种方式
12
 * @name thy-flexible-text,[thyFlexibleText]
13
 */
14
@Component({
15
    selector: 'thy-flexible-text,[thyFlexibleText]',
16
    exportAs: 'thyFlexibleText',
1✔
17
    templateUrl: './flexible-text.component.html',
18
    providers: [TooltipService],
×
19
    standalone: true
×
20
})
21
export class ThyFlexibleTextComponent implements OnInit, AfterContentInit, OnDestroy {
22
    isOverflow = false;
×
23

24
    content: string | TemplateRef<HTMLElement>;
25

×
26
    placement: ThyPlacement;
×
27

×
28
    containerClass: string;
29

30
    subscription: Subscription | null = null;
31

×
32
    offset: number;
×
33

×
34
    /**
35
     * 触发提示方式
36
     * @type hover | focus | click
37
     * @default hover
×
38
     */
×
39
    @Input('thyTooltipTrigger') trigger: 'hover' | 'focus' | 'click';
×
40

41
    /**
42
     * 自定义class类,如果不设置默认会包含 `flexible-text-container`
43
     */
×
44
    @Input('thyContainerClass')
×
45
    set thyContainerClass(value: string) {
×
46
        this.containerClass = value;
×
47
        this.updateContainerClass();
×
48
    }
×
49

×
50
    get thyContainerClass(): string {
×
51
        return this.containerClass;
×
52
    }
53

54
    /**
×
55
     * 需要展示的全部内容
×
56
     * @type string | TemplateRef<HTMLElement>
×
57
     */
58
    @Input('thyTooltipContent') set thyContent(value: string | TemplateRef<HTMLElement>) {
×
59
        this.content = value;
×
60
        if (this.tooltipService.thyTooltipDirective) {
×
61
            this.tooltipService.thyTooltipDirective.content = this.content;
62
        }
63
    }
64

65
    /**
×
66
     * tooltip 的提示位置
×
67
     * @type top | bottom | left | right
×
68
     * @default top
×
69
     */
70
    @Input('thyTooltipPlacement') set thyPlacement(value: ThyPlacement) {
×
71
        this.placement = value;
×
72
        if (this.tooltipService.thyTooltipDirective) {
73
            this.tooltipService.thyTooltipDirective.placement = this.placement;
×
74
        }
×
75
    }
76

77
    /**
78
     * tooltip 偏移量
79
     */
×
80
    @Input('thyTooltipOffset') @InputNumber() set thyOffset(value: number) {
81
        this.offset = value;
82
        if (this.tooltipService.thyTooltipDirective) {
×
83
            this.tooltipService.thyTooltipDirective.tooltipOffset = this.offset;
84
        }
×
85
    }
×
86

87
    private destroy$ = new Subject<void>();
88

89
    private hostRenderer = useHostRenderer();
×
90

91
    constructor(
×
92
        private elementRef: ElementRef,
93
        private viewContainerRef: ViewContainerRef,
94
        public tooltipService: TooltipService,
×
95
        private contentObserver: ContentObserver,
96
        private ngZone: NgZone
97
    ) {}
98

99
    static createResizeObserver(element: HTMLElement) {
100
        return new Observable(observer => {
×
101
            const resize = new ResizeObserver(entries => {
×
102
                observer.next(entries);
103
            });
104
            resize.observe(element);
×
105
            return () => {
×
106
                resize.disconnect();
×
107
            };
108
        });
109
    }
×
110

111
    ngOnInit() {
×
112
        this.updateContainerClass();
113
        this.tooltipService.attach(this.elementRef, this.viewContainerRef, this.trigger);
114
        if (this.placement) {
×
115
            this.tooltipService.thyTooltipDirective.placement = this.placement;
×
116
        }
117
        if (this.offset) {
118
            this.tooltipService.thyTooltipDirective.tooltipOffset = this.offset;
119
        }
×
120
        this.tooltipService.thyTooltipDirective.content = this.content;
121
        this.tooltipService.thyTooltipDirective.thyTooltipDisabled = true;
1✔
122
    }
123

124
    ngAfterContentInit() {
125
        // Note: the zone may be nooped through `BootstrapOptions` when bootstrapping the root module. This means
126
        // the `onStable` will never emit any value.
127
        const onStable$ = this.ngZone.isStable ? from(Promise.resolve()) : this.ngZone.onStable.pipe(take(1));
128
        // Normally this isn't in the zone, but it can cause performance regressions for apps
1✔
129
        // using `zone-patch-rxjs` because it'll trigger a change detection when it unsubscribes.
130
        this.ngZone.runOutsideAngular(() => {
131
            // Wait for the next time period to avoid blocking the js thread.
132
            onStable$.pipe(takeUntil(this.destroy$)).subscribe(() => {
133
                this.contentObserver
134
                    .observe(this.elementRef)
135
                    .pipe(debounceTime(100), takeUntil(this.destroy$))
136
                    .subscribe(() => {
1✔
137
                        this.applyOverflow();
138
                    });
139

140
                ThyFlexibleTextComponent.createResizeObserver(this.elementRef.nativeElement)
141
                    .pipe(debounceTime(100), takeUntil(this.destroy$))
1✔
142
                    .subscribe(() => {
143
                        this.applyOverflow();
144
                    });
145
            });
146
        });
147
    }
148

149
    ngOnDestroy() {
150
        this.destroy$.next();
151
        this.tooltipService.detach();
152
    }
153

154
    applyOverflow() {
155
        const nativeElement = this.elementRef.nativeElement;
156
        if (nativeElement.clientWidth < nativeElement.scrollWidth || nativeElement.clientHeight < nativeElement.scrollHeight) {
157
            this.isOverflow = true;
158
        } else {
159
            this.isOverflow = false;
160
        }
161
        this.tooltipService.thyTooltipDirective.thyTooltipDisabled = !this.isOverflow;
162
    }
163

164
    updateContainerClass() {
165
        const containerClass = isUndefinedOrNull(this.containerClass) ? 'flexible-text-container' : this.containerClass;
166
        const flexibleTextClass = {
167
            'text-truncate': true,
168
            [containerClass]: containerClass !== ''
169
        };
170
        this.hostRenderer.updateClassByMap(flexibleTextClass);
171
    }
172
}
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