@nanahoshi/mona-ui 0.18.5 → 0.19.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 (112) hide show
  1. package/README.md +71 -13
  2. package/fesm2022/nanahoshi-mona-ui-auto-complete.mjs +11 -3
  3. package/fesm2022/nanahoshi-mona-ui-breadcrumb.mjs +17 -9
  4. package/fesm2022/nanahoshi-mona-ui-button-group.mjs +16 -7
  5. package/fesm2022/nanahoshi-mona-ui-calendar.mjs +122 -48
  6. package/fesm2022/nanahoshi-mona-ui-card.mjs +22 -14
  7. package/fesm2022/nanahoshi-mona-ui-chart.mjs +78 -18
  8. package/fesm2022/nanahoshi-mona-ui-check-box.mjs +1 -1
  9. package/fesm2022/nanahoshi-mona-ui-chip.mjs +199 -77
  10. package/fesm2022/nanahoshi-mona-ui-circular-progress-bar.mjs +1 -2
  11. package/fesm2022/nanahoshi-mona-ui-color-gradient.mjs +23 -5
  12. package/fesm2022/nanahoshi-mona-ui-color-palette.mjs +49 -28
  13. package/fesm2022/nanahoshi-mona-ui-color-picker.mjs +42 -26
  14. package/fesm2022/nanahoshi-mona-ui-combo-box.mjs +11 -3
  15. package/fesm2022/nanahoshi-mona-ui-date-picker.mjs +28 -16
  16. package/fesm2022/nanahoshi-mona-ui-datetime-picker.mjs +74 -51
  17. package/fesm2022/nanahoshi-mona-ui-dialog.mjs +57 -25
  18. package/fesm2022/nanahoshi-mona-ui-dropdown-list.mjs +13 -5
  19. package/fesm2022/nanahoshi-mona-ui-dropdowns.mjs +17 -6
  20. package/fesm2022/nanahoshi-mona-ui-editor.mjs +178 -59
  21. package/fesm2022/nanahoshi-mona-ui-filter.mjs +137 -54
  22. package/fesm2022/{nanahoshi-mona-ui-grid-grid-footer-cell.component-WEDbZ5vy.mjs → nanahoshi-mona-ui-grid-grid-footer-cell.component-Bg7rckst.mjs} +2 -2
  23. package/fesm2022/{nanahoshi-mona-ui-grid-grid-footer-table-cell.directive-ibH5osCg.mjs → nanahoshi-mona-ui-grid-grid-footer-table-cell.directive-BSSpaCLL.mjs} +2 -2
  24. package/fesm2022/nanahoshi-mona-ui-grid-grid-list.component-D9AwQFDV.mjs +145 -0
  25. package/fesm2022/{nanahoshi-mona-ui-grid-grid-toggle.component-hc-LeIb0.mjs → nanahoshi-mona-ui-grid-grid-toggle.component-Byb9iTes.mjs} +21 -17
  26. package/fesm2022/{nanahoshi-mona-ui-grid-grid-virtual-list.component-DYajpOb9.mjs → nanahoshi-mona-ui-grid-grid-virtual-list.component-CBmdtrXm.mjs} +5 -5
  27. package/fesm2022/{nanahoshi-mona-ui-grid-nanahoshi-mona-ui-grid-Pm8Fbp6M.mjs → nanahoshi-mona-ui-grid-nanahoshi-mona-ui-grid-DPmJmCap.mjs} +90 -42
  28. package/fesm2022/nanahoshi-mona-ui-grid.mjs +1 -1
  29. package/fesm2022/nanahoshi-mona-ui-i18n.mjs +1168 -0
  30. package/fesm2022/nanahoshi-mona-ui-internal-list.mjs +12 -4
  31. package/fesm2022/nanahoshi-mona-ui-internal-tree.mjs +48 -21
  32. package/fesm2022/nanahoshi-mona-ui-list-box.mjs +33 -18
  33. package/fesm2022/nanahoshi-mona-ui-list-view.mjs +10 -10
  34. package/fesm2022/nanahoshi-mona-ui-list.mjs +2 -0
  35. package/fesm2022/nanahoshi-mona-ui-menubar.mjs +29 -16
  36. package/fesm2022/nanahoshi-mona-ui-multi-select.mjs +12 -3
  37. package/fesm2022/nanahoshi-mona-ui-notification.mjs +23 -18
  38. package/fesm2022/nanahoshi-mona-ui-numeric-text-box.mjs +211 -106
  39. package/fesm2022/nanahoshi-mona-ui-otp-input.mjs +14 -6
  40. package/fesm2022/nanahoshi-mona-ui-pager.mjs +46 -19
  41. package/fesm2022/nanahoshi-mona-ui-popup-menu.mjs +57 -46
  42. package/fesm2022/nanahoshi-mona-ui-popup.mjs +35 -15
  43. package/fesm2022/nanahoshi-mona-ui-progress-bar.mjs +38 -17
  44. package/fesm2022/nanahoshi-mona-ui-rating.mjs +25 -7
  45. package/fesm2022/nanahoshi-mona-ui-scroll-view.mjs +431 -101
  46. package/fesm2022/nanahoshi-mona-ui-segmented.mjs +1 -1
  47. package/fesm2022/nanahoshi-mona-ui-sheet.mjs +26 -8
  48. package/fesm2022/nanahoshi-mona-ui-sidebar.mjs +222 -28
  49. package/fesm2022/nanahoshi-mona-ui-slider.mjs +91 -36
  50. package/fesm2022/nanahoshi-mona-ui-spinner.mjs +34 -15
  51. package/fesm2022/nanahoshi-mona-ui-split-button.mjs +39 -23
  52. package/fesm2022/nanahoshi-mona-ui-splitter.mjs +50 -25
  53. package/fesm2022/nanahoshi-mona-ui-stepper.mjs +32 -14
  54. package/fesm2022/nanahoshi-mona-ui-switch.mjs +9 -9
  55. package/fesm2022/nanahoshi-mona-ui-tabs.mjs +74 -56
  56. package/fesm2022/nanahoshi-mona-ui-text-box.mjs +16 -8
  57. package/fesm2022/nanahoshi-mona-ui-time-picker.mjs +33 -19
  58. package/fesm2022/nanahoshi-mona-ui-time-selector.mjs +66 -27
  59. package/fesm2022/nanahoshi-mona-ui-tree-view.mjs +23 -15
  60. package/fesm2022/nanahoshi-mona-ui-window.mjs +71 -40
  61. package/i18n/package.json +4 -0
  62. package/package.json +5 -1
  63. package/types/nanahoshi-mona-ui-auto-complete.d.ts +6 -1
  64. package/types/nanahoshi-mona-ui-breadcrumb.d.ts +9 -3
  65. package/types/nanahoshi-mona-ui-button-group.d.ts +9 -3
  66. package/types/nanahoshi-mona-ui-calendar.d.ts +13 -3
  67. package/types/nanahoshi-mona-ui-card.d.ts +8 -2
  68. package/types/nanahoshi-mona-ui-chart.d.ts +10 -1
  69. package/types/nanahoshi-mona-ui-chip.d.ts +14 -5
  70. package/types/nanahoshi-mona-ui-color-gradient.d.ts +6 -1
  71. package/types/nanahoshi-mona-ui-color-palette.d.ts +21 -10
  72. package/types/nanahoshi-mona-ui-color-picker.d.ts +30 -20
  73. package/types/nanahoshi-mona-ui-combo-box.d.ts +6 -1
  74. package/types/nanahoshi-mona-ui-date-picker.d.ts +7 -2
  75. package/types/nanahoshi-mona-ui-datetime-picker.d.ts +33 -8
  76. package/types/nanahoshi-mona-ui-dialog.d.ts +16 -7
  77. package/types/nanahoshi-mona-ui-dropdown-list.d.ts +6 -1
  78. package/types/nanahoshi-mona-ui-dropdowns.d.ts +4 -1
  79. package/types/nanahoshi-mona-ui-editor.d.ts +6 -1
  80. package/types/nanahoshi-mona-ui-filter.d.ts +16 -10
  81. package/types/nanahoshi-mona-ui-grid.d.ts +38 -1
  82. package/types/nanahoshi-mona-ui-i18n.d.ts +633 -0
  83. package/types/nanahoshi-mona-ui-internal-list.d.ts +7 -2
  84. package/types/nanahoshi-mona-ui-internal-tree.d.ts +7 -3
  85. package/types/nanahoshi-mona-ui-list-box.d.ts +9 -4
  86. package/types/nanahoshi-mona-ui-list-view.d.ts +6 -6
  87. package/types/nanahoshi-mona-ui-list.d.ts +1 -1
  88. package/types/nanahoshi-mona-ui-menubar.d.ts +59 -58
  89. package/types/nanahoshi-mona-ui-multi-select.d.ts +6 -1
  90. package/types/nanahoshi-mona-ui-notification.d.ts +11 -5
  91. package/types/nanahoshi-mona-ui-numeric-text-box.d.ts +24 -15
  92. package/types/nanahoshi-mona-ui-otp-input.d.ts +9 -3
  93. package/types/nanahoshi-mona-ui-pager.d.ts +19 -6
  94. package/types/nanahoshi-mona-ui-popup.d.ts +2 -1
  95. package/types/nanahoshi-mona-ui-progress-bar.d.ts +9 -7
  96. package/types/nanahoshi-mona-ui-rating.d.ts +19 -12
  97. package/types/nanahoshi-mona-ui-scroll-view.d.ts +34 -28
  98. package/types/nanahoshi-mona-ui-sheet.d.ts +8 -2
  99. package/types/nanahoshi-mona-ui-sidebar.d.ts +3 -0
  100. package/types/nanahoshi-mona-ui-slider.d.ts +44 -26
  101. package/types/nanahoshi-mona-ui-spinner.d.ts +13 -4
  102. package/types/nanahoshi-mona-ui-split-button.d.ts +62 -56
  103. package/types/nanahoshi-mona-ui-splitter.d.ts +9 -6
  104. package/types/nanahoshi-mona-ui-stepper.d.ts +9 -3
  105. package/types/nanahoshi-mona-ui-switch.d.ts +1 -1
  106. package/types/nanahoshi-mona-ui-tabs.d.ts +96 -35
  107. package/types/nanahoshi-mona-ui-text-box.d.ts +11 -5
  108. package/types/nanahoshi-mona-ui-time-picker.d.ts +7 -2
  109. package/types/nanahoshi-mona-ui-time-selector.d.ts +16 -5
  110. package/types/nanahoshi-mona-ui-tree-view.d.ts +15 -10
  111. package/types/nanahoshi-mona-ui-window.d.ts +26 -20
  112. package/fesm2022/nanahoshi-mona-ui-grid-grid-list.component-ZM3CneJ0.mjs +0 -145
@@ -1,7 +1,7 @@
1
1
  import { FocusMonitor } from '@angular/cdk/a11y';
2
2
  import { NgTemplateOutlet } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
- import { Directive, inject, DestroyRef, ElementRef, computed, signal, contentChildren, TemplateRef, viewChild, input, output, model, afterNextRender, Component } from '@angular/core';
4
+ import { Directive, inject, DestroyRef, ElementRef, computed, signal, contentChildren, TemplateRef, viewChild, input, output, model, effect, untracked, afterNextRender, Component } from '@angular/core';
5
5
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
6
6
  import * as i1 from '@angular/forms';
7
7
  import { FormsModule } from '@angular/forms';
@@ -10,6 +10,7 @@ import { ButtonDirective } from '@nanahoshi/mona-ui/button';
10
10
  import { themeControlSurfaceClasses, rxTimeout } from '@nanahoshi/mona-ui/internal';
11
11
  import { Subject, filter, switchMap, of, tap, delay, concatMap, timer, takeUntil, distinctUntilChanged, map } from 'rxjs';
12
12
  import { twMerge } from 'tailwind-merge';
13
+ import { MonaI18nService, formatNumber, validateLocalizedNumber, validateLocalizedNumberEdit } from '@nanahoshi/mona-ui/i18n';
13
14
  import { TextBoxDirective } from '@nanahoshi/mona-ui/text-box';
14
15
  import { cva } from 'class-variance-authority';
15
16
 
@@ -25,6 +26,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
25
26
  }]
26
27
  }] });
27
28
 
29
+ const NUMERIC_TEXT_BOX_DEFAULT_MESSAGES = {
30
+ decrease: "Decrease value",
31
+ increase: "Increase value"
32
+ };
33
+
28
34
  const numericTextboxThemeVariants = cva(`
29
35
  flex w-full min-w-0 items-center
30
36
  overflow-hidden p-0
@@ -75,43 +81,33 @@ const numericTextboxInputThemeVariants = cva(`
75
81
  focus-visible:border-transparent focus-visible:ring-0
76
82
  `, {
77
83
  variants: {
78
- leftRounded: {
79
- full: `
80
- rounded-tl-full rounded-bl-full
81
- `,
82
- large: `
83
- rounded-tl-lg rounded-bl-lg
84
- `,
85
- medium: `
86
- rounded-tl-md rounded-bl-md
87
- `,
88
- none: `
89
- rounded-tl-none rounded-bl-none
90
- `,
91
- small: `
92
- rounded-tl-sm rounded-bl-sm
93
- `
84
+ startRounded: {
85
+ full: "rounded-s-full",
86
+ large: "rounded-s-lg",
87
+ medium: "rounded-s-md",
88
+ none: "rounded-s-none",
89
+ small: "rounded-s-sm"
94
90
  },
95
- rightRounded: {
91
+ endRounded: {
96
92
  full: `
97
- rounded-tr-full rounded-br-full
98
- data-[spinners='true']:rounded-tr-none data-[spinners='true']:rounded-br-none
93
+ rounded-e-full
94
+ data-[spinners='true']:rounded-e-none
99
95
  `,
100
96
  large: `
101
- rounded-tr-lg rounded-br-lg
102
- data-[spinners='true']:rounded-tr-none data-[spinners='true']:rounded-br-none
97
+ rounded-e-lg
98
+ data-[spinners='true']:rounded-e-none
103
99
  `,
104
100
  medium: `
105
- rounded-tr-md rounded-br-md
106
- data-[spinners='true']:rounded-tr-none data-[spinners='true']:rounded-br-none
101
+ rounded-e-md
102
+ data-[spinners='true']:rounded-e-none
107
103
  `,
108
104
  none: `
109
- rounded-tr-none rounded-br-none
110
- data-[spinners='true']:rounded-tr-none data-[spinners='true']:rounded-br-none
105
+ rounded-e-none
106
+ data-[spinners='true']:rounded-e-none
111
107
  `,
112
108
  small: `
113
- rounded-tr-sm rounded-br-sm
114
- data-[spinners='true']:rounded-tr-none data-[spinners='true']:rounded-br-none
109
+ rounded-e-sm
110
+ data-[spinners='true']:rounded-e-none
115
111
  `
116
112
  }
117
113
  }
@@ -123,13 +119,11 @@ const numericTextboxButtonThemeVariants = cva(`
123
119
 
124
120
  [&>button]:flex [&>button]:flex-1 [&>button]:items-center
125
121
  [&>button]:rounded-none [&>button]:p-0
126
- [&>button]:first:rounded-tl-none
127
- [&>button]:first:rounded-bl-none
128
- [&>button]:first:rounded-br-none
122
+ [&>button]:first:rounded-s-none
123
+ [&>button]:first:rounded-b-none
129
124
  [&>button]:first:h-1/2
130
- [&>button]:last:rounded-tl-none
131
- [&>button]:last:rounded-bl-none
132
- [&>button]:last:rounded-tr-none
125
+ [&>button]:last:rounded-s-none
126
+ [&>button]:last:rounded-t-none
133
127
  [&>button]:last:h-1/2
134
128
  `, {
135
129
  variants: {
@@ -145,10 +139,14 @@ class NumericTextBoxComponent {
145
139
  #destroyRef;
146
140
  #focusMonitor;
147
141
  #hostElementRef;
142
+ #i18n;
143
+ #pendingPaste;
148
144
  constructor() {
149
145
  this.#destroyRef = inject(DestroyRef);
150
146
  this.#focusMonitor = inject(FocusMonitor);
151
147
  this.#hostElementRef = inject((ElementRef));
148
+ this.#i18n = inject(MonaI18nService);
149
+ this.#pendingPaste = false;
152
150
  this.beforeInput$ = new Subject();
153
151
  this.classes = computed(() => {
154
152
  const rounded = this.rounded();
@@ -158,14 +156,6 @@ class NumericTextBoxComponent {
158
156
  return twMerge(classes, userClass);
159
157
  }, /* @ts-ignore */
160
158
  ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
161
- this.inputClasses = computed(() => {
162
- const hasPrefixTemplate = this.prefixTemplateList().length > 0;
163
- const leftRounded = hasPrefixTemplate ? "none" : this.rounded();
164
- const rightRounded = this.spinners() ? "none" : this.rounded();
165
- const inputVariants = numericTextboxInputThemeVariants({ leftRounded, rightRounded });
166
- return twMerge(inputVariants);
167
- }, /* @ts-ignore */
168
- ...(ngDevMode ? [{ debugName: "inputClasses" }] : /* istanbul ignore next */ []));
169
159
  this.focused = signal(false, /* @ts-ignore */
170
160
  ...(ngDevMode ? [{ debugName: "focused" }] : /* istanbul ignore next */ []));
171
161
  this.formattedValue = computed(() => {
@@ -175,11 +165,22 @@ class NumericTextBoxComponent {
175
165
  return this.formatValueForDisplay(this.value());
176
166
  }, /* @ts-ignore */
177
167
  ...(ngDevMode ? [{ debugName: "formattedValue" }] : /* istanbul ignore next */ []));
168
+ this.inputClasses = computed(() => {
169
+ const hasPrefixTemplate = this.prefixTemplateList().length > 0;
170
+ const startRounded = hasPrefixTemplate ? "none" : this.rounded();
171
+ const endRounded = this.spinners() ? "none" : this.rounded();
172
+ const inputVariants = numericTextboxInputThemeVariants({ endRounded, startRounded });
173
+ return twMerge(inputVariants);
174
+ }, /* @ts-ignore */
175
+ ...(ngDevMode ? [{ debugName: "inputClasses" }] : /* istanbul ignore next */ []));
178
176
  this.invalidInput = computed(() => this.touched() && (this.invalid() || (this.required() && this.value() == null)), /* @ts-ignore */
179
177
  ...(ngDevMode ? [{ debugName: "invalidInput" }] : /* istanbul ignore next */ []));
180
178
  this.keydown$ = new Subject();
179
+ this.messages = this.#i18n.componentMessages("numericTextBox", NUMERIC_TEXT_BOX_DEFAULT_MESSAGES);
180
+ this.prefixTemplateList = contentChildren(NumericTextBoxPrefixTemplateDirective, { ...(ngDevMode ? { debugName: "prefixTemplateList" } : /* istanbul ignore next */ {}), read: TemplateRef });
181
181
  this.rawInputValue = signal("", /* @ts-ignore */
182
182
  ...(ngDevMode ? [{ debugName: "rawInputValue" }] : /* istanbul ignore next */ []));
183
+ this.spin$ = new Subject();
183
184
  this.spinButtonClasses = computed(() => {
184
185
  const size = this.size();
185
186
  return numericTextboxButtonThemeVariants({ size });
@@ -190,9 +191,7 @@ class NumericTextBoxComponent {
190
191
  return size === "large" ? 20 : size === "medium" ? 16 : 14;
191
192
  }, /* @ts-ignore */
192
193
  ...(ngDevMode ? [{ debugName: "spinButtonIconSize" }] : /* istanbul ignore next */ []));
193
- this.spin$ = new Subject();
194
194
  this.spinStop$ = new Subject();
195
- this.prefixTemplateList = contentChildren(NumericTextBoxPrefixTemplateDirective, { ...(ngDevMode ? { debugName: "prefixTemplateList" } : /* istanbul ignore next */ {}), read: TemplateRef });
196
195
  this.valueChange$ = new Subject();
197
196
  this.valueTextBoxRef = viewChild.required("valueTextBox", /* @ts-ignore */
198
197
  ...(ngDevMode ? [{ debugName: "valueTextBoxRef" }] : /* istanbul ignore next */ []));
@@ -202,11 +201,17 @@ class NumericTextBoxComponent {
202
201
  */
203
202
  this.ariaLabel = input(null, { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: "aria-label" });
204
203
  /**
205
- * @description Number of decimals to show.
204
+ * @description Number of fractional decimal places to display and accept. Values are truncated to an integer
205
+ * and clamped to the range 0–20. Non-finite and negative values normalize to 0.
206
206
  * @default 0
207
207
  */
208
- this.decimals = input(0, /* @ts-ignore */
209
- ...(ngDevMode ? [{ debugName: "decimals" }] : /* istanbul ignore next */ []));
208
+ this.decimals = input(0, { ...(ngDevMode ? { debugName: "decimals" } : /* istanbul ignore next */ {}), transform: (value) => {
209
+ const num = Math.trunc(value);
210
+ if (!Number.isFinite(num) || num < 0) {
211
+ return 0;
212
+ }
213
+ return Math.min(20, num);
214
+ } });
210
215
  /**
211
216
  * @description Sets whether the input is disabled.
212
217
  */
@@ -229,6 +234,13 @@ class NumericTextBoxComponent {
229
234
  * @description Emits when the inner input element loses focus.
230
235
  */
231
236
  this.inputFocusOut = output();
237
+ /**
238
+ * @description Marks the numeric text box as invalid. When bound to a signal form field via `[formField]`,
239
+ * this is written by the `FormField` directive.
240
+ * @default false
241
+ */
242
+ this.invalid = input(false, /* @ts-ignore */
243
+ ...(ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []));
232
244
  /**
233
245
  * @description Maximum value that can be entered.
234
246
  */
@@ -254,13 +266,6 @@ class NumericTextBoxComponent {
254
266
  */
255
267
  this.required = input(false, /* @ts-ignore */
256
268
  ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
257
- /**
258
- * @description Marks the numeric text box as invalid. When bound to a signal form field via `[formField]`,
259
- * this is written by the `FormField` directive.
260
- * @default false
261
- */
262
- this.invalid = input(false, /* @ts-ignore */
263
- ...(ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []));
264
269
  /**
265
270
  * @description Sets the border radius of the input.
266
271
  */
@@ -309,6 +314,14 @@ class NumericTextBoxComponent {
309
314
  */
310
315
  this.value = model(null, /* @ts-ignore */
311
316
  ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
317
+ effect(() => {
318
+ this.#i18n.localeId();
319
+ untracked(() => {
320
+ if (this.focused() && !this.readonly()) {
321
+ this.rawInputValue.set(this.formatEditValue(this.value()));
322
+ }
323
+ });
324
+ });
312
325
  afterNextRender({
313
326
  read: () => {
314
327
  this.setSubscriptions();
@@ -321,7 +334,7 @@ class NumericTextBoxComponent {
321
334
  this.focused.set(isFocused);
322
335
  if (isFocused && !this.readonly()) {
323
336
  const currentValue = this.value();
324
- const rawValue = currentValue?.toString() ?? "";
337
+ const rawValue = this.formatEditValue(currentValue);
325
338
  this.rawInputValue.set(rawValue);
326
339
  }
327
340
  });
@@ -353,7 +366,16 @@ class NumericTextBoxComponent {
353
366
  decrease() {
354
367
  const value = this.value();
355
368
  if (value == null) {
356
- this.applyRawValue("0");
369
+ const min = this.minValue();
370
+ const max = this.maxValue();
371
+ let initial = 0;
372
+ if (min != null && initial < min) {
373
+ initial = min;
374
+ }
375
+ if (max != null && initial > max) {
376
+ initial = max;
377
+ }
378
+ this.commitNumericValue(initial);
357
379
  }
358
380
  else {
359
381
  let result = NumericTextBoxComponent.calculate(value, this.step(), "-");
@@ -361,7 +383,7 @@ class NumericTextBoxComponent {
361
383
  if (min != null && result < min) {
362
384
  result = min;
363
385
  }
364
- this.applyRawValue(result.toString());
386
+ this.commitNumericValue(result);
365
387
  }
366
388
  this.focus();
367
389
  }
@@ -374,7 +396,16 @@ class NumericTextBoxComponent {
374
396
  increase() {
375
397
  const value = this.value();
376
398
  if (value == null) {
377
- this.applyRawValue("0");
399
+ const min = this.minValue();
400
+ const max = this.maxValue();
401
+ let initial = 0;
402
+ if (min != null && initial < min) {
403
+ initial = min;
404
+ }
405
+ if (max != null && initial > max) {
406
+ initial = max;
407
+ }
408
+ this.commitNumericValue(initial);
378
409
  }
379
410
  else {
380
411
  let result = NumericTextBoxComponent.calculate(value, this.step(), "+");
@@ -382,11 +413,12 @@ class NumericTextBoxComponent {
382
413
  if (max != null && result > max) {
383
414
  result = max;
384
415
  }
385
- this.applyRawValue(result.toString());
416
+ this.commitNumericValue(result);
386
417
  }
387
418
  this.focus();
388
419
  }
389
420
  onBlur(event) {
421
+ this.#pendingPaste = false;
390
422
  const relatedTarget = event.relatedTarget;
391
423
  if (relatedTarget && this.#hostElementRef.nativeElement.contains(relatedTarget)) {
392
424
  return;
@@ -398,32 +430,56 @@ class NumericTextBoxComponent {
398
430
  this.rawInputValue.set(this.formatValueForDisplay(this.value()));
399
431
  this.inputBlur.emit(event);
400
432
  }
433
+ applyRawValue(text) {
434
+ this.rawInputValue.set(text);
435
+ this.valueChange$.next(text);
436
+ }
437
+ commitNumericValue(value) {
438
+ this.value.set(value);
439
+ this.rawInputValue.set(this.focused() && !this.readonly()
440
+ ? this.formatEditValue(value)
441
+ : this.formatValueForDisplay(value));
442
+ this.touch.emit();
443
+ }
401
444
  correctValue() {
402
445
  const value = this.value();
403
446
  const min = this.minValue();
404
447
  const max = this.maxValue();
405
448
  if (value == null) {
406
449
  if (this.nullable()) {
407
- this.applyRawValue("");
450
+ if (this.rawInputValue() !== "") {
451
+ this.rawInputValue.set("");
452
+ }
453
+ return false;
408
454
  }
409
455
  else if (min != null) {
410
- this.applyRawValue(min.toString());
456
+ this.commitNumericValue(min);
457
+ return true;
411
458
  }
412
459
  else {
413
- this.applyRawValue("0");
460
+ this.commitNumericValue(0);
461
+ return true;
414
462
  }
415
- return true;
416
463
  }
417
464
  if (min != null && value < min) {
418
- this.applyRawValue(min.toString());
465
+ this.commitNumericValue(min);
419
466
  return true;
420
467
  }
421
468
  if (max != null && value > max) {
422
- this.applyRawValue(max.toString());
469
+ this.commitNumericValue(max);
423
470
  return true;
424
471
  }
425
472
  return false;
426
473
  }
474
+ formatEditValue(value) {
475
+ if (value == null) {
476
+ return "";
477
+ }
478
+ return formatNumber(value, this.#i18n.localeId(), {
479
+ maximumFractionDigits: 20,
480
+ useGrouping: false
481
+ });
482
+ }
427
483
  formatValueForDisplay(value) {
428
484
  if (value == null) {
429
485
  return "";
@@ -433,19 +489,80 @@ class NumericTextBoxComponent {
433
489
  return formatter(value);
434
490
  }
435
491
  const decimals = this.decimals();
436
- if (decimals > 0) {
437
- return value.toFixed(decimals);
492
+ return formatNumber(value, this.#i18n.localeId(), {
493
+ minimumFractionDigits: decimals,
494
+ maximumFractionDigits: decimals,
495
+ useGrouping: false
496
+ });
497
+ }
498
+ onPaste(event) {
499
+ const pastedText = event.clipboardData?.getData("text/plain");
500
+ if (pastedText == null) {
501
+ this.#pendingPaste = false;
502
+ return;
438
503
  }
439
- return value.toString();
504
+ const inputElement = this.valueTextBoxRef()?.nativeElement;
505
+ if (!inputElement) {
506
+ this.#pendingPaste = false;
507
+ return;
508
+ }
509
+ const { value, selectionStart, selectionEnd } = inputElement;
510
+ const start = selectionStart ?? value.length;
511
+ const end = selectionEnd ?? value.length;
512
+ const proposedValue = value.slice(0, start) + pastedText + value.slice(end);
513
+ const validation = validateLocalizedNumber(proposedValue, this.#i18n.localeId(), {
514
+ mode: "locale",
515
+ decimals: this.decimals()
516
+ });
517
+ if (!validation.valid || validation.value === null) {
518
+ event.preventDefault();
519
+ this.#pendingPaste = false;
520
+ return;
521
+ }
522
+ this.#pendingPaste = true;
440
523
  }
441
- applyRawValue(text) {
442
- this.rawInputValue.set(text);
443
- this.valueChange$.next(text);
524
+ parseValue(value) {
525
+ const raw = value == null ? "" : value;
526
+ this.rawInputValue.set(raw);
527
+ const isPaste = this.#pendingPaste;
528
+ this.#pendingPaste = false;
529
+ if (isPaste) {
530
+ const validation = validateLocalizedNumber(raw, this.#i18n.localeId(), {
531
+ mode: "locale",
532
+ decimals: this.decimals()
533
+ });
534
+ return validation.valid && validation.value !== null ? validation.value : this.value();
535
+ }
536
+ if (raw === "") {
537
+ return null;
538
+ }
539
+ if (raw.trim() !== raw) {
540
+ return this.value();
541
+ }
542
+ const edit = validateLocalizedNumberEdit(raw, this.#i18n.localeId(), {
543
+ decimals: this.decimals()
544
+ });
545
+ if (edit.valid) {
546
+ return edit.value === null ? this.value() : edit.value;
547
+ }
548
+ const localeValidation = validateLocalizedNumber(raw, this.#i18n.localeId(), {
549
+ mode: "locale",
550
+ decimals: this.decimals()
551
+ });
552
+ if (localeValidation.valid && localeValidation.value !== null) {
553
+ return localeValidation.value;
554
+ }
555
+ return this.value();
444
556
  }
445
557
  setBeforeInputSubscription() {
446
558
  this.beforeInput$.pipe(takeUntilDestroyed(this.#destroyRef)).subscribe((event) => {
447
559
  const inputElement = event.target;
448
- const insertedText = event.data;
560
+ const isPaste = event.inputType === "insertFromPaste" || (this.#pendingPaste && event.inputType !== "insertText");
561
+ if (!isPaste) {
562
+ this.#pendingPaste = false;
563
+ }
564
+ const insertedText = event.data ??
565
+ event.dataTransfer?.getData("text/plain");
449
566
  if (insertedText == null) {
450
567
  return;
451
568
  }
@@ -454,27 +571,27 @@ class NumericTextBoxComponent {
454
571
  return;
455
572
  }
456
573
  const proposedValue = value.slice(0, selectionStart) + insertedText + value.slice(selectionEnd);
457
- if (proposedValue.lastIndexOf("-") > 0) {
458
- event.preventDefault();
459
- return;
460
- }
461
- if ((proposedValue.match(/\./g) || []).length > 1) {
462
- event.preventDefault();
463
- return;
464
- }
465
- if (this.decimals() === 0 && proposedValue.includes(".")) {
466
- event.preventDefault();
467
- return;
468
- }
469
- if (proposedValue.includes(".")) {
470
- const decimalPart = proposedValue.split(".")[1];
471
- if (decimalPart && decimalPart.length > this.decimals()) {
574
+ const localeId = this.#i18n.localeId();
575
+ const decimals = this.decimals();
576
+ if (isPaste) {
577
+ const validation = validateLocalizedNumber(proposedValue, localeId, {
578
+ mode: "locale",
579
+ decimals
580
+ });
581
+ if (!validation.valid || validation.value === null) {
472
582
  event.preventDefault();
473
- return;
583
+ this.#pendingPaste = false;
584
+ }
585
+ else {
586
+ this.#pendingPaste = true;
474
587
  }
588
+ return;
475
589
  }
476
- const numericRegex = new RegExp(`^-?\\d*\\.?\\d{0,${this.decimals()}}$`);
477
- if (!numericRegex.test(proposedValue)) {
590
+ this.#pendingPaste = false;
591
+ const editValidation = validateLocalizedNumberEdit(proposedValue, localeId, {
592
+ decimals
593
+ });
594
+ if (!editValidation.valid) {
478
595
  event.preventDefault();
479
596
  }
480
597
  });
@@ -531,20 +648,8 @@ class NumericTextBoxComponent {
531
648
  }
532
649
  });
533
650
  }
534
- parseValue(value) {
535
- const normalizedValue = value == null ? "" : value;
536
- this.rawInputValue.set(normalizedValue);
537
- if (normalizedValue === "" || normalizedValue === "-") {
538
- return null;
539
- }
540
- const sanitizedValue = normalizedValue.replace(/,/g, "");
541
- if (!NumericTextBoxComponent.isNumeric(sanitizedValue)) {
542
- return this.value();
543
- }
544
- return parseFloat(sanitizedValue);
545
- }
546
651
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NumericTextBoxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
547
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: NumericTextBoxComponent, isStandalone: true, selector: "mona-numeric-text-box", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, decimals: { classPropertyName: "decimals", publicName: "decimals", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, formatter: { classPropertyName: "formatter", publicName: "formatter", isSignal: true, isRequired: false, transformFunction: null }, maxValue: { classPropertyName: "maxValue", publicName: "maxValue", isSignal: true, isRequired: false, transformFunction: null }, minValue: { classPropertyName: "minValue", publicName: "minValue", isSignal: true, isRequired: false, transformFunction: null }, nullable: { classPropertyName: "nullable", publicName: "nullable", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, spinners: { classPropertyName: "spinners", publicName: "spinners", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, tabindex: { classPropertyName: "tabindex", publicName: "tabindex", 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: { inputBlur: "inputBlur", inputFocus: "inputFocus", inputFocusOut: "inputFocusOut", touch: "touch", value: "valueChange" }, host: { properties: { "class": "classes()", "attr.data-disabled": "disabled() || null", "attr.data-invalid": "invalidInput() || null", "attr.data-readonly": "readonly() || null", "attr.data-required": "required() || null" } }, queries: [{ propertyName: "prefixTemplateList", predicate: NumericTextBoxPrefixTemplateDirective, read: TemplateRef, isSignal: true }], viewQueries: [{ propertyName: "valueTextBoxRef", first: true, predicate: ["valueTextBox"], descendants: true, isSignal: true }], ngImport: i0, template: "@for (prefixTemplate of prefixTemplateList(); track $index) {\n <span class=\"flex h-full flex-none flex-wrap items-center overflow-hidden border-none\">\n <ng-container *ngTemplateOutlet=\"prefixTemplate\"></ng-container>\n </span>\n}\n<input\n monaTextBox\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n [type]=\"'text'\"\n inputmode=\"numeric\"\n [readonly]=\"readonly()\"\n [tabIndex]=\"tabindex()\"\n [ngModel]=\"formattedValue()\"\n (ngModelChange)=\"applyRawValue($event)\"\n (keydown)=\"keydown$.next($event)\"\n (focus)=\"inputFocus.emit($event)\"\n (focusout)=\"inputFocusOut.emit($event)\"\n (blur)=\"onBlur($event)\"\n (beforeinput)=\"beforeInput$.next($event)\"\n (wheel)=\"wheel$.next($event)\"\n [size]=\"size()\"\n [class]=\"inputClasses()\"\n autocomplete=\"off\"\n role=\"spinbutton\"\n [attr.aria-disabled]=\"disabled()\"\n [attr.aria-invalid]=\"invalidInput() || null\"\n [attr.aria-readonly]=\"readonly()\"\n [attr.aria-required]=\"required()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-valuenow]=\"value()\"\n [attr.aria-valuemin]=\"minValue()\"\n [attr.aria-valuemax]=\"maxValue()\"\n [attr.aria-valuetext]=\"formattedValue()\"\n [attr.data-spinners]=\"spinners()\"\n #valueTextBox />\n@if (spinners()) {\n <div [class]=\"spinButtonClasses()\">\n <button\n monaButton\n [disabled]=\"disabled()\"\n [tabindex]=\"-1\"\n look=\"ghost\"\n [size]=\"size()\"\n (mousedown)=\"$event.preventDefault()\"\n (pointerdown)=\"spin$.next('+')\"\n (pointerup)=\"spinStop$.next()\"\n (pointerleave)=\"spinStop$.next()\"\n aria-label=\"Increase value\">\n <svg lucideChevronUp [size]=\"spinButtonIconSize()\"></svg>\n </button>\n <button\n monaButton\n [disabled]=\"disabled()\"\n [tabindex]=\"-1\"\n look=\"ghost\"\n [size]=\"size()\"\n (mousedown)=\"$event.preventDefault()\"\n (pointerdown)=\"spin$.next('-')\"\n (pointerup)=\"spinStop$.next()\"\n (pointerleave)=\"spinStop$.next()\"\n aria-label=\"Decrease value\">\n <svg lucideChevronDown [size]=\"spinButtonIconSize()\"></svg>\n </button>\n </div>\n}\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: TextBoxDirective, selector: "input[monaTextBox]", inputs: ["invalid", "rounded", "size", "touched", "class"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: ButtonDirective, selector: "button[monaButton]", inputs: ["aria-haspopup", "disabled", "iconOnly", "loading", "look", "rounded", "selected", "size", "tabindex", "type", "toggleable", "class"], outputs: ["disabledChange", "loadingChange", "lookChange", "selectedChange"] }, { kind: "component", type: LucideChevronUp, selector: "svg[lucideChevronUp]" }, { kind: "component", type: LucideChevronDown, selector: "svg[lucideChevronDown]" }] }); }
652
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: NumericTextBoxComponent, isStandalone: true, selector: "mona-numeric-text-box", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, decimals: { classPropertyName: "decimals", publicName: "decimals", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, formatter: { classPropertyName: "formatter", publicName: "formatter", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, maxValue: { classPropertyName: "maxValue", publicName: "maxValue", isSignal: true, isRequired: false, transformFunction: null }, minValue: { classPropertyName: "minValue", publicName: "minValue", isSignal: true, isRequired: false, transformFunction: null }, nullable: { classPropertyName: "nullable", publicName: "nullable", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", 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 }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, spinners: { classPropertyName: "spinners", publicName: "spinners", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, tabindex: { classPropertyName: "tabindex", publicName: "tabindex", 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: { inputBlur: "inputBlur", inputFocus: "inputFocus", inputFocusOut: "inputFocusOut", touch: "touch", value: "valueChange" }, host: { properties: { "class": "classes()", "attr.data-disabled": "disabled() || null", "attr.data-invalid": "invalidInput() || null", "attr.data-readonly": "readonly() || null", "attr.data-required": "required() || null" } }, queries: [{ propertyName: "prefixTemplateList", predicate: NumericTextBoxPrefixTemplateDirective, read: TemplateRef, isSignal: true }], viewQueries: [{ propertyName: "valueTextBoxRef", first: true, predicate: ["valueTextBox"], descendants: true, isSignal: true }], ngImport: i0, template: "@for (prefixTemplate of prefixTemplateList(); track $index) {\n <span class=\"flex h-full flex-none flex-wrap items-center overflow-hidden border-none\">\n <ng-container *ngTemplateOutlet=\"prefixTemplate\"></ng-container>\n </span>\n}\n<input\n monaTextBox\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n [type]=\"'text'\"\n [attr.inputmode]=\"decimals() > 0 ? 'decimal' : 'numeric'\"\n [readonly]=\"readonly()\"\n [tabIndex]=\"tabindex()\"\n [ngModel]=\"formattedValue()\"\n (ngModelChange)=\"applyRawValue($event)\"\n (keydown)=\"keydown$.next($event)\"\n (focus)=\"inputFocus.emit($event)\"\n (focusout)=\"inputFocusOut.emit($event)\"\n (blur)=\"onBlur($event)\"\n (beforeinput)=\"beforeInput$.next($event)\"\n (paste)=\"onPaste($event)\"\n (wheel)=\"wheel$.next($event)\"\n [size]=\"size()\"\n [class]=\"inputClasses()\"\n autocomplete=\"off\"\n role=\"spinbutton\"\n [attr.aria-disabled]=\"disabled()\"\n [attr.aria-invalid]=\"invalidInput() || null\"\n [attr.aria-readonly]=\"readonly()\"\n [attr.aria-required]=\"required()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-valuenow]=\"value()\"\n [attr.aria-valuemin]=\"minValue()\"\n [attr.aria-valuemax]=\"maxValue()\"\n [attr.aria-valuetext]=\"formattedValue()\"\n [attr.data-spinners]=\"spinners()\"\n #valueTextBox />\n@if (spinners()) {\n <div [class]=\"spinButtonClasses()\">\n <button\n monaButton\n [disabled]=\"disabled()\"\n [tabindex]=\"-1\"\n look=\"ghost\"\n [size]=\"size()\"\n (mousedown)=\"$event.preventDefault()\"\n (pointerdown)=\"spin$.next('+')\"\n (pointerup)=\"spinStop$.next()\"\n (pointerleave)=\"spinStop$.next()\"\n [attr.aria-label]=\"messages().increase\">\n <svg lucideChevronUp [size]=\"spinButtonIconSize()\"></svg>\n </button>\n <button\n monaButton\n [disabled]=\"disabled()\"\n [tabindex]=\"-1\"\n look=\"ghost\"\n [size]=\"size()\"\n (mousedown)=\"$event.preventDefault()\"\n (pointerdown)=\"spin$.next('-')\"\n (pointerup)=\"spinStop$.next()\"\n (pointerleave)=\"spinStop$.next()\"\n [attr.aria-label]=\"messages().decrease\">\n <svg lucideChevronDown [size]=\"spinButtonIconSize()\"></svg>\n </button>\n </div>\n}\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: TextBoxDirective, selector: "input[monaTextBox]", inputs: ["invalid", "rounded", "size", "touched", "class"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: ButtonDirective, selector: "button[monaButton]", inputs: ["aria-haspopup", "disabled", "iconOnly", "loading", "look", "rounded", "selected", "size", "tabindex", "type", "toggleable", "class"], outputs: ["disabledChange", "loadingChange", "lookChange", "selectedChange"] }, { kind: "component", type: LucideChevronUp, selector: "svg[lucideChevronUp]" }, { kind: "component", type: LucideChevronDown, selector: "svg[lucideChevronDown]" }] }); }
548
653
  }
549
654
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NumericTextBoxComponent, decorators: [{
550
655
  type: Component,
@@ -554,10 +659,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
554
659
  "[attr.data-invalid]": "invalidInput() || null",
555
660
  "[attr.data-readonly]": "readonly() || null",
556
661
  "[attr.data-required]": "required() || null"
557
- }, template: "@for (prefixTemplate of prefixTemplateList(); track $index) {\n <span class=\"flex h-full flex-none flex-wrap items-center overflow-hidden border-none\">\n <ng-container *ngTemplateOutlet=\"prefixTemplate\"></ng-container>\n </span>\n}\n<input\n monaTextBox\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n [type]=\"'text'\"\n inputmode=\"numeric\"\n [readonly]=\"readonly()\"\n [tabIndex]=\"tabindex()\"\n [ngModel]=\"formattedValue()\"\n (ngModelChange)=\"applyRawValue($event)\"\n (keydown)=\"keydown$.next($event)\"\n (focus)=\"inputFocus.emit($event)\"\n (focusout)=\"inputFocusOut.emit($event)\"\n (blur)=\"onBlur($event)\"\n (beforeinput)=\"beforeInput$.next($event)\"\n (wheel)=\"wheel$.next($event)\"\n [size]=\"size()\"\n [class]=\"inputClasses()\"\n autocomplete=\"off\"\n role=\"spinbutton\"\n [attr.aria-disabled]=\"disabled()\"\n [attr.aria-invalid]=\"invalidInput() || null\"\n [attr.aria-readonly]=\"readonly()\"\n [attr.aria-required]=\"required()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-valuenow]=\"value()\"\n [attr.aria-valuemin]=\"minValue()\"\n [attr.aria-valuemax]=\"maxValue()\"\n [attr.aria-valuetext]=\"formattedValue()\"\n [attr.data-spinners]=\"spinners()\"\n #valueTextBox />\n@if (spinners()) {\n <div [class]=\"spinButtonClasses()\">\n <button\n monaButton\n [disabled]=\"disabled()\"\n [tabindex]=\"-1\"\n look=\"ghost\"\n [size]=\"size()\"\n (mousedown)=\"$event.preventDefault()\"\n (pointerdown)=\"spin$.next('+')\"\n (pointerup)=\"spinStop$.next()\"\n (pointerleave)=\"spinStop$.next()\"\n aria-label=\"Increase value\">\n <svg lucideChevronUp [size]=\"spinButtonIconSize()\"></svg>\n </button>\n <button\n monaButton\n [disabled]=\"disabled()\"\n [tabindex]=\"-1\"\n look=\"ghost\"\n [size]=\"size()\"\n (mousedown)=\"$event.preventDefault()\"\n (pointerdown)=\"spin$.next('-')\"\n (pointerup)=\"spinStop$.next()\"\n (pointerleave)=\"spinStop$.next()\"\n aria-label=\"Decrease value\">\n <svg lucideChevronDown [size]=\"spinButtonIconSize()\"></svg>\n </button>\n </div>\n}\n" }]
662
+ }, template: "@for (prefixTemplate of prefixTemplateList(); track $index) {\n <span class=\"flex h-full flex-none flex-wrap items-center overflow-hidden border-none\">\n <ng-container *ngTemplateOutlet=\"prefixTemplate\"></ng-container>\n </span>\n}\n<input\n monaTextBox\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n [type]=\"'text'\"\n [attr.inputmode]=\"decimals() > 0 ? 'decimal' : 'numeric'\"\n [readonly]=\"readonly()\"\n [tabIndex]=\"tabindex()\"\n [ngModel]=\"formattedValue()\"\n (ngModelChange)=\"applyRawValue($event)\"\n (keydown)=\"keydown$.next($event)\"\n (focus)=\"inputFocus.emit($event)\"\n (focusout)=\"inputFocusOut.emit($event)\"\n (blur)=\"onBlur($event)\"\n (beforeinput)=\"beforeInput$.next($event)\"\n (paste)=\"onPaste($event)\"\n (wheel)=\"wheel$.next($event)\"\n [size]=\"size()\"\n [class]=\"inputClasses()\"\n autocomplete=\"off\"\n role=\"spinbutton\"\n [attr.aria-disabled]=\"disabled()\"\n [attr.aria-invalid]=\"invalidInput() || null\"\n [attr.aria-readonly]=\"readonly()\"\n [attr.aria-required]=\"required()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-valuenow]=\"value()\"\n [attr.aria-valuemin]=\"minValue()\"\n [attr.aria-valuemax]=\"maxValue()\"\n [attr.aria-valuetext]=\"formattedValue()\"\n [attr.data-spinners]=\"spinners()\"\n #valueTextBox />\n@if (spinners()) {\n <div [class]=\"spinButtonClasses()\">\n <button\n monaButton\n [disabled]=\"disabled()\"\n [tabindex]=\"-1\"\n look=\"ghost\"\n [size]=\"size()\"\n (mousedown)=\"$event.preventDefault()\"\n (pointerdown)=\"spin$.next('+')\"\n (pointerup)=\"spinStop$.next()\"\n (pointerleave)=\"spinStop$.next()\"\n [attr.aria-label]=\"messages().increase\">\n <svg lucideChevronUp [size]=\"spinButtonIconSize()\"></svg>\n </button>\n <button\n monaButton\n [disabled]=\"disabled()\"\n [tabindex]=\"-1\"\n look=\"ghost\"\n [size]=\"size()\"\n (mousedown)=\"$event.preventDefault()\"\n (pointerdown)=\"spin$.next('-')\"\n (pointerup)=\"spinStop$.next()\"\n (pointerleave)=\"spinStop$.next()\"\n [attr.aria-label]=\"messages().decrease\">\n <svg lucideChevronDown [size]=\"spinButtonIconSize()\"></svg>\n </button>\n </div>\n}\n" }]
558
663
  }], ctorParameters: () => [], propDecorators: { prefixTemplateList: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => NumericTextBoxPrefixTemplateDirective), { ...{
559
664
  read: TemplateRef
560
- }, isSignal: true }] }], valueTextBoxRef: [{ type: i0.ViewChild, args: ["valueTextBox", { isSignal: true }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], decimals: [{ type: i0.Input, args: [{ isSignal: true, alias: "decimals", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], formatter: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatter", required: false }] }], inputBlur: [{ type: i0.Output, args: ["inputBlur"] }], inputFocus: [{ type: i0.Output, args: ["inputFocus"] }], inputFocusOut: [{ type: i0.Output, args: ["inputFocusOut"] }], maxValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxValue", required: false }] }], minValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "minValue", required: false }] }], nullable: [{ type: i0.Input, args: [{ isSignal: true, alias: "nullable", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], spinners: [{ type: i0.Input, args: [{ isSignal: true, alias: "spinners", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], tabindex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabindex", 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"] }] } });
665
+ }, isSignal: true }] }], valueTextBoxRef: [{ type: i0.ViewChild, args: ["valueTextBox", { isSignal: true }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], decimals: [{ type: i0.Input, args: [{ isSignal: true, alias: "decimals", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], formatter: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatter", required: false }] }], inputBlur: [{ type: i0.Output, args: ["inputBlur"] }], inputFocus: [{ type: i0.Output, args: ["inputFocus"] }], inputFocusOut: [{ type: i0.Output, args: ["inputFocusOut"] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], maxValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxValue", required: false }] }], minValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "minValue", required: false }] }], nullable: [{ type: i0.Input, args: [{ isSignal: true, alias: "nullable", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], spinners: [{ type: i0.Input, args: [{ isSignal: true, alias: "spinners", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], tabindex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabindex", 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"] }] } });
561
666
 
562
667
  /*
563
668
  * Public API Surface of @nanahoshi/mona-ui/numeric-text-box
@@ -567,5 +672,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
567
672
  * Generated bundle index. Do not edit.
568
673
  */
569
674
 
570
- export { NumericTextBoxComponent, NumericTextBoxPrefixTemplateDirective };
675
+ export { NUMERIC_TEXT_BOX_DEFAULT_MESSAGES, NumericTextBoxComponent, NumericTextBoxPrefixTemplateDirective };
571
676
  //# sourceMappingURL=nanahoshi-mona-ui-numeric-text-box.mjs.map