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

atinc / ngx-tethys / b66b74a3-9903-48d8-bdbb-209455e25694

23 Aug 2023 06:27AM UTC coverage: 90.181% (+0.02%) from 90.157%
b66b74a3-9903-48d8-bdbb-209455e25694

push

circleci

web-flow
feat(datePicker): #INFR-9165 support thyMode dynamically switched (#2770)

5110 of 6321 branches covered (80.84%)

Branch coverage included in aggregate %.

19 of 19 new or added lines in 3 files covered. (100.0%)

12909 of 13660 relevant lines covered (94.5%)

976.52 hits per line

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

87.78
/src/date-picker/base-picker.component.ts
1
import { InputBoolean, ThyPlacement } from 'ngx-tethys/core';
2
import { coerceBooleanProperty, elementMatchClosest, FunctionProp, TinyDate } from 'ngx-tethys/util';
3

4
import { ChangeDetectorRef, Component, ElementRef, EventEmitter, Input, OnChanges, OnInit, Output, TemplateRef } from '@angular/core';
5

6
import { AbstractPickerComponent } from './abstract-picker.component';
7
import { CompatibleValue, RangeAdvancedValue } from './inner-types';
8
import { CompatibleDate, ThyPanelMode } from './standard-types';
9

1✔
10
/**
11
 * @private
121✔
12
 */
121✔
13
@Component({
4✔
14
    template: ``,
15
    standalone: true,
16
    host: {
17
        '[attr.tabindex]': `tabIndex`,
123✔
18
        '(focus)': 'onFocus($event)',
19
        '(blur)': 'onBlur($event)'
20
    }
394✔
21
})
22
export class BasePickerComponent extends AbstractPickerComponent implements OnInit, OnChanges {
23
    showWeek = false;
51!
24

25
    panelMode: ThyPanelMode | ThyPanelMode[];
26

123✔
27
    initialized: boolean;
123✔
28

123✔
29
    @Input() thyDateRender: FunctionProp<TemplateRef<Date> | string>;
123✔
30

123✔
31
    @Input() set thyMode(value: ThyPanelMode) {
123✔
32
        this._panelMode = value ?? 'date';
123✔
33
        if (this.initialized) {
123✔
34
            this.setDefaultTimePickerState(this._panelMode);
35
        }
36
    }
123✔
37

123✔
38
    get thyMode() {
123✔
39
        return this._panelMode;
40
    }
41

43✔
42
    /**
43✔
43
     * @type EventEmitter<ThyPanelMode | ThyPanelMode[]>
43✔
44
     */
37✔
45
    @Output() readonly thyOnPanelChange = new EventEmitter<ThyPanelMode | ThyPanelMode[]>();
46

47
    /**
48
     * @type EventEmitter<Date[]>
49
     */
127✔
50
    @Output() readonly thyOnCalendarChange = new EventEmitter<Date[]>();
127✔
51

53✔
52
    private _showTime: object | boolean;
53

54
    /**
74✔
55
     * 增加时间选择功能
56
     * @default false
127✔
57
     */
127✔
58
    @Input() get thyShowTime(): object | boolean {
105✔
59
        return this._showTime;
60
    }
61
    set thyShowTime(value: object | boolean) {
62
        this._showTime = typeof value === 'object' ? value : coerceBooleanProperty(value);
105✔
63
    }
64

105✔
65
    /**
66
     * 是否展示时间(时、分)
67
     * @default false
68
     */
69
    @Input() @InputBoolean() thyMustShowTime = false;
43✔
70

6✔
71
    /**
72
     * 弹出位置
73
     * @type top | topLeft | topRight | bottom | bottomLeft | bottomRight | left | leftTop | leftBottom | right | rightTop | rightBottom
74
     */
75
    @Input() thyPlacement: ThyPlacement = 'bottomLeft';
10!
76

15✔
77
    /**
10✔
78
     * @type EventEmitter<CompatibleDate | null>
79
     */
80
    @Output() readonly thyOnOk = new EventEmitter<CompatibleDate | null>();
81

23✔
82
    constructor(cdr: ChangeDetectorRef, protected element: ElementRef) {
83
        super(cdr);
84
    }
5!
85

×
86
    ngOnInit(): void {
×
87
        super.ngOnInit();
×
88
        this.setDefaultTimePickerState(this._panelMode);
89
        this.initialized = true;
90
    }
×
91

92
    onValueChange(value: CompatibleValue | RangeAdvancedValue): void {
93
        this.restoreTimePickerState(value as CompatibleValue);
94
        super.onValueChange(value);
5!
95
        if (!this.flexible) {
5✔
96
            this.closeOverlay();
97
        }
98
    }
×
99

100
    // Displays the time directly when the time must be displayed by default
101
    setDefaultTimePickerState(value: ThyPanelMode) {
5✔
102
        this.withTime = this.thyMustShowTime;
103
        if (this.isRange) {
104
            this.panelMode = this.flexible ? ['date', 'date'] : [value, value];
139✔
105
        } else {
139✔
106
            this.panelMode = value;
44✔
107
        }
108
        this.showWeek = value === 'week';
109
        if (!this.thyFormat) {
110
            const inputFormats: { [key in ThyPanelMode]?: string } = {
1✔
111
                year: 'yyyy',
112
                month: 'yyyy-MM',
113
                week: 'yyyy-ww周',
114
                date: this.thyShowTime ? 'yyyy-MM-dd HH:mm' : 'yyyy-MM-dd'
2✔
115
            };
1✔
116
            this.thyFormat = this.flexible ? inputFormats['date'] : inputFormats[value];
117
        }
1✔
118
    }
119

1✔
120
    // Restore after clearing time to select whether the original picker time is displayed or not
121
    restoreTimePickerState(value: CompatibleValue | null) {
122
        if (!value) {
123
            this.withTime = this.thyMustShowTime || this.originWithTime;
1✔
124
        }
125
    }
126

127
    // Emit thyOnCalendarChange when select date by thy-range-picker
128
    onCalendarChange(value: TinyDate[]): void {
129
        if (this.isRange) {
130
            const rangeValue = value.map(x => x.nativeDate);
131
            this.thyOnCalendarChange.emit(rangeValue);
132
        }
133
    }
134

1✔
135
    onShowTimePickerChange(show: boolean): void {
136
        this.withTime = show;
137
    }
138

1✔
139
    onResultOk(): void {
140
        if (this.isRange) {
141
            const value = this.thyValue as TinyDate[];
142
            if (value.length) {
143
                this.thyOnOk.emit([value[0].nativeDate, value[1].nativeDate]);
144
            } else {
145
                this.thyOnOk.emit([]);
146
            }
147
        } else {
148
            if (this.thyValue) {
149
                this.thyOnOk.emit((this.thyValue as TinyDate).nativeDate);
150
            } else {
151
                this.thyOnOk.emit(null);
152
            }
153
        }
154
        this.closeOverlay();
155
    }
156

157
    onOpenChange(open: boolean): void {
158
        this.thyOpenChange.emit(open);
159
        if (!open) {
160
            this.onTouchedFn();
161
        }
162
    }
163

164
    onFocus(event: Event) {
165
        this.picker.focus();
166
    }
167

168
    onBlur(event?: FocusEvent) {
169
        // Tab 聚焦后自动聚焦到 input 输入框,此分支下直接返回,无需触发 onTouchedFn
170
        if (elementMatchClosest(event?.relatedTarget as HTMLElement, ['date-popup', 'thy-picker'])) {
171
            return;
172
        }
173
        this.onTouchedFn();
174
    }
175
}
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