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

atinc / ngx-tethys / f2387ab8-6fe4-4140-b09f-990c71f4bead

16 May 2025 10:24AM UTC coverage: 90.205% (-0.1%) from 90.323%
f2387ab8-6fe4-4140-b09f-990c71f4bead

push

circleci

web-flow
refactor(skeleton): migrate to signal for skeleton #TINFR-1769 (#3407)

5570 of 6835 branches covered (81.49%)

Branch coverage included in aggregate %.

21 of 43 new or added lines in 5 files covered. (48.84%)

10 existing lines in 5 files now uncovered.

13566 of 14379 relevant lines covered (94.35%)

908.71 hits per line

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

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

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

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

33
    /**
14✔
34
     * 动画速度
14✔
35
     * @default 1.5s
12✔
36
     */
37
    readonly thyAnimatedInterval = input<string | number>();
2!
38

2✔
39
    /**
UNCOV
40
     * 骨架尺寸
×
41
     * @default 20px
42
     */
14✔
43
    readonly thySize = input<string, string | number>(`20px`, { transform: coerceCssPixelValue });
14✔
44

19✔
45
    /**
46
     * 骨架主色
47
     * @default #F7F7F7
14✔
48
     */
49
    readonly thyPrimaryColor = input<string>();
50

51
    /**
1✔
52
     * 骨架次色
53
     * @default #aaaaaa
54
     */
55
    readonly thySecondaryColor = input<string>();
56

57
    /**
58
     * 是否展示动画
59
     * @default true
1✔
60
     */
61
    readonly thyAnimated = input<boolean, ThyBooleanInput>(undefined, { transform: coerceBooleanProperty });
62

63
    readonly animatedInterval = computed(() => {
64
        return this.thyAnimatedInterval() || this.parent?.thyAnimatedInterval() || this.skeletonConfigModel.thyAnimatedInterval;
65
    });
66

67
    readonly primaryColor = computed(() => {
68
        return this.thyPrimaryColor() || this.parent?.thyPrimaryColor() || this.skeletonConfigModel.thyPrimaryColor;
69
    });
70

71
    readonly secondaryColor = computed(() => {
72
        return this.thySecondaryColor() || this.parent?.thySecondaryColor() || this.skeletonConfigModel.thySecondaryColor;
73
    });
74

75
    readonly animated = computed(() => {
76
        if (!isUndefinedOrNull(this.thyAnimated())) {
77
            return this.thyAnimated();
78
        }
79
        if (!isUndefinedOrNull(this.parent?.thyAnimated())) {
80
            return this.parent.thyAnimated();
81
        }
82
        return this.skeletonConfigModel.thyAnimated;
83
    });
84

85
    readonly afterStyles = computed(() => {
86
        return {
87
            ...(this.secondaryColor() && {
88
                background: `linear-gradient(90deg, ${helpers.hexToRgb(this.secondaryColor(), 0)}, ${helpers.hexToRgb(
89
                    this.secondaryColor(),
90
                    0.15
91
                )}, ${helpers.hexToRgb(this.secondaryColor(), 0)}`
92
            }),
93
            animation: ![false, 'false'].includes(this.animated()) ? `thy-skeleton-animation ${this.animatedInterval()}s infinite` : 'none'
94
        };
95
    });
96
}
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