@nuralyui/timepicker 0.1.1 → 0.1.3

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.
@@ -1,95 +0,0 @@
1
- import { LitElement, TemplateResult } from 'lit';
2
- import { TimeValue, TimeFormat, TimePickerConfig, TimePickerPlacement } from './timepicker.types.js';
3
- export interface TimePickerHost extends LitElement {
4
- getCurrentTime(): TimeValue;
5
- setTime(time: TimeValue): void;
6
- formatTime(time: TimeValue): string;
7
- parseTime(timeString: string): TimeValue | null;
8
- getConfig(): TimePickerConfig;
9
- requestUpdate(): void;
10
- }
11
- declare const NrTimePickerElement_base: (new (...args: any[]) => import("../../shared/dependency-mixin.js").DependencyAware) & (new (...args: any[]) => import("../../shared/theme-mixin.js").ThemeAware) & (new (...args: any[]) => import("../../shared/event-handler-mixin.js").EventHandlerCapable) & typeof LitElement;
12
- /**
13
- * A comprehensive time picker component that supports both 12-hour and 24-hour formats,
14
- * with optional seconds display and extensive customization options.
15
- *
16
- * @example
17
- * ```html
18
- * <nr-timepicker
19
- * value="14:30:00"
20
- * format="24h"
21
- * show-seconds
22
- * placeholder="Select time">
23
- * </nr-timepicker>
24
- * ```
25
- */
26
- export declare class NrTimePickerElement extends NrTimePickerElement_base implements TimePickerHost {
27
- static styles: import("lit").CSSResult[];
28
- value: string;
29
- name: string;
30
- placeholder: string;
31
- format: TimeFormat;
32
- showSeconds: boolean;
33
- disabled: boolean;
34
- readonly: boolean;
35
- required: boolean;
36
- minTime?: string;
37
- maxTime?: string;
38
- disabledTimes?: string[];
39
- enabledTimes?: string[];
40
- helperText: string;
41
- label: string;
42
- size: 'small' | 'medium' | 'large';
43
- variant: 'outlined' | 'filled' | 'standard';
44
- placement: TimePickerPlacement;
45
- private clockOpen;
46
- private inputValue;
47
- private state;
48
- private validationMessage;
49
- private selectionController;
50
- private validationController;
51
- private formattingController;
52
- constructor();
53
- connectedCallback(): void;
54
- updated(changedProperties: Map<string, any>): void;
55
- render(): TemplateResult;
56
- open(): void;
57
- close(): void;
58
- clear(): void;
59
- setToNow(): void;
60
- validate(): boolean;
61
- private renderLabel;
62
- private renderInput;
63
- private renderDropdown;
64
- private renderColumnPicker;
65
- private renderHourColumn;
66
- private renderMinuteColumn;
67
- private renderSecondColumn;
68
- private renderActions;
69
- private renderHelperText;
70
- private handleInputChange;
71
- private handleInputFocus;
72
- private handleInputBlur;
73
- private handleTriggerClick;
74
- private handleHourSelect;
75
- private handleMinuteSelect;
76
- private handleSecondSelect;
77
- private handleOutsideClick;
78
- private shouldUpdateConstraints;
79
- private updateConstraints;
80
- private setTimeFromValue;
81
- private updateInputValue;
82
- private validateTime;
83
- getCurrentTime(): TimeValue;
84
- setTime(time: TimeValue): void;
85
- formatTime(time: TimeValue): string;
86
- parseTime(timeString: string): TimeValue | null;
87
- getConfig(): TimePickerConfig;
88
- }
89
- declare global {
90
- interface HTMLElementTagNameMap {
91
- 'nr-timepicker': NrTimePickerElement;
92
- }
93
- }
94
- export {};
95
- //# sourceMappingURL=timepicker.component.clean.d.ts.map
@@ -1,471 +0,0 @@
1
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
- return c > 3 && r && Object.defineProperty(target, key, r), r;
6
- };
7
- import { LitElement, html, css, nothing } from 'lit';
8
- import { customElement, property, state } from 'lit/decorators.js';
9
- import { classMap } from 'lit/directives/class-map.js';
10
- // Import base mixin and types
11
- import { NuralyUIBaseMixin } from '../../shared/base-mixin.js';
12
- import { TimeFormat, TimePickerState, TimePickerPlacement, TimePeriod, EMPTY_TIME_VALUE, } from './timepicker.types.js';
13
- // Import controllers
14
- import { TimePickerSelectionController } from './controllers/timepicker-selection.controller.js';
15
- import { TimePickerValidationController } from './controllers/timepicker-validation.controller.js';
16
- import { TimePickerFormattingController } from './controllers/timepicker-formatting.controller.js';
17
- // Import utilities and constants
18
- import { TimeUtils } from './utils/time.utils.js';
19
- import { TIME_PICKER_EVENTS } from './constants/timepicker.constants.js';
20
- // Import styles
21
- import { timePickerStyles } from './timepicker.style.js';
22
- /**
23
- * A comprehensive time picker component that supports both 12-hour and 24-hour formats,
24
- * with optional seconds display and extensive customization options.
25
- *
26
- * @example
27
- * ```html
28
- * <nr-timepicker
29
- * value="14:30:00"
30
- * format="24h"
31
- * show-seconds
32
- * placeholder="Select time">
33
- * </nr-timepicker>
34
- * ```
35
- */
36
- let NrTimePickerElement = class NrTimePickerElement extends NuralyUIBaseMixin(LitElement) {
37
- constructor() {
38
- super();
39
- // Properties
40
- this.value = '';
41
- this.name = '';
42
- this.placeholder = 'Select time';
43
- this.format = TimeFormat.TwentyFourHour;
44
- this.showSeconds = false;
45
- this.disabled = false;
46
- this.readonly = false;
47
- this.required = false;
48
- this.helperText = '';
49
- this.label = '';
50
- this.size = 'medium';
51
- this.variant = 'outlined';
52
- this.placement = TimePickerPlacement.Bottom;
53
- // State
54
- this.clockOpen = false;
55
- this.inputValue = '';
56
- this.state = TimePickerState.Default;
57
- this.validationMessage = '';
58
- // Controllers
59
- this.selectionController = new TimePickerSelectionController(this);
60
- this.validationController = new TimePickerValidationController(this);
61
- this.formattingController = new TimePickerFormattingController(this);
62
- this.addEventListener('click', this.handleOutsideClick.bind(this));
63
- }
64
- connectedCallback() {
65
- super.connectedCallback();
66
- this.updateConstraints();
67
- if (this.value) {
68
- this.setTimeFromValue(this.value);
69
- }
70
- }
71
- updated(changedProperties) {
72
- super.updated(changedProperties);
73
- if (changedProperties.has('value') && this.value !== this.inputValue) {
74
- this.setTimeFromValue(this.value);
75
- }
76
- if (this.shouldUpdateConstraints(changedProperties)) {
77
- this.updateConstraints();
78
- }
79
- }
80
- render() {
81
- const wrapperClasses = {
82
- 'time-picker': true,
83
- 'time-picker--open': this.clockOpen,
84
- 'time-picker--disabled': this.disabled,
85
- 'time-picker--readonly': this.readonly,
86
- 'time-picker--error': this.state === TimePickerState.Error,
87
- };
88
- return html `
89
- <div class="${classMap(wrapperClasses)}" part="wrapper">
90
- ${this.renderLabel()}
91
- ${this.renderInput()}
92
- ${this.renderDropdown()}
93
- ${this.renderHelperText()}
94
- </div>
95
- `;
96
- }
97
- // Public API methods
98
- open() { this.clockOpen = true; }
99
- close() { this.clockOpen = false; }
100
- clear() {
101
- this.value = '';
102
- this.inputValue = '';
103
- this.selectionController.clearSelection();
104
- }
105
- setToNow() {
106
- const now = TimeUtils.getCurrentTime();
107
- this.selectionController.selectTime(now);
108
- this.updateInputValue();
109
- }
110
- validate() {
111
- return this.validationController.validate();
112
- }
113
- // Private methods
114
- renderLabel() {
115
- if (!this.label)
116
- return nothing;
117
- return html `
118
- <label class="time-picker__label" part="label" for="time-input">
119
- ${this.label}
120
- ${this.required ? html `<span class="time-picker__required">*</span>` : nothing}
121
- </label>
122
- `;
123
- }
124
- renderInput() {
125
- const inputClasses = {
126
- 'time-picker__input': true,
127
- 'time-picker__input--error': this.state === TimePickerState.Error,
128
- };
129
- return html `
130
- <div class="time-picker__input-wrapper" part="input-wrapper">
131
- <input
132
- id="time-input"
133
- class="${classMap(inputClasses)}"
134
- part="input"
135
- type="text"
136
- .value="${this.inputValue}"
137
- placeholder="${this.placeholder}"
138
- ?disabled="${this.disabled}"
139
- ?readonly="${this.readonly}"
140
- ?required="${this.required}"
141
- @input="${this.handleInputChange}"
142
- @focus="${this.handleInputFocus}"
143
- @blur="${this.handleInputBlur}"
144
- />
145
- <button
146
- class="time-picker__trigger"
147
- part="trigger"
148
- type="button"
149
- ?disabled="${this.disabled}"
150
- @click="${this.handleTriggerClick}"
151
- aria-label="Open time picker"
152
- >
153
- <slot name="icon">
154
- <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
155
- <path d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2zm0 18c-4.411 0-8-3.589-8-8s3.589-8 8-8 8 3.589 8 8-3.589 8-8 8z"/>
156
- <path d="M12.5 7H11v6l5.25 3.15.75-1.23-4.5-2.67z"/>
157
- </svg>
158
- </slot>
159
- </button>
160
- </div>
161
- `;
162
- }
163
- renderDropdown() {
164
- if (!this.clockOpen)
165
- return nothing;
166
- const dropdownClasses = {
167
- 'time-picker__dropdown': true,
168
- 'time-picker__dropdown--open': this.clockOpen,
169
- 'time-picker__dropdown--top': this.placement === TimePickerPlacement.Top,
170
- };
171
- return html `
172
- <div class="${classMap(dropdownClasses)}" part="dropdown">
173
- ${this.renderColumnPicker()}
174
- ${this.renderActions()}
175
- </div>
176
- `;
177
- }
178
- renderColumnPicker() {
179
- const selectedTime = this.selectionController.getSelectedTime() || EMPTY_TIME_VALUE;
180
- const config = this.getConfig();
181
- return html `
182
- <div class="time-picker__columns" part="columns">
183
- ${this.renderHourColumn(selectedTime, config)}
184
- ${this.renderMinuteColumn(selectedTime)}
185
- ${this.showSeconds ? this.renderSecondColumn(selectedTime) : nothing}
186
- </div>
187
- `;
188
- }
189
- renderHourColumn(selectedTime, config) {
190
- const hours = config.format === TimeFormat.TwelveHour
191
- ? Array.from({ length: 12 }, (_, i) => i === 0 ? 12 : i)
192
- : Array.from({ length: 24 }, (_, i) => i);
193
- const displayHour = config.format === TimeFormat.TwelveHour
194
- ? this.formattingController.formatHours(selectedTime.hours)
195
- : selectedTime.hours;
196
- return html `
197
- <div class="time-picker__column" part="hour-column">
198
- <div class="time-picker__column-list">
199
- ${hours.map(hour => html `
200
- <div
201
- class="time-picker__column-item ${hour === displayHour ? 'time-picker__column-item--selected' : ''}"
202
- @click="${() => this.handleHourSelect(hour, config.format)}"
203
- >
204
- ${hour.toString().padStart(2, '0')}
205
- </div>
206
- `)}
207
- </div>
208
- </div>
209
- `;
210
- }
211
- renderMinuteColumn(selectedTime) {
212
- const minutes = Array.from({ length: 60 }, (_, i) => i);
213
- return html `
214
- <div class="time-picker__column" part="minute-column">
215
- <div class="time-picker__column-list">
216
- ${minutes.map(minute => html `
217
- <div
218
- class="time-picker__column-item ${minute === selectedTime.minutes ? 'time-picker__column-item--selected' : ''}"
219
- @click="${() => this.handleMinuteSelect(minute)}"
220
- >
221
- ${minute.toString().padStart(2, '0')}
222
- </div>
223
- `)}
224
- </div>
225
- </div>
226
- `;
227
- }
228
- renderSecondColumn(selectedTime) {
229
- const seconds = Array.from({ length: 60 }, (_, i) => i);
230
- return html `
231
- <div class="time-picker__column" part="second-column">
232
- <div class="time-picker__column-list">
233
- ${seconds.map(second => html `
234
- <div
235
- class="time-picker__column-item ${second === selectedTime.seconds ? 'time-picker__column-item--selected' : ''}"
236
- @click="${() => this.handleSecondSelect(second)}"
237
- >
238
- ${second.toString().padStart(2, '0')}
239
- </div>
240
- `)}
241
- </div>
242
- </div>
243
- `;
244
- }
245
- renderActions() {
246
- return html `
247
- <div class="time-picker__actions">
248
- <button
249
- class="time-picker__action-button"
250
- @click="${() => this.setToNow()}"
251
- >
252
- Now
253
- </button>
254
- <button
255
- class="time-picker__action-button time-picker__action-button--primary"
256
- @click="${() => this.close()}"
257
- >
258
- OK
259
- </button>
260
- </div>
261
- `;
262
- }
263
- renderHelperText() {
264
- const text = this.validationMessage || this.helperText;
265
- if (!text)
266
- return nothing;
267
- const isError = this.state === TimePickerState.Error || !!this.validationMessage;
268
- return html `
269
- <div class="time-picker__helper-text ${isError ? 'time-picker__helper-text--error' : ''}" part="helper-text">
270
- ${text}
271
- </div>
272
- `;
273
- }
274
- // Event handlers
275
- handleInputChange(e) {
276
- const target = e.target;
277
- const value = target.value;
278
- if (this.parseTime(value)) {
279
- this.value = value;
280
- this.inputValue = value;
281
- }
282
- else {
283
- target.value = this.inputValue;
284
- }
285
- }
286
- handleInputFocus() {
287
- this.dispatchEvent(new CustomEvent(TIME_PICKER_EVENTS.FOCUS, {
288
- bubbles: true,
289
- composed: true,
290
- }));
291
- }
292
- handleInputBlur() {
293
- this.dispatchEvent(new CustomEvent(TIME_PICKER_EVENTS.BLUR, {
294
- bubbles: true,
295
- composed: true,
296
- }));
297
- }
298
- handleTriggerClick() {
299
- if (!this.disabled && !this.readonly) {
300
- this.clockOpen = !this.clockOpen;
301
- }
302
- }
303
- handleHourSelect(hour, format) {
304
- const selectedTime = this.selectionController.getSelectedTime() || TimeUtils.getCurrentTime();
305
- let adjustedHour = hour;
306
- if (format === TimeFormat.TwelveHour) {
307
- const currentPeriod = this.formattingController.getPeriod(selectedTime.hours);
308
- if (hour === 12) {
309
- adjustedHour = currentPeriod === TimePeriod.AM ? 0 : 12;
310
- }
311
- else {
312
- adjustedHour = currentPeriod === TimePeriod.AM ? hour : hour + 12;
313
- }
314
- }
315
- const updatedTime = Object.assign(Object.assign({}, selectedTime), { hours: adjustedHour });
316
- if (this.validateTime(updatedTime)) {
317
- this.selectionController.selectTime(updatedTime);
318
- this.updateInputValue();
319
- }
320
- }
321
- handleMinuteSelect(minute) {
322
- const selectedTime = this.selectionController.getSelectedTime() || TimeUtils.getCurrentTime();
323
- const updatedTime = Object.assign(Object.assign({}, selectedTime), { minutes: minute });
324
- if (this.validateTime(updatedTime)) {
325
- this.selectionController.selectTime(updatedTime);
326
- this.updateInputValue();
327
- }
328
- }
329
- handleSecondSelect(second) {
330
- const selectedTime = this.selectionController.getSelectedTime() || TimeUtils.getCurrentTime();
331
- const updatedTime = Object.assign(Object.assign({}, selectedTime), { seconds: second });
332
- if (this.validateTime(updatedTime)) {
333
- this.selectionController.selectTime(updatedTime);
334
- this.updateInputValue();
335
- }
336
- }
337
- handleOutsideClick(e) {
338
- if (!this.contains(e.target)) {
339
- this.close();
340
- }
341
- }
342
- // Utility methods
343
- shouldUpdateConstraints(changedProperties) {
344
- return (changedProperties.has('minTime') ||
345
- changedProperties.has('maxTime') ||
346
- changedProperties.has('disabledTimes') ||
347
- changedProperties.has('enabledTimes'));
348
- }
349
- updateConstraints() {
350
- const constraints = {
351
- minTime: this.minTime,
352
- maxTime: this.maxTime,
353
- disabledTimes: this.disabledTimes || [],
354
- enabledTimes: this.enabledTimes,
355
- };
356
- this.validationController.setConstraints(constraints);
357
- }
358
- setTimeFromValue(value) {
359
- if (this.selectionController.setTimeFromString(value)) {
360
- this.inputValue = value;
361
- this.requestUpdate();
362
- }
363
- }
364
- updateInputValue() {
365
- const selectedTime = this.selectionController.getSelectedTime();
366
- if (selectedTime) {
367
- const formattedValue = this.formattingController.formatForDisplay(selectedTime);
368
- this.inputValue = formattedValue;
369
- this.value = formattedValue;
370
- this.dispatchEvent(new CustomEvent(TIME_PICKER_EVENTS.CHANGE, {
371
- detail: { value: formattedValue, time: selectedTime },
372
- bubbles: true,
373
- composed: true,
374
- }));
375
- }
376
- }
377
- validateTime(time) {
378
- return this.validationController.validateTime(time);
379
- }
380
- // TimePickerHost interface implementation
381
- getCurrentTime() {
382
- return this.selectionController.getSelectedTime() || EMPTY_TIME_VALUE;
383
- }
384
- setTime(time) {
385
- this.selectionController.selectTime(time);
386
- this.updateInputValue();
387
- }
388
- formatTime(time) {
389
- return this.formattingController.formatForDisplay(time);
390
- }
391
- parseTime(timeString) {
392
- return this.formattingController.parseInputValue(timeString);
393
- }
394
- getConfig() {
395
- return {
396
- format: this.format,
397
- showSeconds: this.showSeconds,
398
- disabled: this.disabled,
399
- readonly: this.readonly,
400
- };
401
- }
402
- };
403
- NrTimePickerElement.styles = [css `${timePickerStyles}`];
404
- __decorate([
405
- property({ type: String })
406
- ], NrTimePickerElement.prototype, "value", void 0);
407
- __decorate([
408
- property({ type: String })
409
- ], NrTimePickerElement.prototype, "name", void 0);
410
- __decorate([
411
- property({ type: String })
412
- ], NrTimePickerElement.prototype, "placeholder", void 0);
413
- __decorate([
414
- property({ type: String })
415
- ], NrTimePickerElement.prototype, "format", void 0);
416
- __decorate([
417
- property({ type: Boolean, attribute: 'show-seconds' })
418
- ], NrTimePickerElement.prototype, "showSeconds", void 0);
419
- __decorate([
420
- property({ type: Boolean })
421
- ], NrTimePickerElement.prototype, "disabled", void 0);
422
- __decorate([
423
- property({ type: Boolean })
424
- ], NrTimePickerElement.prototype, "readonly", void 0);
425
- __decorate([
426
- property({ type: Boolean })
427
- ], NrTimePickerElement.prototype, "required", void 0);
428
- __decorate([
429
- property({ type: String, attribute: 'min-time' })
430
- ], NrTimePickerElement.prototype, "minTime", void 0);
431
- __decorate([
432
- property({ type: String, attribute: 'max-time' })
433
- ], NrTimePickerElement.prototype, "maxTime", void 0);
434
- __decorate([
435
- property({ type: Array, attribute: 'disabled-times' })
436
- ], NrTimePickerElement.prototype, "disabledTimes", void 0);
437
- __decorate([
438
- property({ type: Array, attribute: 'enabled-times' })
439
- ], NrTimePickerElement.prototype, "enabledTimes", void 0);
440
- __decorate([
441
- property({ type: String, attribute: 'helper-text' })
442
- ], NrTimePickerElement.prototype, "helperText", void 0);
443
- __decorate([
444
- property({ type: String })
445
- ], NrTimePickerElement.prototype, "label", void 0);
446
- __decorate([
447
- property({ type: String })
448
- ], NrTimePickerElement.prototype, "size", void 0);
449
- __decorate([
450
- property({ type: String })
451
- ], NrTimePickerElement.prototype, "variant", void 0);
452
- __decorate([
453
- property({ type: String })
454
- ], NrTimePickerElement.prototype, "placement", void 0);
455
- __decorate([
456
- state()
457
- ], NrTimePickerElement.prototype, "clockOpen", void 0);
458
- __decorate([
459
- state()
460
- ], NrTimePickerElement.prototype, "inputValue", void 0);
461
- __decorate([
462
- state()
463
- ], NrTimePickerElement.prototype, "state", void 0);
464
- __decorate([
465
- state()
466
- ], NrTimePickerElement.prototype, "validationMessage", void 0);
467
- NrTimePickerElement = __decorate([
468
- customElement('nr-timepicker')
469
- ], NrTimePickerElement);
470
- export { NrTimePickerElement };
471
- //# sourceMappingURL=timepicker.component.clean.js.map