• 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

78.43
/src/table/table-column.component.ts
1
import {
2
    Component,
3
    ContentChild,
4
    ElementRef,
5
    EventEmitter,
6
    InjectionToken,
7
    Input,
8
    OnInit,
9
    Output,
10
    TemplateRef,
11
    ViewEncapsulation,
12
    inject
13
} from '@angular/core';
14
import { coerceBooleanProperty, coerceCssPixelValue, isArray, isObject } from 'ngx-tethys/util';
15
import { ThyTableSortDirection, ThyTableSortEvent } from './table.interface';
16
import { SafeAny } from 'ngx-tethys/types';
17

18
export interface IThyTableColumnParentComponent {
19
    rowKey: string;
20
    updateColumnSelections(key: string, selections: any): void;
21
}
22

23
/**
24
 * Injection token used to provide the parent component to options.
25
 */
1✔
26
export const THY_TABLE_COLUMN_PARENT_COMPONENT = new InjectionToken<IThyTableColumnParentComponent>('THY_TABLE_COLUMN_PARENT_COMPONENT');
27

28
export type FixedDirection = 'left' | 'right';
29

30
/**
31
 * 表格列组件
32
 * @name thy-table-column
33
 * @order 20
34
 */
35
@Component({
36
    selector: 'thy-table-column',
37
    template: '<ng-content></ng-content>',
38
    encapsulation: ViewEncapsulation.None
39
})
1✔
40
export class ThyTableColumnComponent implements OnInit {
400✔
41
    private el = inject(ElementRef);
400✔
42
    parent = inject(THY_TABLE_COLUMN_PARENT_COMPONENT, { optional: true })!;
43

44
    /**
45
     * 设置数据属性 Key,读取数组中对象的当前 Key 值
46
     * @type string
47
     */
400✔
48
    @Input('thyModelKey') model = '';
49

50
    /**
51
     * 设置列名,显示在表头
52
     * @type string
53
     */
400✔
54
    @Input('thyTitle') title = '';
55

56
    /**
57
     * 设置列的特殊类型,序列号、选择框、单选框、切换按钮
58
     * @type string
59
     */
400✔
60
    @Input('thyType') type = '';
61

400✔
62
    public width: string = '';
63

64
    /**
65
     * 设置列的宽度
66
     */
67
    @Input()
68
    set thyWidth(value: string | number) {
75✔
69
        this.width = coerceCssPixelValue(value);
70
    }
71

400✔
72
    public minWidth: string = '';
73

74
    /**
75
     * 设置列的最小宽度
76
     */
77
    @Input()
78
    set thyMinWidth(value: string | number) {
×
79
        this.minWidth = coerceCssPixelValue(value);
80
    }
81

82
    /**
83
     * 设置列的样式
84
     */
400✔
85
    @Input('thyClassName') className = '';
86

87
    /**
88
     * 设置列头部的 Class,即 th 元素上的样式
89
     * @type string
90
     */
400✔
91
    @Input('thyHeaderClassName') headerClassName = '';
92

93
    /**
94
     * 设置自定义类型的禁用状态
95
     * @type boolean
96
     */
400✔
97
    @Input({ alias: 'thyDisabled', transform: coerceBooleanProperty }) disabled = false;
98

99
    /**
100
     * thyType 为 checkbox 或者 radio 类型时选中的数据 ,支持单个对象,单个 Id,同时支持多个 Id,多个对象
101
     */
102
    @Input('thySelections')
103
    set selections(value: any) {
99✔
104
        if (value) {
89!
105
            this._selections = isArray(value) ? value : [value];
89✔
106
            this._selections = this._selections.map((item: string | number | object) => {
×
107
                return isObject(item) ? (item as Record<string, SafeAny>)[this.parent.rowKey] : item;
108
            });
89!
109
            if (!this._firstChange) {
×
110
                this.parent.updateColumnSelections(this.key, this._selections);
111
            }
112
        }
113
    }
114

115
    get selections() {
2,349✔
116
        return this._selections;
117
    }
118
    /**
119
     * 设置数据为空的时候显示的文本
120
     * @type string
121
     */
400✔
122
    @Input('thyDefaultText') defaultText = '';
123

124
    /**
125
     * 设置 Tree 模式下折叠展开按钮展示列,不传默认第一列
126
     */
400✔
127
    @Input({ alias: 'thyExpand', transform: coerceBooleanProperty }) expand = false;
128

129
    public sortable!: boolean;
130

131
    /**
132
     * 是否开启列排序功能(开启时 thyModelKey 为 必传)
133
     * @default false
134
     */
135
    @Input({ transform: coerceBooleanProperty })
136
    set thySortable(value: boolean) {
4✔
137
        if (value) {
3!
138
            if (this.model) {
3✔
139
                this.sortable = true;
140
            } else {
×
141
                throw new Error(`thyModelKey is required when sortable`);
142
            }
143
        } else {
1✔
144
            this.sortable = false;
145
        }
146
    }
147

148
    /**
149
     * 默认列排序顺序
150
     * @type 'asc' | 'desc' | ''
151
     */
400✔
152
    @Input('thySortDirection') sortDirection = ThyTableSortDirection.default;
153

154
    /**
155
     * 设置固定列
156
     */
157
    @Input('thyFixed') fixed?: FixedDirection;
158

159
    /**
160
     * 当前列是否是操作列,设置为 true 时会追加 thy-operation-links 样式类,文字居中
161
     * @default false
162
     */
163
    @Input({ alias: 'thyOperational', transform: coerceBooleanProperty }) operational?: boolean;
164

165
    /**
166
     * 当前列是否是次要列,设置为 true 时会追加 thy-table-column-secondary 样式类,文字颜色为 $gray-600
167
     * @default false
168
     */
169
    @Input({ alias: 'thySecondary', transform: coerceBooleanProperty }) secondary?: boolean;
170

171
    /**
172
     * 列排序修改事件
173
     */
400✔
174
    @Output('thySortChange') readonly sortChange: EventEmitter<ThyTableSortEvent> = new EventEmitter<ThyTableSortEvent>();
175

176
    @ContentChild('header', { static: true }) headerTemplateRef?: TemplateRef<any>;
177

178
    @ContentChild('cell', { static: true }) cellTemplateRef?: TemplateRef<any>;
179

180
    @ContentChild(TemplateRef, { static: true })
181
    set templateRef(value: TemplateRef<any>) {
400✔
182
        if (value) {
109!
183
            if (!this.headerTemplateRef && !this.cellTemplateRef) {
×
184
                this.cellTemplateRef = value;
185
            }
186
        }
187
    }
188

189
    public key!: string;
190

191
    public left?: number;
192

193
    public right?: number;
194

195
    private _selections: any;
196

400✔
197
    private _firstChange = true;
198

199
    ngOnInit() {
377✔
200
        this.key = this._generateKey();
377✔
201
        this._firstChange = false;
202
    }
203

204
    private _generateKey() {
377✔
205
        return `[$$column]${Math.random().toString(16).slice(2, 10)}`;
206
    }
207
}
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