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

atinc / ngx-tethys / #102

26 May 2026 08:11AM UTC coverage: 91.111% (+0.7%) from 90.407%
#102

push

web-flow
build: bump docgeni to 2.8.0-next.5 (#3809)

4571 of 5491 branches covered (83.25%)

Branch coverage included in aggregate %.

13141 of 13949 relevant lines covered (94.21%)

966.75 hits per line

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

97.44
/src/skeleton/skeleton-rectangle.component.ts
1
import { NgStyle } from '@angular/common';
2
import { ChangeDetectionStrategy, Component, computed, inject, input, ViewEncapsulation } from '@angular/core';
3
import { coerceBooleanProperty, coerceCssPixelValue, helpers, isUndefinedOrNull, ThyBooleanInput } from 'ngx-tethys/util';
4
import { ThySkeleton } from './skeleton.component';
5
import { THY_SKELETON_CONFIG } from './skeleton.config';
6

7
/**
8
 * 骨架屏矩形组件
9
 * @name thy-skeleton-rectangle
10
 * @order 20
11
 */
12
@Component({
13
    selector: 'thy-skeleton-rectangle',
14
    host: {
15
        '[class.thy-skeleton]': 'true',
16
        '[class.thy-skeleton-rectangle]': 'true',
17
        '[style.background]': 'primaryColor()',
18
        '[style.width]': 'thyRowWidth()',
19
        '[style.height]': 'thyRowHeight()',
20
        '[style.borderRadius]': 'thyBorderRadius()'
21
    },
22
    template: ` <div class="thy-skeleton-after" [ngStyle]="afterStyles()"></div> `,
23
    changeDetection: ChangeDetectionStrategy.OnPush,
24
    encapsulation: ViewEncapsulation.None,
25
    imports: [NgStyle]
26
})
27
export class ThySkeletonRectangle {
1✔
28
    private skeletonConfigModel = inject(THY_SKELETON_CONFIG, { optional: true });
117✔
29

30
    private parent = inject(ThySkeleton, { optional: true })!;
117✔
31

32
    /**
33
     * 是否展示动画
34
     * @default true
35
     */
36
    readonly thyAnimated = input<boolean, ThyBooleanInput>(undefined, { transform: coerceBooleanProperty });
117✔
37

38
    /**
39
     * 动画速度
40
     * @default 1.5s
41
     */
42
    readonly thyAnimatedInterval = input<string | number>();
117✔
43

44
    /**
45
     * 骨架边框圆角
46
     * @default 4px
47
     */
48
    readonly thyBorderRadius = input<string, string | number>(undefined, { transform: coerceCssPixelValue });
117✔
49

50
    /**
51
     * 骨架宽度
52
     * @default 100%
53
     */
54
    readonly thyRowWidth = input<string, string | number>(undefined, { transform: coerceCssPixelValue });
117✔
55

56
    /**
57
     * 骨架高度
58
     * @default 20px
59
     */
60
    readonly thyRowHeight = input<string, string | number>(undefined, { transform: coerceCssPixelValue });
117✔
61

62
    /**
63
     * 骨架主色
64
     * @default #F7F7F7
65
     */
66
    readonly thyPrimaryColor = input<string>();
117✔
67

68
    /**
69
     * 骨架次色
70
     * @default #aaaaaa
71
     */
72
    readonly thySecondaryColor = input<string>();
117✔
73

74
    readonly animatedInterval = computed(() => {
117✔
75
        return this.thyAnimatedInterval() || this.parent?.thyAnimatedInterval() || this.skeletonConfigModel?.thyAnimatedInterval;
116✔
76
    });
77

78
    readonly primaryColor = computed(() => {
117✔
79
        return this.thyPrimaryColor() || this.parent?.thyPrimaryColor() || this.skeletonConfigModel?.thyPrimaryColor;
121✔
80
    });
81

82
    readonly secondaryColor = computed(() => {
117✔
83
        return this.thySecondaryColor() || this.parent?.thySecondaryColor() || this.skeletonConfigModel?.thySecondaryColor;
117✔
84
    });
85

86
    readonly animated = computed(() => {
117✔
87
        if (!isUndefinedOrNull(this.thyAnimated())) {
117✔
88
            return this.thyAnimated();
115✔
89
        }
90
        if (!isUndefinedOrNull(this.parent?.thyAnimated())) {
2✔
91
            return this.parent.thyAnimated();
2✔
92
        }
93
        return this.skeletonConfigModel?.thyAnimated;
×
94
    });
95

96
    readonly afterStyles = computed(() => {
117✔
97
        return {
117✔
98
            ...(this.secondaryColor() && {
122✔
99
                background: `linear-gradient(90deg, ${helpers.hexToRgb(this.secondaryColor()!, 0)}, ${helpers.hexToRgb(
100
                    this.secondaryColor()!,
101
                    0.15
102
                )}, ${helpers.hexToRgb(this.secondaryColor()!, 0)}`
103
            }),
104
            animation: ![false, 'false'].includes(this.animated()!) ? `thy-skeleton-animation ${this.animatedInterval()}s infinite` : 'none'
117✔
105
        };
106
    });
107
}
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