@nuralyui/timepicker 0.1.1

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.
Files changed (43) hide show
  1. package/controllers/formatting.controller.d.ts +93 -0
  2. package/controllers/formatting.controller.d.ts.map +1 -0
  3. package/controllers/formatting.controller.js +195 -0
  4. package/controllers/formatting.controller.js.map +1 -0
  5. package/controllers/index.d.ts +9 -0
  6. package/controllers/index.d.ts.map +1 -0
  7. package/controllers/index.js +9 -0
  8. package/controllers/index.js.map +1 -0
  9. package/controllers/selection.controller.d.ts +72 -0
  10. package/controllers/selection.controller.d.ts.map +1 -0
  11. package/controllers/selection.controller.js +175 -0
  12. package/controllers/selection.controller.js.map +1 -0
  13. package/controllers/validation.controller.d.ts +88 -0
  14. package/controllers/validation.controller.d.ts.map +1 -0
  15. package/controllers/validation.controller.js +200 -0
  16. package/controllers/validation.controller.js.map +1 -0
  17. package/index.d.ts +12 -0
  18. package/index.js +12 -0
  19. package/interfaces/timepicker.interface.d.ts +103 -0
  20. package/interfaces/timepicker.interface.d.ts.map +1 -0
  21. package/interfaces/timepicker.interface.js +7 -0
  22. package/interfaces/timepicker.interface.js.map +1 -0
  23. package/package.json +63 -0
  24. package/test/timepicker.test.d.ts +7 -0
  25. package/test/timepicker.test.d.ts.map +1 -0
  26. package/test/timepicker.test.js +218 -0
  27. package/test/timepicker.test.js.map +1 -0
  28. package/timepicker.component.backup.d.ts +165 -0
  29. package/timepicker.component.backup.js +890 -0
  30. package/timepicker.component.clean.d.ts +95 -0
  31. package/timepicker.component.clean.js +471 -0
  32. package/timepicker.component.d.ts +117 -0
  33. package/timepicker.component.js +747 -0
  34. package/timepicker.constants.d.ts +85 -0
  35. package/timepicker.constants.js +85 -0
  36. package/timepicker.style.d.ts +7 -0
  37. package/timepicker.style.js +646 -0
  38. package/timepicker.types.d.ts +161 -0
  39. package/timepicker.types.js +125 -0
  40. package/utils/time.utils.d.ts +87 -0
  41. package/utils/time.utils.d.ts.map +1 -0
  42. package/utils/time.utils.js +235 -0
  43. package/utils/time.utils.js.map +1 -0
@@ -0,0 +1,88 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2023 Nuraly, Laabidi Aymen
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ import { TimeValue, TimeConstraints } from '../timepicker.types.js';
7
+ import { TimePickerHost, TimeValidationController } from '../interfaces/timepicker.interface.js';
8
+ /**
9
+ * Controller for handling time validation logic
10
+ */
11
+ export declare class TimePickerValidationController implements TimeValidationController {
12
+ private host;
13
+ private constraints;
14
+ constructor(host: TimePickerHost);
15
+ /**
16
+ * Set validation constraints
17
+ */
18
+ setConstraints(constraints: TimeConstraints): void;
19
+ /**
20
+ * Get current constraints
21
+ */
22
+ getConstraints(): TimeConstraints;
23
+ /**
24
+ * Validate time against all constraints
25
+ */
26
+ validateConstraints(time: TimeValue): boolean;
27
+ /**
28
+ * Check if time is within min/max bounds
29
+ */
30
+ isTimeInBounds(time: TimeValue): boolean;
31
+ /**
32
+ * Check if time is explicitly disabled
33
+ */
34
+ isTimeDisabled(time: TimeValue): boolean;
35
+ /**
36
+ * Check if time is in enabled times list (if specified)
37
+ */
38
+ isTimeEnabled(time: TimeValue): boolean;
39
+ /**
40
+ * Get validation message for a time
41
+ */
42
+ getValidationMessage(time: TimeValue): string;
43
+ /**
44
+ * Get bounds validation message
45
+ */
46
+ private getBoundsValidationMessage;
47
+ /**
48
+ * Validate time format
49
+ */
50
+ validateTimeFormat(timeString: string): boolean;
51
+ /**
52
+ * Get validation result with details
53
+ */
54
+ getValidationResult(time: TimeValue): {
55
+ isValid: boolean;
56
+ message: string;
57
+ errors: string[];
58
+ };
59
+ /**
60
+ * Find nearest valid time
61
+ */
62
+ findNearestValidTime(time: TimeValue): TimeValue | null;
63
+ /**
64
+ * Check if current time selection is valid
65
+ */
66
+ isCurrentSelectionValid(): boolean;
67
+ /**
68
+ * Set min time constraint
69
+ */
70
+ setMinTime(minTime: string | null): void;
71
+ /**
72
+ * Set max time constraint
73
+ */
74
+ setMaxTime(maxTime: string | null): void;
75
+ /**
76
+ * Set disabled times
77
+ */
78
+ setDisabledTimes(disabledTimes: string[]): void;
79
+ /**
80
+ * Set enabled times
81
+ */
82
+ setEnabledTimes(enabledTimes: string[]): void;
83
+ /**
84
+ * Clear all constraints
85
+ */
86
+ clearConstraints(): void;
87
+ }
88
+ //# sourceMappingURL=validation.controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.controller.d.ts","sourceRoot":"","sources":["../../../../src/components/timepicker/controllers/validation.controller.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AAGjG;;GAEG;AACH,qBAAa,8BAA+B,YAAW,wBAAwB;IAGjE,OAAO,CAAC,IAAI;IAFxB,OAAO,CAAC,WAAW,CAAuB;gBAEtB,IAAI,EAAE,cAAc;IAExC;;OAEG;IACH,cAAc,CAAC,WAAW,EAAE,eAAe,GAAG,IAAI;IAIlD;;OAEG;IACH,cAAc,IAAI,eAAe;IAIjC;;OAEG;IACH,mBAAmB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO;IAQ7C;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO;IAmBxC;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO;IASxC;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO;IAUvC;;OAEG;IACH,oBAAoB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM;IAgB7C;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAqBlC;;OAEG;IACH,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAM/C;;OAEG;IACH,mBAAmB,CAAC,IAAI,EAAE,SAAS,GAAG;QACpC,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,EAAE,CAAC;KAClB;IAsBD;;OAEG;IACH,oBAAoB,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,IAAI;IAuBvD;;OAEG;IACH,uBAAuB,IAAI,OAAO;IAKlC;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAIxC;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAIxC;;OAEG;IACH,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,IAAI;IAI/C;;OAEG;IACH,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,IAAI;IAI7C;;OAEG;IACH,gBAAgB,IAAI,IAAI;CAGzB"}
@@ -0,0 +1,200 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2023 Nuraly, Laabidi Aymen
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ import { TimeUtils } from '../utils/time.utils.js';
7
+ /**
8
+ * Controller for handling time validation logic
9
+ */
10
+ export class TimePickerValidationController {
11
+ constructor(host) {
12
+ this.host = host;
13
+ this.constraints = {};
14
+ }
15
+ /**
16
+ * Set validation constraints
17
+ */
18
+ setConstraints(constraints) {
19
+ this.constraints = Object.assign({}, constraints);
20
+ }
21
+ /**
22
+ * Get current constraints
23
+ */
24
+ getConstraints() {
25
+ return Object.assign({}, this.constraints);
26
+ }
27
+ /**
28
+ * Validate time against all constraints
29
+ */
30
+ validateConstraints(time) {
31
+ return (this.isTimeInBounds(time) &&
32
+ !this.isTimeDisabled(time) &&
33
+ this.isTimeEnabled(time));
34
+ }
35
+ /**
36
+ * Check if time is within min/max bounds
37
+ */
38
+ isTimeInBounds(time) {
39
+ let minTime = null;
40
+ let maxTime = null;
41
+ // Parse min time constraint
42
+ if (this.constraints.minTime) {
43
+ const config = this.host.getConfig();
44
+ minTime = TimeUtils.parseTimeString(this.constraints.minTime, config.format);
45
+ }
46
+ // Parse max time constraint
47
+ if (this.constraints.maxTime) {
48
+ const config = this.host.getConfig();
49
+ maxTime = TimeUtils.parseTimeString(this.constraints.maxTime, config.format);
50
+ }
51
+ return TimeUtils.isTimeInRange(time, minTime, maxTime);
52
+ }
53
+ /**
54
+ * Check if time is explicitly disabled
55
+ */
56
+ isTimeDisabled(time) {
57
+ if (!this.constraints.disabledTimes || this.constraints.disabledTimes.length === 0) {
58
+ return false;
59
+ }
60
+ const timeString = this.host.formatTime(time);
61
+ return this.constraints.disabledTimes.includes(timeString);
62
+ }
63
+ /**
64
+ * Check if time is in enabled times list (if specified)
65
+ */
66
+ isTimeEnabled(time) {
67
+ // If no enabled times specified, all times are enabled (except disabled ones)
68
+ if (!this.constraints.enabledTimes || this.constraints.enabledTimes.length === 0) {
69
+ return true;
70
+ }
71
+ const timeString = this.host.formatTime(time);
72
+ return this.constraints.enabledTimes.includes(timeString);
73
+ }
74
+ /**
75
+ * Get validation message for a time
76
+ */
77
+ getValidationMessage(time) {
78
+ if (!this.isTimeInBounds(time)) {
79
+ return this.getBoundsValidationMessage(time);
80
+ }
81
+ if (this.isTimeDisabled(time)) {
82
+ return 'This time is not available';
83
+ }
84
+ if (!this.isTimeEnabled(time)) {
85
+ return 'This time is not in the allowed time range';
86
+ }
87
+ return '';
88
+ }
89
+ /**
90
+ * Get bounds validation message
91
+ */
92
+ getBoundsValidationMessage(time) {
93
+ const config = this.host.getConfig();
94
+ let message = '';
95
+ if (this.constraints.minTime && this.constraints.maxTime) {
96
+ message = `Time must be between ${this.constraints.minTime} and ${this.constraints.maxTime}`;
97
+ }
98
+ else if (this.constraints.minTime) {
99
+ const minTime = TimeUtils.parseTimeString(this.constraints.minTime, config.format);
100
+ if (minTime && TimeUtils.compareTime(time, minTime) < 0) {
101
+ message = `Time must be after ${this.constraints.minTime}`;
102
+ }
103
+ }
104
+ else if (this.constraints.maxTime) {
105
+ const maxTime = TimeUtils.parseTimeString(this.constraints.maxTime, config.format);
106
+ if (maxTime && TimeUtils.compareTime(time, maxTime) > 0) {
107
+ message = `Time must be before ${this.constraints.maxTime}`;
108
+ }
109
+ }
110
+ return message;
111
+ }
112
+ /**
113
+ * Validate time format
114
+ */
115
+ validateTimeFormat(timeString) {
116
+ const config = this.host.getConfig();
117
+ const parsedTime = TimeUtils.parseTimeString(timeString, config.format);
118
+ return parsedTime !== null;
119
+ }
120
+ /**
121
+ * Get validation result with details
122
+ */
123
+ getValidationResult(time) {
124
+ const errors = [];
125
+ if (!this.isTimeInBounds(time)) {
126
+ errors.push(this.getBoundsValidationMessage(time));
127
+ }
128
+ if (this.isTimeDisabled(time)) {
129
+ errors.push('This time is disabled');
130
+ }
131
+ if (!this.isTimeEnabled(time)) {
132
+ errors.push('This time is not in the allowed range');
133
+ }
134
+ return {
135
+ isValid: errors.length === 0,
136
+ message: errors.length > 0 ? errors[0] : '',
137
+ errors,
138
+ };
139
+ }
140
+ /**
141
+ * Find nearest valid time
142
+ */
143
+ findNearestValidTime(time) {
144
+ if (this.validateConstraints(time)) {
145
+ return time;
146
+ }
147
+ // Try nearby times (within 1 hour range)
148
+ for (let minuteOffset = 1; minuteOffset <= 60; minuteOffset++) {
149
+ // Try adding minutes
150
+ const laterTime = TimeUtils.addTime(time, 0, minuteOffset, 0);
151
+ if (this.validateConstraints(laterTime)) {
152
+ return laterTime;
153
+ }
154
+ // Try subtracting minutes
155
+ const earlierTime = TimeUtils.addTime(time, 0, -minuteOffset, 0);
156
+ if (this.validateConstraints(earlierTime)) {
157
+ return earlierTime;
158
+ }
159
+ }
160
+ return null;
161
+ }
162
+ /**
163
+ * Check if current time selection is valid
164
+ */
165
+ isCurrentSelectionValid() {
166
+ const selectedTime = this.host.getCurrentTime();
167
+ return this.validateConstraints(selectedTime);
168
+ }
169
+ /**
170
+ * Set min time constraint
171
+ */
172
+ setMinTime(minTime) {
173
+ this.constraints.minTime = minTime || undefined;
174
+ }
175
+ /**
176
+ * Set max time constraint
177
+ */
178
+ setMaxTime(maxTime) {
179
+ this.constraints.maxTime = maxTime || undefined;
180
+ }
181
+ /**
182
+ * Set disabled times
183
+ */
184
+ setDisabledTimes(disabledTimes) {
185
+ this.constraints.disabledTimes = [...disabledTimes];
186
+ }
187
+ /**
188
+ * Set enabled times
189
+ */
190
+ setEnabledTimes(enabledTimes) {
191
+ this.constraints.enabledTimes = [...enabledTimes];
192
+ }
193
+ /**
194
+ * Clear all constraints
195
+ */
196
+ clearConstraints() {
197
+ this.constraints = {};
198
+ }
199
+ }
200
+ //# sourceMappingURL=validation.controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.controller.js","sourceRoot":"","sources":["../../../../src/components/timepicker/controllers/validation.controller.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2023 Nuraly, Laabidi Aymen\n * SPDX-License-Identifier: MIT\n */\n\nimport { TimeValue, TimeConstraints } from '../timepicker.types.js';\nimport { TimePickerHost, TimeValidationController } from '../interfaces/timepicker.interface.js';\nimport { TimeUtils } from '../utils/time.utils.js';\n\n/**\n * Controller for handling time validation logic\n */\nexport class TimePickerValidationController implements TimeValidationController {\n private constraints: TimeConstraints = {};\n\n constructor(private host: TimePickerHost) {}\n\n /**\n * Set validation constraints\n */\n setConstraints(constraints: TimeConstraints): void {\n this.constraints = { ...constraints };\n }\n\n /**\n * Get current constraints\n */\n getConstraints(): TimeConstraints {\n return { ...this.constraints };\n }\n\n /**\n * Validate time against all constraints\n */\n validateConstraints(time: TimeValue): boolean {\n return (\n this.isTimeInBounds(time) &&\n !this.isTimeDisabled(time) &&\n this.isTimeEnabled(time)\n );\n }\n\n /**\n * Check if time is within min/max bounds\n */\n isTimeInBounds(time: TimeValue): boolean {\n let minTime: TimeValue | null = null;\n let maxTime: TimeValue | null = null;\n\n // Parse min time constraint\n if (this.constraints.minTime) {\n const config = this.host.getConfig();\n minTime = TimeUtils.parseTimeString(this.constraints.minTime, config.format);\n }\n\n // Parse max time constraint\n if (this.constraints.maxTime) {\n const config = this.host.getConfig();\n maxTime = TimeUtils.parseTimeString(this.constraints.maxTime, config.format);\n }\n\n return TimeUtils.isTimeInRange(time, minTime, maxTime);\n }\n\n /**\n * Check if time is explicitly disabled\n */\n isTimeDisabled(time: TimeValue): boolean {\n if (!this.constraints.disabledTimes || this.constraints.disabledTimes.length === 0) {\n return false;\n }\n\n const timeString = this.host.formatTime(time);\n return this.constraints.disabledTimes.includes(timeString);\n }\n\n /**\n * Check if time is in enabled times list (if specified)\n */\n isTimeEnabled(time: TimeValue): boolean {\n // If no enabled times specified, all times are enabled (except disabled ones)\n if (!this.constraints.enabledTimes || this.constraints.enabledTimes.length === 0) {\n return true;\n }\n\n const timeString = this.host.formatTime(time);\n return this.constraints.enabledTimes.includes(timeString);\n }\n\n /**\n * Get validation message for a time\n */\n getValidationMessage(time: TimeValue): string {\n if (!this.isTimeInBounds(time)) {\n return this.getBoundsValidationMessage(time);\n }\n\n if (this.isTimeDisabled(time)) {\n return 'This time is not available';\n }\n\n if (!this.isTimeEnabled(time)) {\n return 'This time is not in the allowed time range';\n }\n\n return '';\n }\n\n /**\n * Get bounds validation message\n */\n private getBoundsValidationMessage(time: TimeValue): string {\n const config = this.host.getConfig();\n let message = '';\n\n if (this.constraints.minTime && this.constraints.maxTime) {\n message = `Time must be between ${this.constraints.minTime} and ${this.constraints.maxTime}`;\n } else if (this.constraints.minTime) {\n const minTime = TimeUtils.parseTimeString(this.constraints.minTime, config.format);\n if (minTime && TimeUtils.compareTime(time, minTime) < 0) {\n message = `Time must be after ${this.constraints.minTime}`;\n }\n } else if (this.constraints.maxTime) {\n const maxTime = TimeUtils.parseTimeString(this.constraints.maxTime, config.format);\n if (maxTime && TimeUtils.compareTime(time, maxTime) > 0) {\n message = `Time must be before ${this.constraints.maxTime}`;\n }\n }\n\n return message;\n }\n\n /**\n * Validate time format\n */\n validateTimeFormat(timeString: string): boolean {\n const config = this.host.getConfig();\n const parsedTime = TimeUtils.parseTimeString(timeString, config.format);\n return parsedTime !== null;\n }\n\n /**\n * Get validation result with details\n */\n getValidationResult(time: TimeValue): {\n isValid: boolean;\n message: string;\n errors: string[];\n } {\n const errors: string[] = [];\n \n if (!this.isTimeInBounds(time)) {\n errors.push(this.getBoundsValidationMessage(time));\n }\n\n if (this.isTimeDisabled(time)) {\n errors.push('This time is disabled');\n }\n\n if (!this.isTimeEnabled(time)) {\n errors.push('This time is not in the allowed range');\n }\n\n return {\n isValid: errors.length === 0,\n message: errors.length > 0 ? errors[0] : '',\n errors,\n };\n }\n\n /**\n * Find nearest valid time\n */\n findNearestValidTime(time: TimeValue): TimeValue | null {\n if (this.validateConstraints(time)) {\n return time;\n }\n\n // Try nearby times (within 1 hour range)\n for (let minuteOffset = 1; minuteOffset <= 60; minuteOffset++) {\n // Try adding minutes\n const laterTime = TimeUtils.addTime(time, 0, minuteOffset, 0);\n if (this.validateConstraints(laterTime)) {\n return laterTime;\n }\n\n // Try subtracting minutes\n const earlierTime = TimeUtils.addTime(time, 0, -minuteOffset, 0);\n if (this.validateConstraints(earlierTime)) {\n return earlierTime;\n }\n }\n\n return null;\n }\n\n /**\n * Check if current time selection is valid\n */\n isCurrentSelectionValid(): boolean {\n const selectedTime = this.host.getCurrentTime();\n return this.validateConstraints(selectedTime);\n }\n\n /**\n * Set min time constraint\n */\n setMinTime(minTime: string | null): void {\n this.constraints.minTime = minTime || undefined;\n }\n\n /**\n * Set max time constraint\n */\n setMaxTime(maxTime: string | null): void {\n this.constraints.maxTime = maxTime || undefined;\n }\n\n /**\n * Set disabled times\n */\n setDisabledTimes(disabledTimes: string[]): void {\n this.constraints.disabledTimes = [...disabledTimes];\n }\n\n /**\n * Set enabled times\n */\n setEnabledTimes(enabledTimes: string[]): void {\n this.constraints.enabledTimes = [...enabledTimes];\n }\n\n /**\n * Clear all constraints\n */\n clearConstraints(): void {\n this.constraints = {};\n }\n}\n"]}
package/index.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2023 Nuraly, Laabidi Aymen
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ export { NrTimePickerElement } from './timepicker.component.js';
7
+ export * from './timepicker.types.js';
8
+ export * from './timepicker.constants.js';
9
+ export * from './utils/time.utils.js';
10
+ export * from './controllers/index.js';
11
+ export * from './interfaces/timepicker.interface.js';
12
+ //# sourceMappingURL=index.d.ts.map
package/index.js ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2023 Nuraly, Laabidi Aymen
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ export { NrTimePickerElement } from './timepicker.component.js';
7
+ export * from './timepicker.types.js';
8
+ export * from './timepicker.constants.js';
9
+ export * from './utils/time.utils.js';
10
+ export * from './controllers/index.js';
11
+ export * from './interfaces/timepicker.interface.js';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,103 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2023 Nuraly, Laabidi Aymen
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ import { TimeValue, TimePickerConfig } from '../timepicker.types.js';
7
+ /**
8
+ * Base controller interface for time picker host
9
+ */
10
+ export interface TimePickerHost {
11
+ /**
12
+ * Get current time value
13
+ */
14
+ getCurrentTime(): TimeValue;
15
+ /**
16
+ * Set time value
17
+ */
18
+ setTime(time: TimeValue): void;
19
+ /**
20
+ * Format time value to string
21
+ */
22
+ formatTime(time: TimeValue): string;
23
+ /**
24
+ * Parse time string to TimeValue
25
+ */
26
+ parseTime(timeString: string): TimeValue | null;
27
+ /**
28
+ * Get time picker configuration
29
+ */
30
+ getConfig(): TimePickerConfig;
31
+ /**
32
+ * Validate time value
33
+ */
34
+ validateTime(time: TimeValue): boolean;
35
+ /**
36
+ * Request component update
37
+ */
38
+ requestUpdate(): void;
39
+ }
40
+ /**
41
+ * Time selection controller interface
42
+ */
43
+ export interface TimeSelectionController {
44
+ /**
45
+ * Select time value
46
+ */
47
+ selectTime(time: TimeValue): void;
48
+ /**
49
+ * Get selected time
50
+ */
51
+ getSelectedTime(): TimeValue | null;
52
+ /**
53
+ * Clear selection
54
+ */
55
+ clearSelection(): void;
56
+ /**
57
+ * Check if time is selected
58
+ */
59
+ isTimeSelected(time: TimeValue): boolean;
60
+ }
61
+ /**
62
+ * Time validation controller interface
63
+ */
64
+ export interface TimeValidationController {
65
+ /**
66
+ * Validate time constraints
67
+ */
68
+ validateConstraints(time: TimeValue): boolean;
69
+ /**
70
+ * Check if time is within min/max bounds
71
+ */
72
+ isTimeInBounds(time: TimeValue): boolean;
73
+ /**
74
+ * Check if time is disabled
75
+ */
76
+ isTimeDisabled(time: TimeValue): boolean;
77
+ /**
78
+ * Get validation message
79
+ */
80
+ getValidationMessage(time: TimeValue): string;
81
+ }
82
+ /**
83
+ * Time formatting controller interface
84
+ */
85
+ export interface TimeFormattingController {
86
+ /**
87
+ * Format time to display string
88
+ */
89
+ formatForDisplay(time: TimeValue): string;
90
+ /**
91
+ * Format time to input value
92
+ */
93
+ formatForInput(time: TimeValue): string;
94
+ /**
95
+ * Parse input value to time
96
+ */
97
+ parseInputValue(value: string): TimeValue | null;
98
+ /**
99
+ * Get time format pattern
100
+ */
101
+ getFormatPattern(): string;
102
+ }
103
+ //# sourceMappingURL=timepicker.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timepicker.interface.d.ts","sourceRoot":"","sources":["../../../../src/components/timepicker/interfaces/timepicker.interface.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,cAAc,IAAI,SAAS,CAAC;IAE5B;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IAE/B;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC;IAEpC;;OAEG;IACH,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAEhD;;OAEG;IACH,SAAS,IAAI,gBAAgB,CAAC;IAE9B;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC;IAEvC;;OAEG;IACH,aAAa,IAAI,IAAI,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IAElC;;OAEG;IACH,eAAe,IAAI,SAAS,GAAG,IAAI,CAAC;IAEpC;;OAEG;IACH,cAAc,IAAI,IAAI,CAAC;IAEvB;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC;CAC1C;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,mBAAmB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC;IAE9C;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC;IAEzC;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC;IAEzC;;OAEG;IACH,oBAAoB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC;CAC/C;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,gBAAgB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC;IAE1C;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC;IAExC;;OAEG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAEjD;;OAEG;IACH,gBAAgB,IAAI,MAAM,CAAC;CAC5B"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2023 Nuraly, Laabidi Aymen
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=timepicker.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timepicker.interface.js","sourceRoot":"","sources":["../../../../src/components/timepicker/interfaces/timepicker.interface.ts"],"names":[],"mappings":"AAAA;;;;GAIG","sourcesContent":["/**\n * @license\n * Copyright 2023 Nuraly, Laabidi Aymen\n * SPDX-License-Identifier: MIT\n */\n\nimport { TimeValue, TimePickerConfig } from '../timepicker.types.js';\n\n/**\n * Base controller interface for time picker host\n */\nexport interface TimePickerHost {\n /**\n * Get current time value\n */\n getCurrentTime(): TimeValue;\n\n /**\n * Set time value\n */\n setTime(time: TimeValue): void;\n\n /**\n * Format time value to string\n */\n formatTime(time: TimeValue): string;\n\n /**\n * Parse time string to TimeValue\n */\n parseTime(timeString: string): TimeValue | null;\n\n /**\n * Get time picker configuration\n */\n getConfig(): TimePickerConfig;\n\n /**\n * Validate time value\n */\n validateTime(time: TimeValue): boolean;\n\n /**\n * Request component update\n */\n requestUpdate(): void;\n}\n\n/**\n * Time selection controller interface\n */\nexport interface TimeSelectionController {\n /**\n * Select time value\n */\n selectTime(time: TimeValue): void;\n\n /**\n * Get selected time\n */\n getSelectedTime(): TimeValue | null;\n\n /**\n * Clear selection\n */\n clearSelection(): void;\n\n /**\n * Check if time is selected\n */\n isTimeSelected(time: TimeValue): boolean;\n}\n\n/**\n * Time validation controller interface\n */\nexport interface TimeValidationController {\n /**\n * Validate time constraints\n */\n validateConstraints(time: TimeValue): boolean;\n\n /**\n * Check if time is within min/max bounds\n */\n isTimeInBounds(time: TimeValue): boolean;\n\n /**\n * Check if time is disabled\n */\n isTimeDisabled(time: TimeValue): boolean;\n\n /**\n * Get validation message\n */\n getValidationMessage(time: TimeValue): string;\n}\n\n/**\n * Time formatting controller interface\n */\nexport interface TimeFormattingController {\n /**\n * Format time to display string\n */\n formatForDisplay(time: TimeValue): string;\n\n /**\n * Format time to input value\n */\n formatForInput(time: TimeValue): string;\n\n /**\n * Parse input value to time\n */\n parseInputValue(value: string): TimeValue | null;\n\n /**\n * Get time format pattern\n */\n getFormatPattern(): string;\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@nuralyui/timepicker",
3
+ "version": "0.1.1",
4
+ "description": "NuralyUI TimePicker - A comprehensive time selection component with clock interface, multiple formats, and validation",
5
+ "type": "module",
6
+ "main": "./index.js",
7
+ "module": "./index.js",
8
+ "types": "./index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./index.d.ts",
12
+ "default": "./index.js"
13
+ },
14
+ "./timepicker.component.js": {
15
+ "types": "./timepicker.component.d.ts",
16
+ "default": "./timepicker.component.js"
17
+ }
18
+ },
19
+ "files": [
20
+ "*.js",
21
+ "*.d.ts",
22
+ "controllers/",
23
+ "interfaces/",
24
+ "utils/",
25
+ "demo/",
26
+ "test/"
27
+ ],
28
+ "scripts": {
29
+ "build": "tsc",
30
+ "test": "wtr \"**/*.test.js\" --node-resolve",
31
+ "test:watch": "wtr \"**/*.test.js\" --node-resolve --watch",
32
+ "demo": "wds --open demo/ --node-resolve"
33
+ },
34
+ "keywords": [
35
+ "timepicker",
36
+ "time",
37
+ "clock",
38
+ "web-components",
39
+ "lit",
40
+ "nuraly",
41
+ "ui-components",
42
+ "time-selector",
43
+ "12h-format",
44
+ "24h-format"
45
+ ],
46
+ "author": "Nuraly Team <team@nuraly.io>",
47
+ "license": "MIT",
48
+ "dependencies": {
49
+ "lit": "^3.0.0"
50
+ },
51
+ "peerDependencies": {
52
+ "@nuraly/shared": "^1.0.0"
53
+ },
54
+ "repository": {
55
+ "type": "git",
56
+ "url": "https://github.com/Nuralyio/NuralyUI.git",
57
+ "directory": "src/components/timepicker"
58
+ },
59
+ "bugs": {
60
+ "url": "https://github.com/Nuralyio/NuralyUI/issues"
61
+ },
62
+ "homepage": "https://nuralyui.com/components/timepicker"
63
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2023 Nuraly, Laabidi Aymen
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=timepicker.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timepicker.test.d.ts","sourceRoot":"","sources":["../../../../src/components/timepicker/test/timepicker.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}