@odx/angular 5.7.0 → 5.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/components/datepicker/lib/datepicker.component.d.ts +1 -0
- package/components/timepicker/README.md +3 -0
- package/components/timepicker/index.d.ts +7 -0
- package/components/timepicker/lib/components/timepicker-option.component.d.ts +28 -0
- package/components/timepicker/lib/directives/timepicker-input-control.directive.d.ts +44 -0
- package/components/timepicker/lib/timepicker.component.d.ts +82 -0
- package/components/timepicker/lib/timepicker.module.d.ts +10 -0
- package/components/timepicker/lib/timepicker.service.d.ts +57 -0
- package/components/timepicker/lib/timepicker.token.d.ts +9 -0
- package/components/timepicker/lib/utils/generate-time-stamps.d.ts +18 -0
- package/components/timepicker/lib/utils/index.d.ts +2 -0
- package/components/timepicker/lib/utils/ngx-mask-helper.d.ts +22 -0
- package/esm2022/components/datepicker/lib/datepicker.component.mjs +4 -3
- package/esm2022/components/timepicker/index.mjs +8 -0
- package/esm2022/components/timepicker/lib/components/timepicker-option.component.mjs +59 -0
- package/esm2022/components/timepicker/lib/directives/timepicker-input-control.directive.mjs +94 -0
- package/esm2022/components/timepicker/lib/timepicker.component.mjs +213 -0
- package/esm2022/components/timepicker/lib/timepicker.module.mjs +20 -0
- package/esm2022/components/timepicker/lib/timepicker.service.mjs +92 -0
- package/esm2022/components/timepicker/lib/timepicker.token.mjs +9 -0
- package/esm2022/components/timepicker/lib/utils/generate-time-stamps.mjs +52 -0
- package/esm2022/components/timepicker/lib/utils/index.mjs +3 -0
- package/esm2022/components/timepicker/lib/utils/ngx-mask-helper.mjs +34 -0
- package/esm2022/components/timepicker/odx-angular-components-timepicker.mjs +5 -0
- package/esm2022/localization/lib/localization.config.mjs +5 -4
- package/esm2022/localization/lib/localization.service.mjs +18 -5
- package/fesm2022/odx-angular-components-datepicker.mjs +3 -2
- package/fesm2022/odx-angular-components-datepicker.mjs.map +1 -1
- package/fesm2022/odx-angular-components-timepicker.mjs +548 -0
- package/fesm2022/odx-angular-components-timepicker.mjs.map +1 -0
- package/fesm2022/odx-angular-localization.mjs +22 -8
- package/fesm2022/odx-angular-localization.mjs.map +1 -1
- package/localization/lib/localization.config.d.ts +2 -0
- package/localization/lib/localization.service.d.ts +5 -1
- package/package.json +7 -1
|
@@ -0,0 +1,548 @@
|
|
|
1
|
+
import { __decorate, __metadata } from 'tslib';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
import { InjectionToken, inject, EventEmitter, Component, ViewEncapsulation, ChangeDetectionStrategy, Output, Injectable, Directive, booleanAttribute, numberAttribute, forwardRef, ViewChild, ViewChildren, Input, HostListener, NgModule } from '@angular/core';
|
|
4
|
+
import * as i1 from '@odx/angular';
|
|
5
|
+
import { DisabledController, detectControllerChanges, WithDisabledState, WindowRef, WithTabIndex, ReadonlyController, CoreModule } from '@odx/angular';
|
|
6
|
+
import { OptionControl } from '@odx/angular/cdk/option-control';
|
|
7
|
+
import { CSSComponent } from '@odx/angular/internal';
|
|
8
|
+
import { InputControlDirective, CustomFormControl } from '@odx/angular/cdk/custom-form-control';
|
|
9
|
+
import { NgxMaskPipe, provideNgxMask } from 'ngx-mask';
|
|
10
|
+
import { fromEvent, distinctUntilChanged, map } from 'rxjs';
|
|
11
|
+
import { isBefore, isEqual, isAfter } from 'date-fns';
|
|
12
|
+
import { ActiveDescendantKeyManager, A11yModule } from '@angular/cdk/a11y';
|
|
13
|
+
import { ActionGroupComponent } from '@odx/angular/components/action-group';
|
|
14
|
+
import { ButtonComponent } from '@odx/angular/components/button';
|
|
15
|
+
import * as i3 from '@odx/angular/components/dropdown';
|
|
16
|
+
import { DropdownDirective, DropdownModule } from '@odx/angular/components/dropdown';
|
|
17
|
+
import { IconComponent } from '@odx/angular/components/icon';
|
|
18
|
+
import { untilDestroyed, trackByIndex, injectElement, isFunction } from '@odx/angular/utils';
|
|
19
|
+
import * as i1$1 from '@angular/common';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* An InjectionToken used for injecting an instance of TimepickerComponent.
|
|
23
|
+
* This token facilitates the decoupling of the TimepickerComponent's implementation from its consumption,
|
|
24
|
+
* allowing for more flexible and maintainable code, especially in scenarios requiring custom time picker
|
|
25
|
+
* behavior or appearance.
|
|
26
|
+
*/
|
|
27
|
+
const TIMEPICKER_CONTROL = new InjectionToken('@odx/angular/components/timepicker::TimepickerComponent');
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Represents a selectable option within a timepicker component. This component allows for
|
|
31
|
+
* individual time values to be selected from a dropdown menu as part of the timepicker interface.
|
|
32
|
+
* It integrates with the timepicker's control to manage selection state and accessibility.
|
|
33
|
+
*
|
|
34
|
+
* @extends {OptionControl<string>}
|
|
35
|
+
*/
|
|
36
|
+
let TimepickerOptionComponent = class TimepickerOptionComponent extends OptionControl {
|
|
37
|
+
get disabled() {
|
|
38
|
+
return !!this.disabledController?.disabled;
|
|
39
|
+
}
|
|
40
|
+
constructor() {
|
|
41
|
+
super();
|
|
42
|
+
this.timepicker = inject(TIMEPICKER_CONTROL);
|
|
43
|
+
this.disabledController = DisabledController.inject();
|
|
44
|
+
this.isSelected = false;
|
|
45
|
+
this.isActive = false;
|
|
46
|
+
/**
|
|
47
|
+
* Emits an event when the option is selected, allowing the timepicker component to update its value and close the dropdown.
|
|
48
|
+
*/
|
|
49
|
+
this.selected = new EventEmitter();
|
|
50
|
+
detectControllerChanges(this.timepicker).pipe(this.takeUntilDestroyed()).subscribe();
|
|
51
|
+
}
|
|
52
|
+
ngOnInit() {
|
|
53
|
+
this.isSelected = this.timepicker.isTimeOptionSelected(this);
|
|
54
|
+
}
|
|
55
|
+
selectOption() {
|
|
56
|
+
this.selected.emit(this);
|
|
57
|
+
}
|
|
58
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TimepickerOptionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
59
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TimepickerOptionComponent, isStandalone: true, selector: "odx-timepicker-option", outputs: { selected: "selected" }, providers: [DisabledController.connect()], usesInheritance: true, hostDirectives: [{ directive: i1.WithDisabledState }], ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
60
|
+
};
|
|
61
|
+
TimepickerOptionComponent = __decorate([
|
|
62
|
+
CSSComponent('timepicker-option'),
|
|
63
|
+
__metadata("design:paramtypes", [])
|
|
64
|
+
], TimepickerOptionComponent);
|
|
65
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TimepickerOptionComponent, decorators: [{
|
|
66
|
+
type: Component,
|
|
67
|
+
args: [{
|
|
68
|
+
selector: 'odx-timepicker-option',
|
|
69
|
+
template: `<ng-content></ng-content>`,
|
|
70
|
+
standalone: true,
|
|
71
|
+
encapsulation: ViewEncapsulation.None,
|
|
72
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
73
|
+
providers: [DisabledController.connect()],
|
|
74
|
+
hostDirectives: [WithDisabledState],
|
|
75
|
+
}]
|
|
76
|
+
}], ctorParameters: function () { return []; }, propDecorators: { selected: [{
|
|
77
|
+
type: Output
|
|
78
|
+
}] } });
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Service to provide utility functions for timepicker components, including validation, placeholder generation, and finding the closest time.
|
|
82
|
+
* It also handles locale-based time formatting.
|
|
83
|
+
*/
|
|
84
|
+
class TimepickerService {
|
|
85
|
+
constructor() {
|
|
86
|
+
this.windowRef = inject(WindowRef);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Generates a placeholder string for time input fields.
|
|
90
|
+
*
|
|
91
|
+
* @param {boolean} apm - Specifies if the placeholder should include AM/PM notation.
|
|
92
|
+
* @returns {string} The placeholder string.
|
|
93
|
+
*/
|
|
94
|
+
getPlaceholder(apm = false) {
|
|
95
|
+
return apm ? '--:-- --' : '--:--';
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Validates if the given time is less than or equal to a maximum time constraint.
|
|
99
|
+
*
|
|
100
|
+
* @param {string} time - The time to validate.
|
|
101
|
+
* @param {string} max - The maximum allowable time.
|
|
102
|
+
* @returns {boolean} True if the time is valid, false otherwise.
|
|
103
|
+
*/
|
|
104
|
+
maxValidation(time, max) {
|
|
105
|
+
const [targetValue, maxValue] = this.convertToDates([time, max]);
|
|
106
|
+
return isBefore(targetValue, maxValue) || isEqual(targetValue, maxValue);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Validates if the given time is greater than or equal to a minimum time constraint.
|
|
110
|
+
*
|
|
111
|
+
* @param {string} time - The time to validate.
|
|
112
|
+
* @param {string} min - The minimum allowable time.
|
|
113
|
+
* @returns {boolean} True if the time is valid, false otherwise.
|
|
114
|
+
*/
|
|
115
|
+
minValidation(time, min) {
|
|
116
|
+
const [targetValue, minValue] = this.convertToDates([time, min]);
|
|
117
|
+
return isAfter(targetValue, minValue) || isEqual(targetValue, minValue);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Finds the closest time to a target time from a list of times.
|
|
121
|
+
*
|
|
122
|
+
* @param {string[]} timeStamps - The list of times to search through.
|
|
123
|
+
* @param {string} targetTime - The target time to find the closest match for.
|
|
124
|
+
* @returns {string} The closest time to the target.
|
|
125
|
+
*/
|
|
126
|
+
findClosestDate(timeStamps, targetTime) {
|
|
127
|
+
const [target] = this.convertToDates([targetTime]);
|
|
128
|
+
const datesArray = this.convertToDates(timeStamps);
|
|
129
|
+
const closestDate = datesArray.reduce((prev, curr) => {
|
|
130
|
+
return Math.abs(curr.getTime() - target.getTime()) < Math.abs(prev.getTime() - target.getTime()) ? curr : prev;
|
|
131
|
+
});
|
|
132
|
+
return this.getLocalizedTimeFormat(`${closestDate.getHours()}:${closestDate.getMinutes()}`);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Formats a time string to a localized time format.
|
|
136
|
+
*
|
|
137
|
+
* @param {string} time - The time string to format.
|
|
138
|
+
* @param {boolean} hour12 - Specifies if the output should use 12-hour format with AM/PM notation.
|
|
139
|
+
* @returns {string} The formatted time string.
|
|
140
|
+
*/
|
|
141
|
+
getLocalizedTimeFormat(time, hour12 = false) {
|
|
142
|
+
const locale = hour12 ? 'en-US' : 'en-GB';
|
|
143
|
+
const [date] = this.convertToDates([time]);
|
|
144
|
+
return new this.windowRef.nativeWindow.Intl.DateTimeFormat(locale, {
|
|
145
|
+
hour: '2-digit',
|
|
146
|
+
minute: '2-digit',
|
|
147
|
+
hour12,
|
|
148
|
+
}).format(date);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Converts an array of time strings to an array of Date objects.
|
|
152
|
+
*
|
|
153
|
+
* @param {string[]} times - The time strings to convert.
|
|
154
|
+
* @returns {Date[]} An array of Date objects corresponding to the input times.
|
|
155
|
+
* @private
|
|
156
|
+
*/
|
|
157
|
+
convertToDates(times) {
|
|
158
|
+
return times.map((time) => new Date(`${time} 2022-12-19`));
|
|
159
|
+
}
|
|
160
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TimepickerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
161
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TimepickerService, providedIn: 'root' }); }
|
|
162
|
+
}
|
|
163
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TimepickerService, decorators: [{
|
|
164
|
+
type: Injectable,
|
|
165
|
+
args: [{ providedIn: 'root' }]
|
|
166
|
+
}] });
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Processes and formats a time input value based on specific rules. It adjusts the input for valid time format,
|
|
170
|
+
* especially focusing on single-digit hour inputs, ensuring minute values start with 0 if the last digit is greater
|
|
171
|
+
* than 5, and appending 'M' to AM/PM indicators.
|
|
172
|
+
*
|
|
173
|
+
* @param {string} value - The current input value of the time field.
|
|
174
|
+
* @param {InputEvent} event - The input event triggered by the user's interaction with the field.
|
|
175
|
+
* @returns {string} The processed and potentially reformatted value.
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* // Prepend 0 to single-digit hours greater than 1
|
|
179
|
+
* processInputValue("2", { inputType: "insertText" }); // Returns "02"
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* // Ensure minute values are within valid ranges
|
|
183
|
+
* processInputValue("11:8", { inputType: "insertText" }); // Returns "11:08"
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* // Append 'M' to AM/PM indicators
|
|
187
|
+
* processInputValue("2 p", { inputType: "insertText" }); // Returns "2 PM"
|
|
188
|
+
*/
|
|
189
|
+
function processInputValue(value, event) {
|
|
190
|
+
if (value.length === 1 && Number(value) > 1) {
|
|
191
|
+
value = `0${value}`;
|
|
192
|
+
}
|
|
193
|
+
else if (value.length === 4 && Number(value.at(-1)) > 5) {
|
|
194
|
+
value = `${value.slice(0, -1)}0${value.slice(-1)}`;
|
|
195
|
+
}
|
|
196
|
+
if (/[AaPp]/.test(value) && event.inputType === 'insertText') {
|
|
197
|
+
value = `${value.toUpperCase()}M`;
|
|
198
|
+
}
|
|
199
|
+
return value;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Directive to enhance a standard input element for time picking, integrating mask functionality for time format.
|
|
204
|
+
* It automatically adapts to locale settings provided by the enclosing `TimepickerComponent` to display time in the appropriate format.
|
|
205
|
+
*
|
|
206
|
+
* @extends {InputControlDirective}
|
|
207
|
+
*/
|
|
208
|
+
let TimepickerInputControlDirective = class TimepickerInputControlDirective extends InputControlDirective {
|
|
209
|
+
constructor() {
|
|
210
|
+
super(...arguments);
|
|
211
|
+
this.timepicker = inject(TIMEPICKER_CONTROL);
|
|
212
|
+
this.timepickerService = inject(TimepickerService);
|
|
213
|
+
this.ngxMaskPipe = inject(NgxMaskPipe);
|
|
214
|
+
/**
|
|
215
|
+
* Stream of value changes for the input element, applying the mask and processing the input based on locale.
|
|
216
|
+
*/
|
|
217
|
+
this.valueChange$ = fromEvent(this.element.nativeElement, 'input').pipe(distinctUntilChanged(), map((event) => this.applyMask(event)));
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Configuration for the mask applied to the timepicker input. Adjusts based on locale settings.
|
|
221
|
+
*/
|
|
222
|
+
get maskConfig() {
|
|
223
|
+
return {
|
|
224
|
+
validation: false,
|
|
225
|
+
apm: this.timepicker.useLocale,
|
|
226
|
+
leadZeroDateTime: !this.timepicker.useLocale,
|
|
227
|
+
patterns: {
|
|
228
|
+
A: { pattern: new RegExp('[AaPp]') },
|
|
229
|
+
M: { pattern: new RegExp('M') },
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Computes and returns the placeholder text for the input based on locale settings.
|
|
235
|
+
*
|
|
236
|
+
* @returns {string} The placeholder text for the input.
|
|
237
|
+
*/
|
|
238
|
+
get placeholder() {
|
|
239
|
+
return this.timepickerService.getPlaceholder(this.timepicker.useLocale);
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Determines whether the timepicker input is readonly, based on the state of the parent timepicker component.
|
|
243
|
+
*
|
|
244
|
+
* @returns {boolean} `true` if the input should be readonly; otherwise, `false`.
|
|
245
|
+
*/
|
|
246
|
+
get isReadonly() {
|
|
247
|
+
return this.timepicker.isReadonly;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Applies the time format mask to the input value, transforming and returning the masked value.
|
|
251
|
+
*
|
|
252
|
+
* @param {Event} event - The input event triggering the mask application.
|
|
253
|
+
* @returns {string} The masked input value.
|
|
254
|
+
*/
|
|
255
|
+
applyMask(event) {
|
|
256
|
+
const mask = this.timepicker.useLocale ? 'Hh:m0 AM' : 'Hh:m0';
|
|
257
|
+
let value = this.ngxMaskPipe.transform(this.nativeElementValue, mask, this.maskConfig);
|
|
258
|
+
if (this.timepicker.useLocale) {
|
|
259
|
+
value = processInputValue(value, event);
|
|
260
|
+
}
|
|
261
|
+
this.nativeElementValue = value;
|
|
262
|
+
return value;
|
|
263
|
+
}
|
|
264
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TimepickerInputControlDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
|
|
265
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: TimepickerInputControlDirective, isStandalone: true, selector: "input[odxTimepickerControl]", host: { properties: { "attr.readonly": "isReadonly || null", "attr.placeholder": "placeholder" } }, providers: [provideNgxMask(), NgxMaskPipe], usesInheritance: true, hostDirectives: [{ directive: i1.WithTabIndex }], ngImport: i0 }); }
|
|
266
|
+
};
|
|
267
|
+
TimepickerInputControlDirective = __decorate([
|
|
268
|
+
CSSComponent('timepicker__control')
|
|
269
|
+
], TimepickerInputControlDirective);
|
|
270
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TimepickerInputControlDirective, decorators: [{
|
|
271
|
+
type: Directive,
|
|
272
|
+
args: [{
|
|
273
|
+
standalone: true,
|
|
274
|
+
selector: 'input[odxTimepickerControl]',
|
|
275
|
+
host: {
|
|
276
|
+
'[attr.readonly]': 'isReadonly || null',
|
|
277
|
+
'[attr.placeholder]': 'placeholder',
|
|
278
|
+
},
|
|
279
|
+
providers: [provideNgxMask(), NgxMaskPipe],
|
|
280
|
+
hostDirectives: [WithTabIndex],
|
|
281
|
+
}]
|
|
282
|
+
}] });
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Generates an array of time stamps within a 24-hour period based on the specified step interval.
|
|
286
|
+
* The time stamps can be formatted in 24-hour format or 12-hour format with AM/PM based on locale preference.
|
|
287
|
+
*
|
|
288
|
+
* @param {number} step - The interval, in minutes, between each time stamp.
|
|
289
|
+
* @param {boolean} useLocale - Determines if the time stamps should use the 12-hour format with AM/PM (`true`) or the 24-hour format (`false`).
|
|
290
|
+
* @returns {string[]} An array of formatted time stamps as strings.
|
|
291
|
+
* @example
|
|
292
|
+
* // Generate time stamps every 30 minutes using 24-hour format
|
|
293
|
+
* generateTimeStamps(30, false);
|
|
294
|
+
* // Returns ["00:00", "00:30", "01:00", ..., "23:30"]
|
|
295
|
+
*
|
|
296
|
+
* @example
|
|
297
|
+
* // Generate time stamps every 60 minutes using 12-hour format with AM/PM
|
|
298
|
+
* generateTimeStamps(60, true);
|
|
299
|
+
* // Returns ["12:00 AM", "01:00 AM", ..., "11:00 PM"]
|
|
300
|
+
*/
|
|
301
|
+
function generateTimeStamps(step, useLocale) {
|
|
302
|
+
const roundedStep = Math.round(step);
|
|
303
|
+
return Array.from({ length: Math.ceil(24 * (60 / roundedStep)) }, (_, i) => {
|
|
304
|
+
const hours = Math.floor((i * roundedStep) / 60);
|
|
305
|
+
const minutes = (i * roundedStep) % 60;
|
|
306
|
+
return formatTime(hours, minutes, useLocale);
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Formats a given time as a string based on the specified hour, minute, and locale preference.
|
|
311
|
+
* Can format time in either 24-hour format or 12-hour format with AM/PM.
|
|
312
|
+
*
|
|
313
|
+
* @param {number} hours - The hour component of the time.
|
|
314
|
+
* @param {number} minutes - The minute component of the time.
|
|
315
|
+
* @param {boolean} useLocale - Determines if the time should be formatted using the 12-hour format with AM/PM (`true`) or the 24-hour format (`false`).
|
|
316
|
+
* @returns {string} The formatted time as a string.
|
|
317
|
+
* @example
|
|
318
|
+
* // Format time using 24-hour format
|
|
319
|
+
* formatTime(14, 30, false); // "14:30"
|
|
320
|
+
*
|
|
321
|
+
* @example
|
|
322
|
+
* // Format time using 12-hour format with AM/PM
|
|
323
|
+
* formatTime(14, 30, true); // "2:30 PM"
|
|
324
|
+
*/
|
|
325
|
+
function formatTime(hours, minutes, useLocale) {
|
|
326
|
+
if (useLocale) {
|
|
327
|
+
const period = hours >= 12 ? 'PM' : 'AM';
|
|
328
|
+
const displayHours = hours % 12 === 0 ? 12 : hours % 12;
|
|
329
|
+
return `${displayHours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')} ${period}`;
|
|
330
|
+
}
|
|
331
|
+
else {
|
|
332
|
+
return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
var TimepickerComponent_1;
|
|
337
|
+
/**
|
|
338
|
+
* Represents a time picker component allowing users to select a time from a dropdown list.
|
|
339
|
+
* This component integrates with Angular forms and supports customization for locale, time range, and step intervals.
|
|
340
|
+
*
|
|
341
|
+
* @extends {CustomFormControl<string | null>}
|
|
342
|
+
*/
|
|
343
|
+
let TimepickerComponent = class TimepickerComponent extends CustomFormControl {
|
|
344
|
+
static { TimepickerComponent_1 = this; }
|
|
345
|
+
/**
|
|
346
|
+
* Controls whether the timepicker should use locale-specific time formats AM/PM.
|
|
347
|
+
* @default false
|
|
348
|
+
*/
|
|
349
|
+
set useLocale(val) {
|
|
350
|
+
if (this.value && this.dateField) {
|
|
351
|
+
const time = this.timepickerService.getLocalizedTimeFormat(this.value, val);
|
|
352
|
+
this.updateValue(time);
|
|
353
|
+
this.dateField.nativeElementValue = time;
|
|
354
|
+
}
|
|
355
|
+
this._useLocale = val;
|
|
356
|
+
}
|
|
357
|
+
get useLocale() {
|
|
358
|
+
return this._useLocale;
|
|
359
|
+
}
|
|
360
|
+
constructor() {
|
|
361
|
+
super(null);
|
|
362
|
+
this.timepickerService = inject(TimepickerService);
|
|
363
|
+
this._useLocale = false;
|
|
364
|
+
this.takeUntilDestroyed = untilDestroyed();
|
|
365
|
+
this.trackByIndex = trackByIndex;
|
|
366
|
+
this.element = injectElement();
|
|
367
|
+
/**
|
|
368
|
+
* Controls the step interval between time options in minutes.
|
|
369
|
+
* @default 30
|
|
370
|
+
*/
|
|
371
|
+
this.step = 30;
|
|
372
|
+
/**
|
|
373
|
+
* Specifies the minimum time value that can be selected ('05:00' or '05:00 AM').
|
|
374
|
+
* @default '00:00'
|
|
375
|
+
*/
|
|
376
|
+
this.min = '00:00';
|
|
377
|
+
/**
|
|
378
|
+
* Specifies the maximum time value that can be selected ('22:00' or '10:00 PM').
|
|
379
|
+
* @default '23:59'
|
|
380
|
+
*/
|
|
381
|
+
this.max = '23:59';
|
|
382
|
+
}
|
|
383
|
+
ngAfterViewInit() {
|
|
384
|
+
this.handleDateFieldChanges();
|
|
385
|
+
this.updateInputValue();
|
|
386
|
+
}
|
|
387
|
+
onOpen() {
|
|
388
|
+
this.keyManager = new ActiveDescendantKeyManager(this.options).withHomeAndEnd();
|
|
389
|
+
this.setActiveOptionBasedOnCurrentValue();
|
|
390
|
+
}
|
|
391
|
+
isTimeOptionSelected(option) {
|
|
392
|
+
return this.value === option.value;
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Handles the selection of a time option from the dropdown, updating the input field and closing the dropdown.
|
|
396
|
+
*
|
|
397
|
+
* @param {TimepickerOptionComponent} option - The selected time option component.
|
|
398
|
+
*/
|
|
399
|
+
timeSelected(option) {
|
|
400
|
+
if (!option || option.disabled)
|
|
401
|
+
return;
|
|
402
|
+
const time = this.timepickerService.getLocalizedTimeFormat(option.getLabel(), this.useLocale);
|
|
403
|
+
this.dateField && (this.dateField.nativeElementValue = time);
|
|
404
|
+
this.updateValue(time);
|
|
405
|
+
this.dropdown?.close();
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Determines whether the specified time is within the allowed time range.
|
|
409
|
+
*
|
|
410
|
+
* @param {string} time - The time to check, in 'HH:mm' or 'HH:mm AM/PM' format.
|
|
411
|
+
* @returns {boolean} True if the time is within the range; otherwise, false.
|
|
412
|
+
*/
|
|
413
|
+
inTimeRange(time) {
|
|
414
|
+
return this.timepickerService.maxValidation(time, this.max) && this.timepickerService.minValidation(time, this.min);
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Generates the list of time options based on the configured step interval and locale settings AM/PM.
|
|
418
|
+
*
|
|
419
|
+
* @returns {string[]} An array of time strings in 'HH:mm' format.
|
|
420
|
+
*/
|
|
421
|
+
get timeStampsList() {
|
|
422
|
+
return generateTimeStamps(this.step, this.useLocale);
|
|
423
|
+
}
|
|
424
|
+
handleControllerEvent(event) {
|
|
425
|
+
if (this.readonlyController?.readonly)
|
|
426
|
+
return;
|
|
427
|
+
this.keyManager?.onKeydown(event);
|
|
428
|
+
const activeOption = this.keyManager?.activeItem;
|
|
429
|
+
activeOption && this.scrollToActiveOption(activeOption, { behavior: 'smooth' });
|
|
430
|
+
if (event.key === 'Enter' || event.key === ' ' || event.key === 'Spacebar') {
|
|
431
|
+
event.preventDefault();
|
|
432
|
+
event.stopImmediatePropagation();
|
|
433
|
+
this.timeSelected(activeOption);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
handleDateFieldChanges() {
|
|
437
|
+
this.dateField?.valueChange$.pipe(this.takeUntilDestroyed()).subscribe((time) => this.updateValue(time ?? null));
|
|
438
|
+
}
|
|
439
|
+
setActiveOptionBasedOnCurrentValue() {
|
|
440
|
+
const isSelected = this.options.find((option) => option.isSelected);
|
|
441
|
+
if (isSelected) {
|
|
442
|
+
this.activateOption(isSelected);
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
this.activateNearestTimeOption();
|
|
446
|
+
}
|
|
447
|
+
activateOption(option) {
|
|
448
|
+
this.keyManager && this.keyManager.setActiveItem(option);
|
|
449
|
+
this.scrollToActiveOption(option);
|
|
450
|
+
}
|
|
451
|
+
activateNearestTimeOption() {
|
|
452
|
+
if (!this.value) {
|
|
453
|
+
const currentDate = new Date();
|
|
454
|
+
const isNearest = this.findNearestTimeOption(currentDate);
|
|
455
|
+
if (isNearest) {
|
|
456
|
+
this.activateOption(isNearest);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
findNearestTimeOption(currentDate) {
|
|
461
|
+
const availableTimeSlots = this.options.filter((option) => !option.disabled);
|
|
462
|
+
const nearestTimeValue = this.timepickerService.findClosestDate(availableTimeSlots.map((option) => option.value), `${currentDate.getHours()}:${currentDate.getMinutes()}`);
|
|
463
|
+
return availableTimeSlots.find((option) => option.value === nearestTimeValue);
|
|
464
|
+
}
|
|
465
|
+
updateInputValue() {
|
|
466
|
+
if (this.value && this.dateField) {
|
|
467
|
+
const time = this.timepickerService.getLocalizedTimeFormat(this.value, this.useLocale);
|
|
468
|
+
this.dateField.nativeElementValue = time;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
scrollToActiveOption(option, _opts = {}) {
|
|
472
|
+
if (isFunction(option.element.nativeElement.scrollIntoView)) {
|
|
473
|
+
option.element.nativeElement.scrollIntoView({ block: 'center', ..._opts });
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TimepickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
477
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "16.2.12", type: TimepickerComponent, isStandalone: true, selector: "odx-timepicker", inputs: { useLocale: ["useLocale", "useLocale", booleanAttribute], step: ["step", "step", numberAttribute], min: "min", max: "max" }, host: { listeners: { "click": "handleControllerEvent($event)", "keydown": "handleControllerEvent($event)" }, properties: { "attr.readonly": "readonlyController?.readonly || null" } }, providers: [
|
|
478
|
+
DisabledController.connect(),
|
|
479
|
+
ReadonlyController.connect(),
|
|
480
|
+
{
|
|
481
|
+
provide: TIMEPICKER_CONTROL,
|
|
482
|
+
useExisting: forwardRef(() => TimepickerComponent_1),
|
|
483
|
+
},
|
|
484
|
+
], viewQueries: [{ propertyName: "dropdown", first: true, predicate: DropdownDirective, descendants: true }, { propertyName: "dateField", first: true, predicate: TimepickerInputControlDirective, descendants: true }, { propertyName: "options", predicate: TimepickerOptionComponent, descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"odx-timepicker__wrapper\">\n <input [value]=\"value\" odxTimepickerControl type=\"text\" />\n</div>\n\n<odx-action-group class=\"odx-no-margin\">\n <button\n #dropdownTrigger\n class=\"odx-timepicker__trigger\"\n odxButton\n size=\"small\"\n variant=\"ghost\"\n aria-label=\"Select time\"\n [odxDropdown]=\"timeList\"\n [odxDropdownOptions]=\"{ matchReferenceWidth: true, position: 'bottom-start', enableFallback: false }\"\n [odxDropdownTriggerElement]=\"dropdownTrigger.element.nativeElement\"\n [odxDropdownReferenceElement]=\"element.nativeElement\"\n (odxDropdownBeforeClose)=\"onTouched()\"\n (odxDropdownAfterOpen)=\"onOpen()\"\n >\n <odx-icon name=\"chevron-down\"></odx-icon>\n </button>\n</odx-action-group>\n\n<ng-template #timeList>\n <div class=\"odx-timepicker__option-list\" role=\"listbox\">\n <odx-timepicker-option\n [value]=\"time\"\n [disabled]=\"!inTimeRange(time)\"\n *ngFor=\"let time of timeStampsList; trackBy: trackByIndex\"\n (selected)=\"timeSelected($event)\"\n >{{ time }}</odx-timepicker-option\n >\n </div>\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: A11yModule }, { kind: "component", type: ActionGroupComponent, selector: "odx-action-group", inputs: ["reverse"] }, { kind: "component", type: ButtonComponent, selector: "button[odxButton], a[odxButton]", inputs: ["variant", "size"] }, { kind: "ngmodule", type: DropdownModule }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.DisabledController, selector: "[disabled]", inputs: ["disabled"] }, { kind: "directive", type: i3.DropdownDirective, selector: "[odxDropdown]", inputs: ["odxDropdown", "odxDropdownDisabled", "odxDropdownShowLoader", "odxDropdownClickOutsideActive", "odxDropdownOptions", "odxDropdownReferenceElement", "odxDropdownTriggerElement", "odxDropdownHost", "odxDropdownOpenTrigger", "odxDropdownCloseTrigger"], outputs: ["odxDropdownBeforeOpen", "odxDropdownAfterOpen", "odxDropdownBeforeClose", "odxDropdownAfterClose"], exportAs: ["odxDropdown"] }, { kind: "component", type: TimepickerOptionComponent, selector: "odx-timepicker-option", outputs: ["selected"] }, { kind: "component", type: IconComponent, selector: "odx-icon", inputs: ["inline", "size", "name", "iconSet", "identifier"] }, { kind: "directive", type: TimepickerInputControlDirective, selector: "input[odxTimepickerControl]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
485
|
+
};
|
|
486
|
+
TimepickerComponent = TimepickerComponent_1 = __decorate([
|
|
487
|
+
CSSComponent('timepicker'),
|
|
488
|
+
__metadata("design:paramtypes", [])
|
|
489
|
+
], TimepickerComponent);
|
|
490
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TimepickerComponent, decorators: [{
|
|
491
|
+
type: Component,
|
|
492
|
+
args: [{ standalone: true, selector: 'odx-timepicker', providers: [
|
|
493
|
+
DisabledController.connect(),
|
|
494
|
+
ReadonlyController.connect(),
|
|
495
|
+
{
|
|
496
|
+
provide: TIMEPICKER_CONTROL,
|
|
497
|
+
useExisting: forwardRef(() => TimepickerComponent),
|
|
498
|
+
},
|
|
499
|
+
], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [A11yModule, ActionGroupComponent, ButtonComponent, DropdownModule, TimepickerOptionComponent, IconComponent, TimepickerInputControlDirective], host: {
|
|
500
|
+
'[attr.readonly]': 'readonlyController?.readonly || null',
|
|
501
|
+
}, template: "<div class=\"odx-timepicker__wrapper\">\n <input [value]=\"value\" odxTimepickerControl type=\"text\" />\n</div>\n\n<odx-action-group class=\"odx-no-margin\">\n <button\n #dropdownTrigger\n class=\"odx-timepicker__trigger\"\n odxButton\n size=\"small\"\n variant=\"ghost\"\n aria-label=\"Select time\"\n [odxDropdown]=\"timeList\"\n [odxDropdownOptions]=\"{ matchReferenceWidth: true, position: 'bottom-start', enableFallback: false }\"\n [odxDropdownTriggerElement]=\"dropdownTrigger.element.nativeElement\"\n [odxDropdownReferenceElement]=\"element.nativeElement\"\n (odxDropdownBeforeClose)=\"onTouched()\"\n (odxDropdownAfterOpen)=\"onOpen()\"\n >\n <odx-icon name=\"chevron-down\"></odx-icon>\n </button>\n</odx-action-group>\n\n<ng-template #timeList>\n <div class=\"odx-timepicker__option-list\" role=\"listbox\">\n <odx-timepicker-option\n [value]=\"time\"\n [disabled]=\"!inTimeRange(time)\"\n *ngFor=\"let time of timeStampsList; trackBy: trackByIndex\"\n (selected)=\"timeSelected($event)\"\n >{{ time }}</odx-timepicker-option\n >\n </div>\n</ng-template>\n" }]
|
|
502
|
+
}], ctorParameters: function () { return []; }, propDecorators: { dropdown: [{
|
|
503
|
+
type: ViewChild,
|
|
504
|
+
args: [DropdownDirective]
|
|
505
|
+
}], options: [{
|
|
506
|
+
type: ViewChildren,
|
|
507
|
+
args: [TimepickerOptionComponent, { emitDistinctChangesOnly: true }]
|
|
508
|
+
}], useLocale: [{
|
|
509
|
+
type: Input,
|
|
510
|
+
args: [{ transform: booleanAttribute }]
|
|
511
|
+
}], step: [{
|
|
512
|
+
type: Input,
|
|
513
|
+
args: [{ transform: numberAttribute }]
|
|
514
|
+
}], min: [{
|
|
515
|
+
type: Input
|
|
516
|
+
}], max: [{
|
|
517
|
+
type: Input
|
|
518
|
+
}], dateField: [{
|
|
519
|
+
type: ViewChild,
|
|
520
|
+
args: [TimepickerInputControlDirective]
|
|
521
|
+
}], handleControllerEvent: [{
|
|
522
|
+
type: HostListener,
|
|
523
|
+
args: ['click', ['$event']]
|
|
524
|
+
}, {
|
|
525
|
+
type: HostListener,
|
|
526
|
+
args: ['keydown', ['$event']]
|
|
527
|
+
}] } });
|
|
528
|
+
|
|
529
|
+
const modules = [TimepickerComponent, TimepickerInputControlDirective, TimepickerOptionComponent];
|
|
530
|
+
class TimepickerModule {
|
|
531
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TimepickerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
532
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: TimepickerModule, imports: [TimepickerComponent, TimepickerInputControlDirective, TimepickerOptionComponent], exports: [CoreModule, TimepickerComponent, TimepickerInputControlDirective, TimepickerOptionComponent] }); }
|
|
533
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TimepickerModule, imports: [TimepickerComponent, CoreModule] }); }
|
|
534
|
+
}
|
|
535
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TimepickerModule, decorators: [{
|
|
536
|
+
type: NgModule,
|
|
537
|
+
args: [{
|
|
538
|
+
imports: modules,
|
|
539
|
+
exports: [CoreModule, ...modules],
|
|
540
|
+
}]
|
|
541
|
+
}] });
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* Generated bundle index. Do not edit.
|
|
545
|
+
*/
|
|
546
|
+
|
|
547
|
+
export { TIMEPICKER_CONTROL, TimepickerComponent, TimepickerInputControlDirective, TimepickerModule, TimepickerOptionComponent, TimepickerService, generateTimeStamps, processInputValue };
|
|
548
|
+
//# sourceMappingURL=odx-angular-components-timepicker.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"odx-angular-components-timepicker.mjs","sources":["../../../../libs/angular/components/timepicker/src/lib/timepicker.token.ts","../../../../libs/angular/components/timepicker/src/lib/components/timepicker-option.component.ts","../../../../libs/angular/components/timepicker/src/lib/timepicker.service.ts","../../../../libs/angular/components/timepicker/src/lib/utils/ngx-mask-helper.ts","../../../../libs/angular/components/timepicker/src/lib/directives/timepicker-input-control.directive.ts","../../../../libs/angular/components/timepicker/src/lib/utils/generate-time-stamps.ts","../../../../libs/angular/components/timepicker/src/lib/timepicker.component.ts","../../../../libs/angular/components/timepicker/src/lib/timepicker.component.html","../../../../libs/angular/components/timepicker/src/lib/timepicker.module.ts","../../../../libs/angular/components/timepicker/src/odx-angular-components-timepicker.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport { TimepickerComponent } from './timepicker.component';\n\n/**\n * An InjectionToken used for injecting an instance of TimepickerComponent.\n * This token facilitates the decoupling of the TimepickerComponent's implementation from its consumption,\n * allowing for more flexible and maintainable code, especially in scenarios requiring custom time picker\n * behavior or appearance.\n */\nexport const TIMEPICKER_CONTROL = new InjectionToken<TimepickerComponent>('@odx/angular/components/timepicker::TimepickerComponent');\n","import { ChangeDetectionStrategy, Component, EventEmitter, OnInit, Output, ViewEncapsulation, inject } from '@angular/core';\nimport { DisabledController, WithDisabledState, detectControllerChanges } from '@odx/angular';\nimport { OptionControl } from '@odx/angular/cdk/option-control';\nimport { CSSComponent } from '@odx/angular/internal';\nimport { TIMEPICKER_CONTROL } from '../timepicker.token';\n\n/**\n * Represents a selectable option within a timepicker component. This component allows for\n * individual time values to be selected from a dropdown menu as part of the timepicker interface.\n * It integrates with the timepicker's control to manage selection state and accessibility.\n *\n * @extends {OptionControl<string>}\n */\n@CSSComponent('timepicker-option')\n@Component({\n selector: 'odx-timepicker-option',\n template: `<ng-content></ng-content>`,\n standalone: true,\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [DisabledController.connect()],\n hostDirectives: [WithDisabledState],\n})\nexport class TimepickerOptionComponent extends OptionControl<string> implements OnInit {\n private readonly timepicker = inject(TIMEPICKER_CONTROL);\n protected readonly disabledController = DisabledController.inject();\n\n public isSelected = false;\n public override isActive = false;\n\n public get disabled(): boolean {\n return !!this.disabledController?.disabled;\n }\n\n /**\n * Emits an event when the option is selected, allowing the timepicker component to update its value and close the dropdown.\n */\n @Output()\n public selected = new EventEmitter<TimepickerOptionComponent>();\n\n constructor() {\n super();\n detectControllerChanges(this.timepicker).pipe(this.takeUntilDestroyed()).subscribe();\n }\n\n public ngOnInit(): void {\n this.isSelected = this.timepicker.isTimeOptionSelected(this);\n }\n\n protected selectOption(): void {\n this.selected.emit(this);\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport { WindowRef } from '@odx/angular';\nimport { isAfter, isBefore, isEqual } from 'date-fns';\n\n/**\n * Service to provide utility functions for timepicker components, including validation, placeholder generation, and finding the closest time.\n * It also handles locale-based time formatting.\n */\n@Injectable({ providedIn: 'root' })\nexport class TimepickerService {\n private readonly windowRef = inject(WindowRef);\n\n /**\n * Generates a placeholder string for time input fields.\n *\n * @param {boolean} apm - Specifies if the placeholder should include AM/PM notation.\n * @returns {string} The placeholder string.\n */\n public getPlaceholder(apm = false): string {\n return apm ? '--:-- --' : '--:--';\n }\n\n /**\n * Validates if the given time is less than or equal to a maximum time constraint.\n *\n * @param {string} time - The time to validate.\n * @param {string} max - The maximum allowable time.\n * @returns {boolean} True if the time is valid, false otherwise.\n */\n public maxValidation(time: string, max: string): boolean {\n const [targetValue, maxValue] = this.convertToDates([time, max]);\n return isBefore(targetValue, maxValue) || isEqual(targetValue, maxValue);\n }\n\n /**\n * Validates if the given time is greater than or equal to a minimum time constraint.\n *\n * @param {string} time - The time to validate.\n * @param {string} min - The minimum allowable time.\n * @returns {boolean} True if the time is valid, false otherwise.\n */\n public minValidation(time: string, min: string): boolean {\n const [targetValue, minValue] = this.convertToDates([time, min]);\n return isAfter(targetValue, minValue) || isEqual(targetValue, minValue);\n }\n\n /**\n * Finds the closest time to a target time from a list of times.\n *\n * @param {string[]} timeStamps - The list of times to search through.\n * @param {string} targetTime - The target time to find the closest match for.\n * @returns {string} The closest time to the target.\n */\n public findClosestDate(timeStamps: string[], targetTime: string): string {\n const [target] = this.convertToDates([targetTime]);\n const datesArray = this.convertToDates(timeStamps);\n\n const closestDate = datesArray.reduce((prev, curr) => {\n return Math.abs(curr.getTime() - target.getTime()) < Math.abs(prev.getTime() - target.getTime()) ? curr : prev;\n });\n\n return this.getLocalizedTimeFormat(`${closestDate.getHours()}:${closestDate.getMinutes()}`);\n }\n\n /**\n * Formats a time string to a localized time format.\n *\n * @param {string} time - The time string to format.\n * @param {boolean} hour12 - Specifies if the output should use 12-hour format with AM/PM notation.\n * @returns {string} The formatted time string.\n */\n public getLocalizedTimeFormat(time: string, hour12 = false): string {\n const locale = hour12 ? 'en-US' : 'en-GB';\n const [date] = this.convertToDates([time]);\n return new this.windowRef.nativeWindow.Intl.DateTimeFormat(locale, {\n hour: '2-digit',\n minute: '2-digit',\n hour12,\n }).format(date);\n }\n\n /**\n * Converts an array of time strings to an array of Date objects.\n *\n * @param {string[]} times - The time strings to convert.\n * @returns {Date[]} An array of Date objects corresponding to the input times.\n * @private\n */\n private convertToDates(times: string[]): Date[] {\n return times.map((time) => new Date(`${time} 2022-12-19`));\n }\n}\n","/**\n * Processes and formats a time input value based on specific rules. It adjusts the input for valid time format,\n * especially focusing on single-digit hour inputs, ensuring minute values start with 0 if the last digit is greater\n * than 5, and appending 'M' to AM/PM indicators.\n *\n * @param {string} value - The current input value of the time field.\n * @param {InputEvent} event - The input event triggered by the user's interaction with the field.\n * @returns {string} The processed and potentially reformatted value.\n *\n * @example\n * // Prepend 0 to single-digit hours greater than 1\n * processInputValue(\"2\", { inputType: \"insertText\" }); // Returns \"02\"\n *\n * @example\n * // Ensure minute values are within valid ranges\n * processInputValue(\"11:8\", { inputType: \"insertText\" }); // Returns \"11:08\"\n *\n * @example\n * // Append 'M' to AM/PM indicators\n * processInputValue(\"2 p\", { inputType: \"insertText\" }); // Returns \"2 PM\"\n */\nexport function processInputValue(value: string, event: InputEvent): string {\n if (value.length === 1 && Number(value) > 1) {\n value = `0${value}`;\n } else if (value.length === 4 && Number(value.at(-1)) > 5) {\n value = `${value.slice(0, -1)}0${value.slice(-1)}`;\n }\n\n if (/[AaPp]/.test(value) && event.inputType === 'insertText') {\n value = `${value.toUpperCase()}M`;\n }\n\n return value;\n}\n","import { Directive, inject } from '@angular/core';\nimport { WithTabIndex } from '@odx/angular';\nimport { InputControlDirective } from '@odx/angular/cdk/custom-form-control';\nimport { CSSComponent } from '@odx/angular/internal';\nimport { IConfig, NgxMaskPipe, provideNgxMask } from 'ngx-mask';\nimport { distinctUntilChanged, fromEvent, map } from 'rxjs';\nimport { TimepickerService } from '../timepicker.service';\nimport { TIMEPICKER_CONTROL } from '../timepicker.token';\nimport { processInputValue } from '../utils/ngx-mask-helper';\n\n/**\n * Directive to enhance a standard input element for time picking, integrating mask functionality for time format.\n * It automatically adapts to locale settings provided by the enclosing `TimepickerComponent` to display time in the appropriate format.\n *\n * @extends {InputControlDirective}\n */\n@CSSComponent('timepicker__control')\n@Directive({\n standalone: true,\n selector: 'input[odxTimepickerControl]',\n host: {\n '[attr.readonly]': 'isReadonly || null',\n '[attr.placeholder]': 'placeholder',\n },\n providers: [provideNgxMask(), NgxMaskPipe],\n hostDirectives: [WithTabIndex],\n})\nexport class TimepickerInputControlDirective extends InputControlDirective {\n private readonly timepicker = inject(TIMEPICKER_CONTROL);\n private readonly timepickerService = inject(TimepickerService);\n protected readonly ngxMaskPipe = inject(NgxMaskPipe);\n\n /**\n * Configuration for the mask applied to the timepicker input. Adjusts based on locale settings.\n */\n protected get maskConfig(): Partial<IConfig> {\n return {\n validation: false,\n apm: this.timepicker.useLocale,\n leadZeroDateTime: !this.timepicker.useLocale,\n\n patterns: {\n A: { pattern: new RegExp('[AaPp]') },\n M: { pattern: new RegExp('M') },\n },\n };\n }\n\n /**\n * Stream of value changes for the input element, applying the mask and processing the input based on locale.\n */\n public override valueChange$ = fromEvent(this.element.nativeElement, 'input').pipe(\n distinctUntilChanged(),\n map((event) => this.applyMask(event)),\n );\n\n /**\n * Computes and returns the placeholder text for the input based on locale settings.\n *\n * @returns {string} The placeholder text for the input.\n */\n public get placeholder(): string {\n return this.timepickerService.getPlaceholder(this.timepicker.useLocale);\n }\n\n /**\n * Determines whether the timepicker input is readonly, based on the state of the parent timepicker component.\n *\n * @returns {boolean} `true` if the input should be readonly; otherwise, `false`.\n */\n protected get isReadonly(): boolean {\n return this.timepicker.isReadonly;\n }\n\n /**\n * Applies the time format mask to the input value, transforming and returning the masked value.\n *\n * @param {Event} event - The input event triggering the mask application.\n * @returns {string} The masked input value.\n */\n private applyMask(event: Event): string {\n const mask = this.timepicker.useLocale ? 'Hh:m0 AM' : 'Hh:m0';\n let value = this.ngxMaskPipe.transform(this.nativeElementValue, mask, this.maskConfig);\n if (this.timepicker.useLocale) {\n value = processInputValue(value, event as InputEvent);\n }\n this.nativeElementValue = value;\n return value;\n }\n}\n","/**\n * Generates an array of time stamps within a 24-hour period based on the specified step interval.\n * The time stamps can be formatted in 24-hour format or 12-hour format with AM/PM based on locale preference.\n *\n * @param {number} step - The interval, in minutes, between each time stamp.\n * @param {boolean} useLocale - Determines if the time stamps should use the 12-hour format with AM/PM (`true`) or the 24-hour format (`false`).\n * @returns {string[]} An array of formatted time stamps as strings.\n * @example\n * // Generate time stamps every 30 minutes using 24-hour format\n * generateTimeStamps(30, false);\n * // Returns [\"00:00\", \"00:30\", \"01:00\", ..., \"23:30\"]\n *\n * @example\n * // Generate time stamps every 60 minutes using 12-hour format with AM/PM\n * generateTimeStamps(60, true);\n * // Returns [\"12:00 AM\", \"01:00 AM\", ..., \"11:00 PM\"]\n */\nexport function generateTimeStamps(step: number, useLocale: boolean): string[] {\n const roundedStep = Math.round(step);\n\n return Array.from({ length: Math.ceil(24 * (60 / roundedStep)) }, (_, i) => {\n const hours = Math.floor((i * roundedStep) / 60);\n const minutes = (i * roundedStep) % 60;\n return formatTime(hours, minutes, useLocale);\n });\n}\n\n/**\n * Formats a given time as a string based on the specified hour, minute, and locale preference.\n * Can format time in either 24-hour format or 12-hour format with AM/PM.\n *\n * @param {number} hours - The hour component of the time.\n * @param {number} minutes - The minute component of the time.\n * @param {boolean} useLocale - Determines if the time should be formatted using the 12-hour format with AM/PM (`true`) or the 24-hour format (`false`).\n * @returns {string} The formatted time as a string.\n * @example\n * // Format time using 24-hour format\n * formatTime(14, 30, false); // \"14:30\"\n *\n * @example\n * // Format time using 12-hour format with AM/PM\n * formatTime(14, 30, true); // \"2:30 PM\"\n */\nfunction formatTime(hours: number, minutes: number, useLocale: boolean): string {\n if (useLocale) {\n const period = hours >= 12 ? 'PM' : 'AM';\n const displayHours = hours % 12 === 0 ? 12 : hours % 12;\n return `${displayHours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')} ${period}`;\n } else {\n return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;\n }\n}\n","import { A11yModule, ActiveDescendantKeyManager } from '@angular/cdk/a11y';\nimport {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n HostListener,\n Input,\n QueryList,\n ViewChild,\n ViewChildren,\n ViewEncapsulation,\n booleanAttribute,\n forwardRef,\n inject,\n numberAttribute,\n} from '@angular/core';\nimport { DisabledController, ReadonlyController } from '@odx/angular';\nimport { CustomFormControl } from '@odx/angular/cdk/custom-form-control';\nimport { OptionControl } from '@odx/angular/cdk/option-control';\nimport { ActionGroupComponent } from '@odx/angular/components/action-group';\nimport { ButtonComponent } from '@odx/angular/components/button';\nimport { DropdownDirective, DropdownModule } from '@odx/angular/components/dropdown';\nimport { IconComponent } from '@odx/angular/components/icon';\nimport { CSSComponent } from '@odx/angular/internal';\nimport { injectElement, isFunction, trackByIndex, untilDestroyed } from '@odx/angular/utils';\nimport { TimepickerOptionComponent } from './components/timepicker-option.component';\nimport { TimepickerInputControlDirective } from './directives/timepicker-input-control.directive';\nimport { TimepickerService } from './timepicker.service';\nimport { TIMEPICKER_CONTROL } from './timepicker.token';\nimport { generateTimeStamps } from './utils/generate-time-stamps';\n\n/**\n * Represents a time picker component allowing users to select a time from a dropdown list.\n * This component integrates with Angular forms and supports customization for locale, time range, and step intervals.\n *\n * @extends {CustomFormControl<string | null>}\n */\n@CSSComponent('timepicker')\n@Component({\n standalone: true,\n selector: 'odx-timepicker',\n templateUrl: 'timepicker.component.html',\n providers: [\n DisabledController.connect(),\n ReadonlyController.connect(),\n {\n provide: TIMEPICKER_CONTROL,\n useExisting: forwardRef(() => TimepickerComponent),\n },\n ],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [A11yModule, ActionGroupComponent, ButtonComponent, DropdownModule, TimepickerOptionComponent, IconComponent, TimepickerInputControlDirective],\n host: {\n '[attr.readonly]': 'readonlyController?.readonly || null',\n },\n})\nexport class TimepickerComponent extends CustomFormControl<string | null> implements AfterViewInit {\n private readonly timepickerService = inject(TimepickerService);\n private _useLocale = false;\n protected keyManager?: ActiveDescendantKeyManager<OptionControl<string>>;\n\n protected readonly takeUntilDestroyed = untilDestroyed();\n protected readonly trackByIndex = trackByIndex;\n\n @ViewChild(DropdownDirective)\n protected readonly dropdown?: DropdownDirective;\n\n @ViewChildren(TimepickerOptionComponent, { emitDistinctChangesOnly: true })\n protected options!: QueryList<TimepickerOptionComponent>;\n\n public readonly element = injectElement();\n\n /**\n * Controls whether the timepicker should use locale-specific time formats AM/PM.\n * @default false\n */\n @Input({ transform: booleanAttribute })\n public set useLocale(val: boolean) {\n if (this.value && this.dateField) {\n const time = this.timepickerService.getLocalizedTimeFormat(this.value, val);\n this.updateValue(time);\n this.dateField.nativeElementValue = time;\n }\n this._useLocale = val;\n }\n\n public get useLocale(): boolean {\n return this._useLocale;\n }\n\n /**\n * Controls the step interval between time options in minutes.\n * @default 30\n */\n @Input({ transform: numberAttribute })\n public step = 30;\n\n /**\n * Specifies the minimum time value that can be selected ('05:00' or '05:00 AM').\n * @default '00:00'\n */\n @Input()\n public min = '00:00';\n\n /**\n * Specifies the maximum time value that can be selected ('22:00' or '10:00 PM').\n * @default '23:59'\n */\n @Input()\n public max = '23:59';\n\n @ViewChild(TimepickerInputControlDirective)\n public dateField?: TimepickerInputControlDirective;\n\n constructor() {\n super(null);\n }\n\n public ngAfterViewInit(): void {\n this.handleDateFieldChanges();\n this.updateInputValue();\n }\n\n public onOpen(): void {\n this.keyManager = new ActiveDescendantKeyManager<OptionControl<string>>(this.options).withHomeAndEnd();\n this.setActiveOptionBasedOnCurrentValue();\n }\n\n public isTimeOptionSelected(option: TimepickerOptionComponent): boolean {\n return this.value === option.value;\n }\n\n /**\n * Handles the selection of a time option from the dropdown, updating the input field and closing the dropdown.\n *\n * @param {TimepickerOptionComponent} option - The selected time option component.\n */\n public timeSelected(option?: TimepickerOptionComponent): void {\n if (!option || option.disabled) return;\n const time = this.timepickerService.getLocalizedTimeFormat(option.getLabel(), this.useLocale);\n this.dateField && (this.dateField.nativeElementValue = time);\n this.updateValue(time);\n this.dropdown?.close();\n }\n\n /**\n * Determines whether the specified time is within the allowed time range.\n *\n * @param {string} time - The time to check, in 'HH:mm' or 'HH:mm AM/PM' format.\n * @returns {boolean} True if the time is within the range; otherwise, false.\n */\n public inTimeRange(time: string): boolean {\n return this.timepickerService.maxValidation(time, this.max) && this.timepickerService.minValidation(time, this.min);\n }\n\n /**\n * Generates the list of time options based on the configured step interval and locale settings AM/PM.\n *\n * @returns {string[]} An array of time strings in 'HH:mm' format.\n */\n public get timeStampsList(): string[] {\n return generateTimeStamps(this.step, this.useLocale);\n }\n\n @HostListener('click', ['$event'])\n @HostListener('keydown', ['$event'])\n protected handleControllerEvent(event: KeyboardEvent) {\n if (this.readonlyController?.readonly) return;\n\n this.keyManager?.onKeydown(event);\n const activeOption = this.keyManager?.activeItem as TimepickerOptionComponent;\n activeOption && this.scrollToActiveOption(activeOption, { behavior: 'smooth' });\n\n if (event.key === 'Enter' || event.key === ' ' || event.key === 'Spacebar') {\n event.preventDefault();\n event.stopImmediatePropagation();\n this.timeSelected(activeOption);\n }\n }\n\n protected handleDateFieldChanges(): void {\n this.dateField?.valueChange$.pipe(this.takeUntilDestroyed()).subscribe((time) => this.updateValue(time ?? null));\n }\n\n private setActiveOptionBasedOnCurrentValue(): void {\n const isSelected = this.options.find((option) => option.isSelected);\n if (isSelected) {\n this.activateOption(isSelected);\n return;\n }\n\n this.activateNearestTimeOption();\n }\n\n private activateOption(option: TimepickerOptionComponent): void {\n this.keyManager && this.keyManager.setActiveItem(option);\n this.scrollToActiveOption(option);\n }\n\n private activateNearestTimeOption(): void {\n if (!this.value) {\n const currentDate = new Date();\n const isNearest = this.findNearestTimeOption(currentDate);\n if (isNearest) {\n this.activateOption(isNearest);\n }\n }\n }\n\n private findNearestTimeOption(currentDate: Date): TimepickerOptionComponent | undefined {\n const availableTimeSlots = this.options.filter((option) => !option.disabled);\n const nearestTimeValue = this.timepickerService.findClosestDate(\n availableTimeSlots.map((option) => option.value) as string[],\n `${currentDate.getHours()}:${currentDate.getMinutes()}`,\n );\n\n return availableTimeSlots.find((option) => option.value === nearestTimeValue);\n }\n\n private updateInputValue(): void {\n if (this.value && this.dateField) {\n const time = this.timepickerService.getLocalizedTimeFormat(this.value, this.useLocale);\n this.dateField.nativeElementValue = time;\n }\n }\n\n private scrollToActiveOption(option: TimepickerOptionComponent, _opts: ScrollIntoViewOptions = {}): void {\n if (isFunction(option.element.nativeElement.scrollIntoView)) {\n option.element.nativeElement.scrollIntoView({ block: 'center', ..._opts });\n }\n }\n}\n","<div class=\"odx-timepicker__wrapper\">\n <input [value]=\"value\" odxTimepickerControl type=\"text\" />\n</div>\n\n<odx-action-group class=\"odx-no-margin\">\n <button\n #dropdownTrigger\n class=\"odx-timepicker__trigger\"\n odxButton\n size=\"small\"\n variant=\"ghost\"\n aria-label=\"Select time\"\n [odxDropdown]=\"timeList\"\n [odxDropdownOptions]=\"{ matchReferenceWidth: true, position: 'bottom-start', enableFallback: false }\"\n [odxDropdownTriggerElement]=\"dropdownTrigger.element.nativeElement\"\n [odxDropdownReferenceElement]=\"element.nativeElement\"\n (odxDropdownBeforeClose)=\"onTouched()\"\n (odxDropdownAfterOpen)=\"onOpen()\"\n >\n <odx-icon name=\"chevron-down\"></odx-icon>\n </button>\n</odx-action-group>\n\n<ng-template #timeList>\n <div class=\"odx-timepicker__option-list\" role=\"listbox\">\n <odx-timepicker-option\n [value]=\"time\"\n [disabled]=\"!inTimeRange(time)\"\n *ngFor=\"let time of timeStampsList; trackBy: trackByIndex\"\n (selected)=\"timeSelected($event)\"\n >{{ time }}</odx-timepicker-option\n >\n </div>\n</ng-template>\n","import { NgModule } from '@angular/core';\nimport { CoreModule } from '@odx/angular';\nimport { TimepickerOptionComponent } from './components/timepicker-option.component';\nimport { TimepickerInputControlDirective } from './directives/timepicker-input-control.directive';\nimport { TimepickerComponent } from './timepicker.component';\n\nconst modules = [TimepickerComponent, TimepickerInputControlDirective, TimepickerOptionComponent];\n@NgModule({\n imports: modules,\n exports: [CoreModule, ...modules],\n})\nexport class TimepickerModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1","i2"],"mappings":"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"}
|