@nanahoshi/mona-ui 0.1.0

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 (134) hide show
  1. package/README.md +25 -0
  2. package/fesm2022/nanahoshi-mona-ui-auto-complete.mjs +590 -0
  3. package/fesm2022/nanahoshi-mona-ui-avatar.mjs +168 -0
  4. package/fesm2022/nanahoshi-mona-ui-breadcrumb.mjs +220 -0
  5. package/fesm2022/nanahoshi-mona-ui-button-group.mjs +225 -0
  6. package/fesm2022/nanahoshi-mona-ui-button.mjs +497 -0
  7. package/fesm2022/nanahoshi-mona-ui-calendar.mjs +1569 -0
  8. package/fesm2022/nanahoshi-mona-ui-check-box.mjs +339 -0
  9. package/fesm2022/nanahoshi-mona-ui-chip.mjs +453 -0
  10. package/fesm2022/nanahoshi-mona-ui-circular-progress-bar.mjs +200 -0
  11. package/fesm2022/nanahoshi-mona-ui-color-gradient.mjs +853 -0
  12. package/fesm2022/nanahoshi-mona-ui-color-palette.mjs +923 -0
  13. package/fesm2022/nanahoshi-mona-ui-color-picker.mjs +495 -0
  14. package/fesm2022/nanahoshi-mona-ui-combo-box.mjs +686 -0
  15. package/fesm2022/nanahoshi-mona-ui-common.mjs +642 -0
  16. package/fesm2022/nanahoshi-mona-ui-contextmenu.mjs +485 -0
  17. package/fesm2022/nanahoshi-mona-ui-date-input.mjs +132 -0
  18. package/fesm2022/nanahoshi-mona-ui-date-picker.mjs +460 -0
  19. package/fesm2022/nanahoshi-mona-ui-datetime-picker.mjs +659 -0
  20. package/fesm2022/nanahoshi-mona-ui-dialog.mjs +828 -0
  21. package/fesm2022/nanahoshi-mona-ui-dropdown-button.mjs +523 -0
  22. package/fesm2022/nanahoshi-mona-ui-dropdown-list.mjs +615 -0
  23. package/fesm2022/nanahoshi-mona-ui-dropdowns.mjs +701 -0
  24. package/fesm2022/nanahoshi-mona-ui-editor.mjs +1400 -0
  25. package/fesm2022/nanahoshi-mona-ui-expansion-panel.mjs +245 -0
  26. package/fesm2022/nanahoshi-mona-ui-fieldset.mjs +170 -0
  27. package/fesm2022/nanahoshi-mona-ui-filter.mjs +680 -0
  28. package/fesm2022/nanahoshi-mona-ui-grid-grid-footer-cell.component-B9SQH5N-.mjs +105 -0
  29. package/fesm2022/nanahoshi-mona-ui-grid-grid-footer-table-cell.directive-DlLwcCFT.mjs +42 -0
  30. package/fesm2022/nanahoshi-mona-ui-grid-grid-list.component-Dgea-O0X.mjs +130 -0
  31. package/fesm2022/nanahoshi-mona-ui-grid-grid-toggle.component-DIUutx9s.mjs +773 -0
  32. package/fesm2022/nanahoshi-mona-ui-grid-grid-virtual-list.component-DRHycGIh.mjs +240 -0
  33. package/fesm2022/nanahoshi-mona-ui-grid-nanahoshi-mona-ui-grid-C3eZIaJK.mjs +5374 -0
  34. package/fesm2022/nanahoshi-mona-ui-grid.mjs +2 -0
  35. package/fesm2022/nanahoshi-mona-ui-internal-filter-input.mjs +87 -0
  36. package/fesm2022/nanahoshi-mona-ui-internal-indicator-icon.mjs +154 -0
  37. package/fesm2022/nanahoshi-mona-ui-internal-list.mjs +1356 -0
  38. package/fesm2022/nanahoshi-mona-ui-internal-tree.mjs +2263 -0
  39. package/fesm2022/nanahoshi-mona-ui-internal.mjs +379 -0
  40. package/fesm2022/nanahoshi-mona-ui-list-box.mjs +630 -0
  41. package/fesm2022/nanahoshi-mona-ui-list-view.mjs +527 -0
  42. package/fesm2022/nanahoshi-mona-ui-list.mjs +4 -0
  43. package/fesm2022/nanahoshi-mona-ui-menubar.mjs +966 -0
  44. package/fesm2022/nanahoshi-mona-ui-multi-select.mjs +641 -0
  45. package/fesm2022/nanahoshi-mona-ui-notification.mjs +536 -0
  46. package/fesm2022/nanahoshi-mona-ui-numeric-text-box.mjs +597 -0
  47. package/fesm2022/nanahoshi-mona-ui-pager.mjs +790 -0
  48. package/fesm2022/nanahoshi-mona-ui-placeholder.mjs +83 -0
  49. package/fesm2022/nanahoshi-mona-ui-popover.mjs +325 -0
  50. package/fesm2022/nanahoshi-mona-ui-popup-menu.mjs +1559 -0
  51. package/fesm2022/nanahoshi-mona-ui-popup.mjs +1321 -0
  52. package/fesm2022/nanahoshi-mona-ui-progress-bar.mjs +294 -0
  53. package/fesm2022/nanahoshi-mona-ui-query.mjs +175 -0
  54. package/fesm2022/nanahoshi-mona-ui-radio-button.mjs +339 -0
  55. package/fesm2022/nanahoshi-mona-ui-scroll-view.mjs +565 -0
  56. package/fesm2022/nanahoshi-mona-ui-slider.mjs +1049 -0
  57. package/fesm2022/nanahoshi-mona-ui-split-button.mjs +636 -0
  58. package/fesm2022/nanahoshi-mona-ui-splitter.mjs +843 -0
  59. package/fesm2022/nanahoshi-mona-ui-stepper.mjs +537 -0
  60. package/fesm2022/nanahoshi-mona-ui-switch.mjs +308 -0
  61. package/fesm2022/nanahoshi-mona-ui-tabs.mjs +664 -0
  62. package/fesm2022/nanahoshi-mona-ui-text-area.mjs +111 -0
  63. package/fesm2022/nanahoshi-mona-ui-text-box.mjs +369 -0
  64. package/fesm2022/nanahoshi-mona-ui-theme.mjs +314 -0
  65. package/fesm2022/nanahoshi-mona-ui-time-picker.mjs +450 -0
  66. package/fesm2022/nanahoshi-mona-ui-time-selector.mjs +723 -0
  67. package/fesm2022/nanahoshi-mona-ui-tooltip.mjs +716 -0
  68. package/fesm2022/nanahoshi-mona-ui-tree-view.mjs +733 -0
  69. package/fesm2022/nanahoshi-mona-ui-window.mjs +1329 -0
  70. package/fesm2022/nanahoshi-mona-ui.mjs +9 -0
  71. package/package.json +289 -0
  72. package/types/nanahoshi-mona-ui-auto-complete.d.ts +223 -0
  73. package/types/nanahoshi-mona-ui-avatar.d.ts +642 -0
  74. package/types/nanahoshi-mona-ui-breadcrumb.d.ts +70 -0
  75. package/types/nanahoshi-mona-ui-button-group.d.ts +77 -0
  76. package/types/nanahoshi-mona-ui-button.d.ts +111 -0
  77. package/types/nanahoshi-mona-ui-calendar.d.ts +262 -0
  78. package/types/nanahoshi-mona-ui-check-box.d.ts +133 -0
  79. package/types/nanahoshi-mona-ui-chip.d.ts +130 -0
  80. package/types/nanahoshi-mona-ui-circular-progress-bar.d.ts +113 -0
  81. package/types/nanahoshi-mona-ui-color-gradient.d.ts +201 -0
  82. package/types/nanahoshi-mona-ui-color-palette.d.ts +102 -0
  83. package/types/nanahoshi-mona-ui-color-picker.d.ts +156 -0
  84. package/types/nanahoshi-mona-ui-combo-box.d.ts +232 -0
  85. package/types/nanahoshi-mona-ui-common.d.ts +386 -0
  86. package/types/nanahoshi-mona-ui-contextmenu.d.ts +129 -0
  87. package/types/nanahoshi-mona-ui-date-input.d.ts +60 -0
  88. package/types/nanahoshi-mona-ui-date-picker.d.ts +177 -0
  89. package/types/nanahoshi-mona-ui-datetime-picker.d.ts +199 -0
  90. package/types/nanahoshi-mona-ui-dialog.d.ts +261 -0
  91. package/types/nanahoshi-mona-ui-dropdown-button.d.ts +159 -0
  92. package/types/nanahoshi-mona-ui-dropdown-list.d.ts +219 -0
  93. package/types/nanahoshi-mona-ui-dropdowns.d.ts +176 -0
  94. package/types/nanahoshi-mona-ui-editor.d.ts +113 -0
  95. package/types/nanahoshi-mona-ui-expansion-panel.d.ts +87 -0
  96. package/types/nanahoshi-mona-ui-fieldset.d.ts +68 -0
  97. package/types/nanahoshi-mona-ui-filter.d.ts +115 -0
  98. package/types/nanahoshi-mona-ui-grid.d.ts +1114 -0
  99. package/types/nanahoshi-mona-ui-internal-filter-input.d.ts +25 -0
  100. package/types/nanahoshi-mona-ui-internal-indicator-icon.d.ts +28 -0
  101. package/types/nanahoshi-mona-ui-internal-list.d.ts +269 -0
  102. package/types/nanahoshi-mona-ui-internal-tree.d.ts +391 -0
  103. package/types/nanahoshi-mona-ui-internal.d.ts +136 -0
  104. package/types/nanahoshi-mona-ui-list-box.d.ts +225 -0
  105. package/types/nanahoshi-mona-ui-list-view.d.ts +188 -0
  106. package/types/nanahoshi-mona-ui-list.d.ts +1 -0
  107. package/types/nanahoshi-mona-ui-menubar.d.ts +198 -0
  108. package/types/nanahoshi-mona-ui-multi-select.d.ts +247 -0
  109. package/types/nanahoshi-mona-ui-notification.d.ts +106 -0
  110. package/types/nanahoshi-mona-ui-numeric-text-box.d.ts +161 -0
  111. package/types/nanahoshi-mona-ui-pager.d.ts +238 -0
  112. package/types/nanahoshi-mona-ui-placeholder.d.ts +35 -0
  113. package/types/nanahoshi-mona-ui-popover.d.ts +130 -0
  114. package/types/nanahoshi-mona-ui-popup-menu.d.ts +412 -0
  115. package/types/nanahoshi-mona-ui-popup.d.ts +485 -0
  116. package/types/nanahoshi-mona-ui-progress-bar.d.ts +139 -0
  117. package/types/nanahoshi-mona-ui-query.d.ts +89 -0
  118. package/types/nanahoshi-mona-ui-radio-button.d.ts +128 -0
  119. package/types/nanahoshi-mona-ui-scroll-view.d.ts +166 -0
  120. package/types/nanahoshi-mona-ui-slider.d.ts +305 -0
  121. package/types/nanahoshi-mona-ui-split-button.d.ts +182 -0
  122. package/types/nanahoshi-mona-ui-splitter.d.ts +70 -0
  123. package/types/nanahoshi-mona-ui-stepper.d.ts +173 -0
  124. package/types/nanahoshi-mona-ui-switch.d.ts +125 -0
  125. package/types/nanahoshi-mona-ui-tabs.d.ts +158 -0
  126. package/types/nanahoshi-mona-ui-text-area.d.ts +42 -0
  127. package/types/nanahoshi-mona-ui-text-box.d.ts +164 -0
  128. package/types/nanahoshi-mona-ui-theme.d.ts +23 -0
  129. package/types/nanahoshi-mona-ui-time-picker.d.ts +184 -0
  130. package/types/nanahoshi-mona-ui-time-selector.d.ts +143 -0
  131. package/types/nanahoshi-mona-ui-tooltip.d.ts +130 -0
  132. package/types/nanahoshi-mona-ui-tree-view.d.ts +274 -0
  133. package/types/nanahoshi-mona-ui-window.d.ts +295 -0
  134. package/types/nanahoshi-mona-ui.d.ts +2 -0
@@ -0,0 +1,450 @@
1
+ import { CdkTrapFocus } from '@angular/cdk/a11y';
2
+ import * as i0 from '@angular/core';
3
+ import { inject, DestroyRef, ElementRef, computed, linkedSignal, signal, viewChild, output, input, model, afterNextRender, effect, untracked, forwardRef, Component } from '@angular/core';
4
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
5
+ import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
6
+ import { ButtonDirective } from '@nanahoshi/mona-ui/button';
7
+ import * as i1 from '@nanahoshi/mona-ui/dropdowns';
8
+ import { DropdownService, dropdownPopupThemeVariants, DropdownPopupInputToken, DropdownPopupHandlerDirective } from '@nanahoshi/mona-ui/dropdowns';
9
+ import { createElementControlId } from '@nanahoshi/mona-ui/internal';
10
+ import { TextBoxComponent, TextBoxSuffixTemplateDirective } from '@nanahoshi/mona-ui/text-box';
11
+ import { ThemeService } from '@nanahoshi/mona-ui/theme';
12
+ import { TimeSelectorComponent } from '@nanahoshi/mona-ui/time-selector';
13
+ import { DateTime } from 'luxon';
14
+ import { fromEvent } from 'rxjs';
15
+ import { twMerge } from 'tailwind-merge';
16
+ import { cva } from 'class-variance-authority';
17
+
18
+ const timePickerBaseVariants = cva(`
19
+ flex items-center w-full
20
+ border border-border
21
+ focus-within:ring-2 focus-within:ring-primary/40 focus-within:border-primary
22
+ data-[invalid='true']:border-error
23
+ data-[invalid='true']:ring-2 data-[invalid='true']:ring-error/40
24
+ [&_mona-text-box]:h-full
25
+ [&_mona-text-box]:border-none
26
+ `, {
27
+ variants: {
28
+ focused: {
29
+ true: `ring-2 ring-primary/40 border-primary`
30
+ },
31
+ rounded: {
32
+ full: "rounded-full",
33
+ large: "rounded-lg",
34
+ medium: "rounded-md",
35
+ none: "rounded-none",
36
+ small: "rounded-sm"
37
+ },
38
+ size: {
39
+ large: "h-10 text-md",
40
+ medium: "h-9 text-sm",
41
+ small: "h-8 text-xs"
42
+ }
43
+ }
44
+ });
45
+
46
+ const timePickerBaseThemeVariants = (theme) => {
47
+ switch (theme) {
48
+ case "mona":
49
+ return timePickerBaseVariants;
50
+ default:
51
+ return timePickerBaseVariants;
52
+ }
53
+ };
54
+
55
+ class TimePickerComponent {
56
+ #destroyRef;
57
+ #dropdownService;
58
+ #hostElementRef;
59
+ #id;
60
+ #themeService;
61
+ constructor() {
62
+ this.#destroyRef = inject(DestroyRef);
63
+ this.#dropdownService = inject(DropdownService);
64
+ this.#hostElementRef = inject(ElementRef);
65
+ this.#id = createElementControlId();
66
+ this.#themeService = inject(ThemeService);
67
+ this.baseClass = computed(() => {
68
+ const theme = this.#themeService.theme();
69
+ const focused = this.#dropdownService.popupRef() != null;
70
+ const rounded = this.rounded();
71
+ const size = this.size();
72
+ const variantClass = timePickerBaseThemeVariants(theme)({ focused, rounded, size });
73
+ const userClass = this.userClass();
74
+ return twMerge(variantClass, userClass);
75
+ }, /* @ts-ignore */
76
+ ...(ngDevMode ? [{ debugName: "baseClass" }] : /* istanbul ignore next */ []));
77
+ this.currentDateString = linkedSignal(() => {
78
+ const value = this.value();
79
+ const format = this.format();
80
+ if (!value) {
81
+ return "";
82
+ }
83
+ return DateTime.fromJSDate(value).toFormat(format);
84
+ }, /* @ts-ignore */
85
+ ...(ngDevMode ? [{ debugName: "currentDateString" }] : /* istanbul ignore next */ []));
86
+ this.expanded = computed(() => this.#dropdownService.popupRef() != null, /* @ts-ignore */
87
+ ...(ngDevMode ? [{ debugName: "expanded" }] : /* istanbul ignore next */ []));
88
+ this.inputAttributes = computed(() => {
89
+ const controls = this.popupId;
90
+ const expanded = this.#dropdownService.popupRef() != null;
91
+ const hasPopup = "dialog";
92
+ const invalid = this.invalid();
93
+ return {
94
+ "aria-autocomplete": "none",
95
+ "aria-controls": controls,
96
+ "aria-expanded": expanded,
97
+ "aria-haspopup": hasPopup,
98
+ "aria-invalid": invalid,
99
+ id: this.#id,
100
+ role: "combobox"
101
+ };
102
+ }, /* @ts-ignore */
103
+ ...(ngDevMode ? [{ debugName: "inputAttributes" }] : /* istanbul ignore next */ []));
104
+ this.invalidState = computed(() => this.invalid() || (this.required() && this.touched() && !this.value()), /* @ts-ignore */
105
+ ...(ngDevMode ? [{ debugName: "invalidState" }] : /* istanbul ignore next */ []));
106
+ this.navigatedDate = signal(new Date(), /* @ts-ignore */
107
+ ...(ngDevMode ? [{ debugName: "navigatedDate" }] : /* istanbul ignore next */ []));
108
+ this.pickerPopupClass = computed(() => {
109
+ const theme = this.#themeService.theme();
110
+ const rounded = this.rounded();
111
+ const size = this.size();
112
+ const userClass = this.popupClass();
113
+ const variantClass = dropdownPopupThemeVariants(theme)({ rounded, size });
114
+ return twMerge(variantClass, userClass);
115
+ }, /* @ts-ignore */
116
+ ...(ngDevMode ? [{ debugName: "pickerPopupClass" }] : /* istanbul ignore next */ []));
117
+ this.popupId = createElementControlId();
118
+ this.timePopupTemplateRef = viewChild.required("timePopupTemplate", /* @ts-ignore */
119
+ ...(ngDevMode ? [{ debugName: "timePopupTemplateRef" }] : /* istanbul ignore next */ []));
120
+ /**
121
+ * @description Emits when the popup is about to close. This event is preventable.
122
+ */
123
+ this.close = output();
124
+ /**
125
+ * @description Emits after the popup is closed.
126
+ */
127
+ this.closed = output();
128
+ /**
129
+ * @description Sets the disabled state of the time picker.
130
+ */
131
+ this.disabled = input(false, /* @ts-ignore */
132
+ ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
133
+ /**
134
+ * @description Sets the format of the time picker.
135
+ */
136
+ this.format = input("HH:mm", /* @ts-ignore */
137
+ ...(ngDevMode ? [{ debugName: "format" }] : /* istanbul ignore next */ []));
138
+ /**
139
+ * @description Sets the hour format of the time picker.
140
+ * @default 24
141
+ */
142
+ this.hourFormat = input("24", /* @ts-ignore */
143
+ ...(ngDevMode ? [{ debugName: "hourFormat" }] : /* istanbul ignore next */ []));
144
+ /**
145
+ * @description Sets the hour step of the time picker.
146
+ * @default 1
147
+ */
148
+ this.hourStep = input(1, /* @ts-ignore */
149
+ ...(ngDevMode ? [{ debugName: "hourStep" }] : /* istanbul ignore next */ []));
150
+ /**
151
+ * @description Marks the time picker as invalid. When bound to a signal form field via `[formField]`,
152
+ * this is written by the `FormField` directive.
153
+ * @default false
154
+ */
155
+ this.invalid = input(false, /* @ts-ignore */
156
+ ...(ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []));
157
+ /**
158
+ * @description Sets the maximum date of the time picker.
159
+ * @default null
160
+ */
161
+ this.max = input(undefined, { ...(ngDevMode ? { debugName: "max" } : /* istanbul ignore next */ {}), transform: value => (value instanceof Date ? value : undefined) });
162
+ /**
163
+ * @description Sets the minimum date of the time picker.
164
+ * @default null
165
+ */
166
+ this.min = input(undefined, { ...(ngDevMode ? { debugName: "min" } : /* istanbul ignore next */ {}), transform: value => (value instanceof Date ? value : undefined) });
167
+ /**
168
+ * @description Sets the minute step of the time picker.
169
+ * @default 1
170
+ */
171
+ this.minuteStep = input(1, /* @ts-ignore */
172
+ ...(ngDevMode ? [{ debugName: "minuteStep" }] : /* istanbul ignore next */ []));
173
+ /**
174
+ * @description Emits when the popup is about to open. This event is preventable.
175
+ */
176
+ this.open = output();
177
+ /**
178
+ * @description Emits after the popup is opened.
179
+ */
180
+ this.opened = output();
181
+ /**
182
+ * @description Sets the placeholder of the time picker.
183
+ */
184
+ this.placeholder = input("", /* @ts-ignore */
185
+ ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
186
+ /**
187
+ * @description Sets the class of the popup element.
188
+ * @default ""
189
+ */
190
+ this.popupClass = input("", /* @ts-ignore */
191
+ ...(ngDevMode ? [{ debugName: "popupClass" }] : /* istanbul ignore next */ []));
192
+ /**
193
+ * @description Sets the height of the popup element.
194
+ * @default 200
195
+ */
196
+ this.popupHeight = input(/* @ts-ignore */
197
+ ...(ngDevMode ? [undefined, { debugName: "popupHeight" }] : /* istanbul ignore next */ []));
198
+ /**
199
+ * @description Sets the width of the popup element.
200
+ * @default null
201
+ */
202
+ this.popupWidth = input(/* @ts-ignore */
203
+ ...(ngDevMode ? [undefined, { debugName: "popupWidth" }] : /* istanbul ignore next */ []));
204
+ /**
205
+ * @description Sets the readonly state of the time picker.
206
+ */
207
+ this.readonly = input(false, /* @ts-ignore */
208
+ ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
209
+ /**
210
+ * @description When true, the input is readonly but the popup button remains enabled.
211
+ * @default false
212
+ */
213
+ this.readonlyInput = input(false, /* @ts-ignore */
214
+ ...(ngDevMode ? [{ debugName: "readonlyInput" }] : /* istanbul ignore next */ []));
215
+ /**
216
+ * @description Sets the required state of the time picker.
217
+ * When bound to a signal form field via `[formField]`, this is written by the `FormField` directive.
218
+ * @default false
219
+ */
220
+ this.required = input(false, /* @ts-ignore */
221
+ ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
222
+ /**
223
+ * @description Sets the border radius of the time picker.
224
+ */
225
+ this.rounded = input("medium", /* @ts-ignore */
226
+ ...(ngDevMode ? [{ debugName: "rounded" }] : /* istanbul ignore next */ []));
227
+ /**
228
+ * @description Sets the second step of the time picker.
229
+ * @default 1
230
+ */
231
+ this.secondStep = input(1, /* @ts-ignore */
232
+ ...(ngDevMode ? [{ debugName: "secondStep" }] : /* istanbul ignore next */ []));
233
+ /**
234
+ * @description Sets the visibility of the clear button.
235
+ */
236
+ this.showClearButton = input(false, /* @ts-ignore */
237
+ ...(ngDevMode ? [{ debugName: "showClearButton" }] : /* istanbul ignore next */ []));
238
+ /**
239
+ * @description Sets the visibility of the second selector.
240
+ */
241
+ this.showSeconds = input(false, /* @ts-ignore */
242
+ ...(ngDevMode ? [{ debugName: "showSeconds" }] : /* istanbul ignore next */ []));
243
+ /**
244
+ * @description Sets the size of the time picker.
245
+ */
246
+ this.size = input("medium", /* @ts-ignore */
247
+ ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
248
+ /**
249
+ * @description Emitted when the time picker is interacted with via blur, selection, or clear.
250
+ * The `FormField` directive listens to this to mark the field as touched.
251
+ */
252
+ this.touch = output();
253
+ /**
254
+ * @description Sets the touched state of the time picker. When bound to a signal form field via `[formField]`,
255
+ * this is written by the `FormField` directive.
256
+ * @default false
257
+ */
258
+ this.touched = input(false, /* @ts-ignore */
259
+ ...(ngDevMode ? [{ debugName: "touched" }] : /* istanbul ignore next */ []));
260
+ this.userClass = input("", { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: "class" });
261
+ /**
262
+ * @description Two-way bindable current time value.
263
+ * @default null
264
+ */
265
+ this.value = model(null, /* @ts-ignore */
266
+ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
267
+ afterNextRender({
268
+ read: () => {
269
+ this.setDateValues();
270
+ this.setSubscriptions();
271
+ }
272
+ });
273
+ effect(() => {
274
+ const popupTemplate = this.timePopupTemplateRef();
275
+ untracked(() => this.#dropdownService.popupTemplate.set(popupTemplate));
276
+ });
277
+ }
278
+ onDateStringEdit(dateString) {
279
+ this.currentDateString.set(dateString);
280
+ }
281
+ onTimeInputBlur() {
282
+ if (this.#dropdownService.popupRef()) {
283
+ this.touch.emit();
284
+ return;
285
+ }
286
+ this.processTimeInput(this.currentDateString());
287
+ this.touch.emit();
288
+ }
289
+ onTimeInputButtonClick() {
290
+ if (this.disabled() || this.readonly()) {
291
+ return;
292
+ }
293
+ this.openPopup();
294
+ }
295
+ onTimeSelectorValueChange(date) {
296
+ this.setCurrentDate(date);
297
+ this.#dropdownService.popupRef()?.close();
298
+ this.focus();
299
+ }
300
+ dateStringEquals(date1, date2) {
301
+ if (date1 && date2) {
302
+ return (DateTime.fromJSDate(date1).toFormat(this.format()) ===
303
+ DateTime.fromJSDate(date2).toFormat(this.format()));
304
+ }
305
+ return date1 === date2;
306
+ }
307
+ focus() {
308
+ const input = this.#hostElementRef.nativeElement.querySelector("input");
309
+ if (input && !this.readonly()) {
310
+ input.focus();
311
+ input.setSelectionRange(input.value.length, input.value.length);
312
+ }
313
+ }
314
+ generateValidDateTime(dateString) {
315
+ const value = this.value();
316
+ const valueDate = value ? DateTime.fromJSDate(value) : DateTime.now();
317
+ let dateTime = DateTime.fromFormat(dateString, this.format());
318
+ if (dateTime.isValid) {
319
+ return dateTime.set({ year: valueDate.year, month: valueDate.month, day: valueDate.day });
320
+ }
321
+ const maxDate = this.max();
322
+ const minDate = this.min();
323
+ const date = minDate ?? maxDate;
324
+ if (date) {
325
+ const newDate = DateTime.fromJSDate(date);
326
+ dateTime = newDate.set({ year: valueDate.year, month: valueDate.month, day: valueDate.day });
327
+ return dateTime;
328
+ }
329
+ return null;
330
+ }
331
+ handleKeydown(e) {
332
+ if (this.disabled() || this.readonly()) {
333
+ return;
334
+ }
335
+ if (e.key === "ArrowDown" && e.altKey) {
336
+ e.preventDefault();
337
+ this.openPopup();
338
+ return;
339
+ }
340
+ }
341
+ openPopup() {
342
+ if (this.#dropdownService.popupRef()) {
343
+ return;
344
+ }
345
+ this.#dropdownService.triggerPopupOpen$.next({
346
+ height: this.popupHeight() || "fit-content",
347
+ width: this.popupWidth() || "auto"
348
+ });
349
+ }
350
+ processTimeInput(inputText) {
351
+ let dateTime = this.generateValidDateTime(inputText);
352
+ if (!dateTime) {
353
+ this.setCurrentDate(null);
354
+ return;
355
+ }
356
+ if (this.dateStringEquals(dateTime.toJSDate(), this.value())) {
357
+ this.setCurrentDateString(this.value());
358
+ return;
359
+ }
360
+ if (dateTime.isValid) {
361
+ this.setCurrentDate(dateTime.toJSDate());
362
+ this.navigatedDate.set(dateTime.toJSDate());
363
+ }
364
+ else {
365
+ this.setCurrentDate(null);
366
+ }
367
+ }
368
+ setCurrentDate(date) {
369
+ this.value.set(date);
370
+ this.setCurrentDateString(date);
371
+ this.touch.emit();
372
+ }
373
+ setCurrentDateString(date) {
374
+ this.updateCurrentDateString(date, this.format());
375
+ }
376
+ setDateValues() {
377
+ const value = this.value();
378
+ this.navigatedDate.set(value ?? DateTime.now().toJSDate());
379
+ if (value) {
380
+ this.updateCurrentDateString(value, this.format());
381
+ }
382
+ }
383
+ setKeyboardNavigation() {
384
+ fromEvent(this.#hostElementRef.nativeElement, "keydown")
385
+ .pipe(takeUntilDestroyed(this.#destroyRef))
386
+ .subscribe(e => this.handleKeydown(e));
387
+ }
388
+ setSubscriptions() {
389
+ this.setKeyboardNavigation();
390
+ fromEvent(this.#hostElementRef.nativeElement, "focusin")
391
+ .pipe(takeUntilDestroyed(this.#destroyRef))
392
+ .subscribe(() => this.focus());
393
+ this.#dropdownService.popupCloseComplete$
394
+ .pipe(takeUntilDestroyed(this.#destroyRef))
395
+ .subscribe(() => this.focus());
396
+ }
397
+ updateCurrentDateString(date, format) {
398
+ if (!date) {
399
+ this.currentDateString.set("");
400
+ return;
401
+ }
402
+ const dateString = DateTime.fromJSDate(date).toFormat(format);
403
+ this.currentDateString.set(dateString);
404
+ }
405
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TimePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
406
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.6", type: TimePickerComponent, isStandalone: true, selector: "mona-time-picker", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, hourFormat: { classPropertyName: "hourFormat", publicName: "hourFormat", isSignal: true, isRequired: false, transformFunction: null }, hourStep: { classPropertyName: "hourStep", publicName: "hourStep", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, minuteStep: { classPropertyName: "minuteStep", publicName: "minuteStep", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, popupClass: { classPropertyName: "popupClass", publicName: "popupClass", isSignal: true, isRequired: false, transformFunction: null }, popupHeight: { classPropertyName: "popupHeight", publicName: "popupHeight", isSignal: true, isRequired: false, transformFunction: null }, popupWidth: { classPropertyName: "popupWidth", publicName: "popupWidth", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, readonlyInput: { classPropertyName: "readonlyInput", publicName: "readonlyInput", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, secondStep: { classPropertyName: "secondStep", publicName: "secondStep", isSignal: true, isRequired: false, transformFunction: null }, showClearButton: { classPropertyName: "showClearButton", publicName: "showClearButton", isSignal: true, isRequired: false, transformFunction: null }, showSeconds: { classPropertyName: "showSeconds", publicName: "showSeconds", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { close: "close", closed: "closed", open: "open", opened: "opened", touch: "touch", value: "valueChange" }, host: { listeners: { "blur": "onTimeInputBlur()" }, properties: { "attr.tabindex": "disabled() ? null : -1", "attr.aria-invalid": "invalidState() ? 'true' : null", "attr.data-expanded": "expanded()", "attr.data-invalid": "invalidState() || null", "class": "baseClass()" } }, providers: [
407
+ DropdownService,
408
+ {
409
+ provide: DropdownPopupInputToken,
410
+ useExisting: forwardRef(() => TimePickerComponent),
411
+ multi: false
412
+ }
413
+ ], viewQueries: [{ propertyName: "timePopupTemplateRef", first: true, predicate: ["timePopupTemplate"], descendants: true, isSignal: true }], hostDirectives: [{ directive: i1.DropdownPopupHandlerDirective }], ngImport: i0, template: "<mona-text-box\r\n [disabled]=\"disabled()\"\r\n [readonly]=\"readonly() || readonlyInput()\"\r\n [required]=\"required()\"\r\n [value]=\"currentDateString()\"\r\n [inputAttributes]=\"inputAttributes()\"\r\n [invalid]=\"invalid()\"\r\n [placeholder]=\"placeholder()\"\r\n [rounded]=\"rounded()\"\r\n [size]=\"size()\"\r\n [touched]=\"touched()\"\r\n [clearButton]=\"showClearButton()\"\r\n (valueChange)=\"onDateStringEdit($event)\"\r\n (inputBlur)=\"onTimeInputBlur()\">\r\n <ng-template monaTextBoxSuffixTemplate>\r\n <button\r\n monaButton\r\n look=\"ghost\"\r\n [iconOnly]=\"true\"\r\n [size]=\"size()\"\r\n [rounded]=\"'none'\"\r\n (click)=\"onTimeInputButtonClick()\"\r\n class=\"h-full w-auto aspect-square\"\r\n [attr.aria-label]=\"'Open time picker'\"\r\n [attr.aria-expanded]=\"expanded()\"\r\n [attr.aria-controls]=\"popupId\"\r\n [disabled]=\"disabled() || readonly()\"\r\n [tabindex]=\"-1\">\r\n <i class=\"ri-time-line\"></i>\r\n </button>\r\n </ng-template>\r\n</mona-text-box>\r\n\r\n<ng-template #timePopupTemplate>\r\n <div\r\n [class]=\"pickerPopupClass()\"\r\n [id]=\"popupId\"\r\n aria-modal=\"true\"\r\n role=\"dialog\"\r\n aria-label=\"Time picker\"\r\n cdkTrapFocus>\r\n <mona-time-selector\r\n [value]=\"value()\"\r\n (valueChange)=\"onTimeSelectorValueChange($event)\"\r\n [max]=\"max()\"\r\n [min]=\"min()\"\r\n [disabled]=\"disabled()\"\r\n [readonly]=\"readonly()\"\r\n [hourFormat]=\"hourFormat()\"\r\n [hourStep]=\"hourStep()\"\r\n [minuteStep]=\"minuteStep()\"\r\n [secondStep]=\"secondStep()\"\r\n [size]=\"size()\"\r\n [rounded]=\"rounded()\"\r\n [showSeconds]=\"showSeconds()\"></mona-time-selector>\r\n </div>\r\n</ng-template>\r\n", dependencies: [{ kind: "directive", type: ButtonDirective, selector: "button[monaButton]", inputs: ["aria-haspopup", "disabled", "iconOnly", "loading", "look", "rounded", "selected", "size", "tabindex", "toggleable", "class"], outputs: ["disabledChange", "loadingChange", "lookChange", "selectedChange"] }, { kind: "ngmodule", type: FontAwesomeModule }, { kind: "component", type: TimeSelectorComponent, selector: "mona-time-selector", inputs: ["ariaLabel", "disabled", "focusOnMount", "footer", "hourFormat", "hourStep", "invalid", "max", "min", "minuteStep", "readonly", "required", "rounded", "secondStep", "showSeconds", "size", "touched", "value"], outputs: ["touch", "valueChange"] }, { kind: "component", type: TextBoxComponent, selector: "mona-text-box", inputs: ["clearButton", "disabled", "inputAttributes", "inputClass", "inputStyle", "invalid", "placeholder", "readonly", "required", "rounded", "size", "touched", "type", "class", "value"], outputs: ["inputBlur", "inputFocus", "touch", "valueChange"] }, { kind: "directive", type: TextBoxSuffixTemplateDirective, selector: "ng-template[monaTextBoxSuffixTemplate]" }, { kind: "directive", type: CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }] }); }
414
+ }
415
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TimePickerComponent, decorators: [{
416
+ type: Component,
417
+ args: [{ selector: "mona-time-picker", providers: [
418
+ DropdownService,
419
+ {
420
+ provide: DropdownPopupInputToken,
421
+ useExisting: forwardRef(() => TimePickerComponent),
422
+ multi: false
423
+ }
424
+ ], imports: [
425
+ ButtonDirective,
426
+ FontAwesomeModule,
427
+ TimeSelectorComponent,
428
+ TextBoxComponent,
429
+ TextBoxSuffixTemplateDirective,
430
+ CdkTrapFocus
431
+ ], hostDirectives: [DropdownPopupHandlerDirective], host: {
432
+ "[attr.tabindex]": "disabled() ? null : -1",
433
+ "[attr.aria-invalid]": "invalidState() ? 'true' : null",
434
+ "[attr.data-expanded]": "expanded()",
435
+ "[attr.data-invalid]": "invalidState() || null",
436
+ "[class]": "baseClass()",
437
+ "(blur)": "onTimeInputBlur()"
438
+ }, template: "<mona-text-box\r\n [disabled]=\"disabled()\"\r\n [readonly]=\"readonly() || readonlyInput()\"\r\n [required]=\"required()\"\r\n [value]=\"currentDateString()\"\r\n [inputAttributes]=\"inputAttributes()\"\r\n [invalid]=\"invalid()\"\r\n [placeholder]=\"placeholder()\"\r\n [rounded]=\"rounded()\"\r\n [size]=\"size()\"\r\n [touched]=\"touched()\"\r\n [clearButton]=\"showClearButton()\"\r\n (valueChange)=\"onDateStringEdit($event)\"\r\n (inputBlur)=\"onTimeInputBlur()\">\r\n <ng-template monaTextBoxSuffixTemplate>\r\n <button\r\n monaButton\r\n look=\"ghost\"\r\n [iconOnly]=\"true\"\r\n [size]=\"size()\"\r\n [rounded]=\"'none'\"\r\n (click)=\"onTimeInputButtonClick()\"\r\n class=\"h-full w-auto aspect-square\"\r\n [attr.aria-label]=\"'Open time picker'\"\r\n [attr.aria-expanded]=\"expanded()\"\r\n [attr.aria-controls]=\"popupId\"\r\n [disabled]=\"disabled() || readonly()\"\r\n [tabindex]=\"-1\">\r\n <i class=\"ri-time-line\"></i>\r\n </button>\r\n </ng-template>\r\n</mona-text-box>\r\n\r\n<ng-template #timePopupTemplate>\r\n <div\r\n [class]=\"pickerPopupClass()\"\r\n [id]=\"popupId\"\r\n aria-modal=\"true\"\r\n role=\"dialog\"\r\n aria-label=\"Time picker\"\r\n cdkTrapFocus>\r\n <mona-time-selector\r\n [value]=\"value()\"\r\n (valueChange)=\"onTimeSelectorValueChange($event)\"\r\n [max]=\"max()\"\r\n [min]=\"min()\"\r\n [disabled]=\"disabled()\"\r\n [readonly]=\"readonly()\"\r\n [hourFormat]=\"hourFormat()\"\r\n [hourStep]=\"hourStep()\"\r\n [minuteStep]=\"minuteStep()\"\r\n [secondStep]=\"secondStep()\"\r\n [size]=\"size()\"\r\n [rounded]=\"rounded()\"\r\n [showSeconds]=\"showSeconds()\"></mona-time-selector>\r\n </div>\r\n</ng-template>\r\n" }]
439
+ }], ctorParameters: () => [], propDecorators: { timePopupTemplateRef: [{ type: i0.ViewChild, args: ["timePopupTemplate", { isSignal: true }] }], close: [{ type: i0.Output, args: ["close"] }], closed: [{ type: i0.Output, args: ["closed"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], hourFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "hourFormat", required: false }] }], hourStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "hourStep", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], minuteStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "minuteStep", required: false }] }], open: [{ type: i0.Output, args: ["open"] }], opened: [{ type: i0.Output, args: ["opened"] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], popupClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "popupClass", required: false }] }], popupHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "popupHeight", required: false }] }], popupWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "popupWidth", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], readonlyInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonlyInput", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], secondStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondStep", required: false }] }], showClearButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showClearButton", required: false }] }], showSeconds: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSeconds", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], touch: [{ type: i0.Output, args: ["touch"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }] } });
440
+
441
+ /*
442
+ * Public API Surface of @nanahoshi/mona-ui/time-picker
443
+ */
444
+
445
+ /**
446
+ * Generated bundle index. Do not edit.
447
+ */
448
+
449
+ export { TimePickerComponent };
450
+ //# sourceMappingURL=nanahoshi-mona-ui-time-picker.mjs.map