@mmlogic/components 0.5.4 → 0.5.5

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 (67) hide show
  1. package/dist/cjs/{cell-renderer-Coy-aD3k.js → cell-renderer-Mx3pwONr.js} +237 -0
  2. package/dist/cjs/loader.cjs.js +1 -1
  3. package/dist/cjs/mosterdcomponents.cjs.js +1 -1
  4. package/dist/cjs/mrd-boolean-field_25.cjs.entry.js +296 -56
  5. package/dist/cjs/mrd-merge-view.cjs.entry.js +3 -3
  6. package/dist/collection/components/fields/mrd-currency-field/mrd-currency-field.js +56 -5
  7. package/dist/collection/components/fields/mrd-date-field/mrd-date-field.css +55 -4
  8. package/dist/collection/components/fields/mrd-date-field/mrd-date-field.js +118 -8
  9. package/dist/collection/components/fields/mrd-datetime-field/mrd-datetime-field.css +55 -4
  10. package/dist/collection/components/fields/mrd-datetime-field/mrd-datetime-field.js +117 -15
  11. package/dist/collection/components/fields/mrd-email-field/mrd-email-field.js +1 -1
  12. package/dist/collection/components/fields/mrd-file-field/mrd-file-field.js +1 -1
  13. package/dist/collection/components/fields/mrd-image-field/mrd-image-field.js +1 -1
  14. package/dist/collection/components/fields/mrd-longtext-field/mrd-longtext-field.js +1 -1
  15. package/dist/collection/components/fields/mrd-number-field/mrd-number-field.js +33 -8
  16. package/dist/collection/components/fields/mrd-secret-field/mrd-secret-field.js +2 -2
  17. package/dist/collection/components/fields/mrd-text-field/mrd-text-field.js +1 -1
  18. package/dist/collection/components/fields/mrd-textarea-field/mrd-textarea-field.js +1 -1
  19. package/dist/collection/components/fields/mrd-time-field/mrd-time-field.js +1 -1
  20. package/dist/collection/components/form/mrd-field/mrd-field.js +11 -11
  21. package/dist/collection/components/invoice/mrd-invoice-view/mrd-invoice-view.js +1 -1
  22. package/dist/collection/components/layout/mrd-layout-section/mrd-layout-section.js +1 -1
  23. package/dist/collection/components/merge/mrd-merge-view/mrd-merge-view.js +2 -2
  24. package/dist/collection/dev/app.js +58 -13
  25. package/dist/collection/utils/format.js +160 -0
  26. package/dist/collection/utils/i18n.js +72 -0
  27. package/dist/components/cell-renderer.js +1 -1
  28. package/dist/components/format.js +1 -1
  29. package/dist/components/i18n.js +1 -1
  30. package/dist/components/mrd-currency-field2.js +1 -1
  31. package/dist/components/mrd-date-field2.js +1 -1
  32. package/dist/components/mrd-datetime-field2.js +1 -1
  33. package/dist/components/mrd-document-list2.js +1 -1
  34. package/dist/components/mrd-document-view2.js +1 -1
  35. package/dist/components/mrd-email-field2.js +1 -1
  36. package/dist/components/mrd-email-view2.js +1 -1
  37. package/dist/components/mrd-field2.js +1 -1
  38. package/dist/components/mrd-file-field2.js +1 -1
  39. package/dist/components/mrd-image-field2.js +1 -1
  40. package/dist/components/mrd-invoice-view2.js +1 -1
  41. package/dist/components/mrd-layout-section.js +1 -1
  42. package/dist/components/mrd-longtext-field2.js +1 -1
  43. package/dist/components/mrd-merge-view.js +1 -1
  44. package/dist/components/mrd-number-field2.js +1 -1
  45. package/dist/components/mrd-secret-field2.js +1 -1
  46. package/dist/components/mrd-table2.js +1 -1
  47. package/dist/components/mrd-text-field2.js +1 -1
  48. package/dist/components/mrd-textarea-field2.js +1 -1
  49. package/dist/components/mrd-time-field2.js +1 -1
  50. package/dist/esm/{cell-renderer-C2FLUrMN.js → cell-renderer-UQOYlDv7.js} +233 -1
  51. package/dist/esm/loader.js +1 -1
  52. package/dist/esm/mosterdcomponents.js +1 -1
  53. package/dist/esm/mrd-boolean-field_25.entry.js +296 -56
  54. package/dist/esm/mrd-merge-view.entry.js +3 -3
  55. package/dist/mosterdcomponents/mosterdcomponents.esm.js +1 -1
  56. package/dist/mosterdcomponents/p-8cc374e0.entry.js +3 -0
  57. package/dist/mosterdcomponents/p-CF--ScWr.js +1 -0
  58. package/dist/mosterdcomponents/{p-4ea5b97c.entry.js → p-d31b71d9.entry.js} +1 -1
  59. package/dist/types/components/fields/mrd-currency-field/mrd-currency-field.d.ts +13 -0
  60. package/dist/types/components/fields/mrd-date-field/mrd-date-field.d.ts +22 -1
  61. package/dist/types/components/fields/mrd-datetime-field/mrd-datetime-field.d.ts +21 -2
  62. package/dist/types/components/fields/mrd-number-field/mrd-number-field.d.ts +6 -0
  63. package/dist/types/components.d.ts +26 -0
  64. package/dist/types/utils/format.d.ts +34 -0
  65. package/package.json +1 -1
  66. package/dist/mosterdcomponents/p-8736313b.entry.js +0 -3
  67. package/dist/mosterdcomponents/p-BgsPVesg.js +0 -1
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var index = require('./index-DVbdkYO3.js');
4
- var cellRenderer = require('./cell-renderer-Coy-aD3k.js');
4
+ var cellRenderer = require('./cell-renderer-Mx3pwONr.js');
5
5
  var clientLayout = require('./client-layout-CqVuJumR.js');
6
6
 
7
7
  const mrdBooleanFieldCss = () => `.sc-mrd-boolean-field-h{display:block}.mrd-boolean-field.sc-mrd-boolean-field{display:flex;align-items:center;width:100%}.mrd-boolean-field__toggle-label.sc-mrd-boolean-field{display:flex;align-items:center;gap:var(--mrd-space-3);cursor:pointer;user-select:none}.mrd-boolean-field__checkbox.sc-mrd-boolean-field{position:absolute;opacity:0;width:0;height:0;pointer-events:none}.mrd-boolean-field__checkbox.sc-mrd-boolean-field:checked+.mrd-boolean-field__toggle.sc-mrd-boolean-field{background-color:var(--mrd-color-primary)}.mrd-boolean-field__checkbox.sc-mrd-boolean-field:checked+.mrd-boolean-field__toggle.sc-mrd-boolean-field::after{transform:translateX(20px)}.mrd-boolean-field__checkbox.sc-mrd-boolean-field:focus+.mrd-boolean-field__toggle.sc-mrd-boolean-field{box-shadow:var(--mrd-shadow-focus)}.mrd-boolean-field__checkbox.sc-mrd-boolean-field:disabled+.mrd-boolean-field__toggle.sc-mrd-boolean-field{opacity:0.5;cursor:not-allowed}.mrd-boolean-field__toggle.sc-mrd-boolean-field{position:relative;display:inline-block;width:44px;height:24px;background-color:var(--mrd-color-neutral-300);border-radius:var(--mrd-border-radius-full);transition:background-color var(--mrd-transition);flex-shrink:0}.mrd-boolean-field__toggle.sc-mrd-boolean-field::after{content:"";position:absolute;top:2px;left:2px;width:20px;height:20px;background-color:var(--mrd-color-white);border-radius:50%;transition:transform var(--mrd-transition);box-shadow:var(--mrd-shadow-sm)}.mrd-boolean-field__text.sc-mrd-boolean-field{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-color-neutral-800)}.mrd-boolean-field__text--required.sc-mrd-boolean-field::after{content:" *";color:var(--mrd-color-danger)}`;
@@ -121,13 +121,26 @@ const MrdCurrencyField = class {
121
121
  this.amountDisplay = '';
122
122
  this.currency = 'EUR';
123
123
  this.error = '';
124
+ /** While focused the user owns the text; prop updates must not overwrite it. */
125
+ this.focused = false;
124
126
  this.handleAmountInput = (e) => {
125
127
  this.amountDisplay = e.target.value;
126
128
  };
129
+ this.handleAmountFocus = () => {
130
+ this.focused = true;
131
+ // Drop the grouping separators while editing, but keep the locale's decimal
132
+ // separator: String(1234.56) would be re-read as 123456 where '.' groups.
133
+ const parsed = cellRenderer.parseLocalizedNumber(this.amountDisplay, this.locale);
134
+ if (parsed !== null) {
135
+ this.amountDisplay = cellRenderer.formatNumber(parsed, this.locale, { useGrouping: false, maximumFractionDigits: 20 });
136
+ }
137
+ };
127
138
  this.handleAmountBlur = (e) => {
139
+ this.focused = false;
128
140
  const raw = e.target.value;
129
141
  const parsed = cellRenderer.parseLocalizedNumber(raw, this.locale);
130
142
  this.error = requiredError(raw, this.required, this.locale);
143
+ this.amountDisplay = parsed !== null ? this.formatAmount(parsed) : '';
131
144
  const val = { amount: parsed, currency: this.currency };
132
145
  this.mrdChange.emit({ name: this.name, value: val });
133
146
  this.mrdBlur.emit({ name: this.name, value: val });
@@ -139,19 +152,56 @@ const MrdCurrencyField = class {
139
152
  };
140
153
  }
141
154
  componentWillLoad() {
142
- if (this.value) {
143
- this.currency = this.value.currency || 'EUR';
144
- this.amountDisplay = this.value.amount !== null ? String(this.value.amount) : '';
155
+ this.syncFromValue();
156
+ }
157
+ componentDidRender() {
158
+ // A rendered `selected` attribute is ignored once the select has an established
159
+ // value, so the currency is applied imperatively — same reason as the DROPDOWN
160
+ // preselect in mrd-relation-field. Without this an edit-mode record that loads
161
+ // after mount keeps showing EUR and would be saved back with the wrong currency.
162
+ if (this.selectEl && this.selectEl.value !== this.currency) {
163
+ this.selectEl.value = this.currency;
145
164
  }
146
165
  }
166
+ /** The record's own currency may sit outside the common list; never drop it. */
167
+ currencyOptions() {
168
+ return COMMON_CURRENCIES.includes(this.currency) ? COMMON_CURRENCIES : [this.currency, ...COMMON_CURRENCIES];
169
+ }
170
+ /** Edit mode loads the record after mount, so the incoming value must re-sync. */
171
+ valueChanged() {
172
+ if (!this.focused)
173
+ this.syncFromValue();
174
+ }
175
+ localeChanged() {
176
+ if (!this.focused)
177
+ this.syncFromValue();
178
+ }
179
+ syncFromValue() {
180
+ const value = this.value;
181
+ this.currency = (value === null || value === void 0 ? void 0 : value.currency) || 'EUR';
182
+ this.amountDisplay =
183
+ (value === null || value === void 0 ? void 0 : value.amount) !== null && (value === null || value === void 0 ? void 0 : value.amount) !== undefined ? this.formatAmount(value.amount) : '';
184
+ }
185
+ /** Display form: locale separators, always two decimals. The ISO code sits in the select. */
186
+ formatAmount(amount) {
187
+ return cellRenderer.formatNumber(amount, this.locale, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
188
+ }
147
189
  render() {
148
190
  const hasError = !!this.error;
149
- return (index.h(index.Host, { key: 'e1a76ab778820c0d781d5ec1549448716d368c1f' }, index.h("div", { key: '8298720abac7f689fe3e697c3c4410702e6a87f2', class: "mrd-currency-field" }, index.h(FieldLabel, { key: 'b23782aef9a866f1fb72e152cb91aeae00a975fa', base: "mrd-currency-field", label: this.label, required: this.required }), index.h("div", { key: '51e5177f9be3c5a6bdf3a5c1187f9261fcc349cf', class: "mrd-currency-field__row" }, index.h("input", { key: 'c6bda6cc92f3a2a34861d44b6163d417e200a6e4', class: controlClass('mrd-currency-field', hasError, 'amount'), type: "text", inputMode: "decimal", name: `${this.name}_amount`, value: this.amountDisplay, placeholder: "0.00", required: this.required, disabled: this.disabled, onInput: this.handleAmountInput, onBlur: this.handleAmountBlur }), index.h("select", { key: '29231cfa142d26aa81594609f1bf7bd5168df073', class: "mrd-currency-field__currency", disabled: this.disabled, onChange: this.handleCurrencyChange }, COMMON_CURRENCIES.map(c => (index.h("option", { key: c, value: c, selected: c === this.currency }, c))))), index.h(FieldError, { key: 'bea9615466427631f08a6ac8a779ae77695d36e3', base: "mrd-currency-field", error: this.error }))));
191
+ return (index.h(index.Host, { key: '43ef1fe660c4eaef025203544916b077975b6aa3' }, index.h("div", { key: '00b8e79182c8e2a353d57ad5c341024caf00d4ea', class: "mrd-currency-field" }, index.h(FieldLabel, { key: '96835c311e0d490864c484b818f1dcc623f488b2', base: "mrd-currency-field", label: this.label, required: this.required }), index.h("div", { key: '80317cfe562af00cc4cbf9aabf4bac2126cf6fe5', class: "mrd-currency-field__row" }, index.h("input", { key: '1983ef1e4d19e0fc529cf5e8be7d287fea36620a', class: controlClass('mrd-currency-field', hasError, 'amount'), type: "text", inputMode: "decimal", name: `${this.name}_amount`, value: this.amountDisplay, placeholder: this.formatAmount(0), required: this.required, disabled: this.disabled, onInput: this.handleAmountInput, onFocus: this.handleAmountFocus, onBlur: this.handleAmountBlur }), index.h("select", { key: 'b5fe3f03590bebaa564d76bc5fcb47c327eacece', class: "mrd-currency-field__currency", ref: el => (this.selectEl = el), disabled: this.disabled, onChange: this.handleCurrencyChange }, this.currencyOptions().map(c => (index.h("option", { key: c, value: c, selected: c === this.currency }, c))))), index.h(FieldError, { key: '1a128b26293170d4137f787622d4e89a23e62c0b', base: "mrd-currency-field", error: this.error }))));
150
192
  }
193
+ static get watchers() { return {
194
+ "value": [{
195
+ "valueChanged": 0
196
+ }],
197
+ "locale": [{
198
+ "localeChanged": 0
199
+ }]
200
+ }; }
151
201
  };
152
202
  MrdCurrencyField.style = mrdCurrencyFieldCss();
153
203
 
154
- const mrdDateFieldCss = () => `.sc-mrd-date-field-h{display:block}.mrd-date-field.sc-mrd-date-field{display:flex;flex-direction:column;gap:var(--mrd-space-1);width:100%}.mrd-date-field__label.sc-mrd-date-field{display:block;font-family:var(--mrd-font-family);font-size:var(--mrd-label-font-size);font-weight:var(--mrd-label-font-weight);color:var(--mrd-label-color)}.mrd-date-field__label--required.sc-mrd-date-field::after{content:" *";color:var(--mrd-color-danger)}.mrd-date-field__input.sc-mrd-date-field{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-input-color);background-color:var(--mrd-input-bg);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);transition:border-color var(--mrd-transition), box-shadow var(--mrd-transition);outline:none;appearance:none;box-sizing:border-box}.mrd-date-field__input.sc-mrd-date-field::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-date-field__input.sc-mrd-date-field:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-date-field__input.sc-mrd-date-field:disabled{background-color:var(--mrd-input-bg-disabled);cursor:not-allowed;opacity:0.7}.mrd-date-field__input--error.sc-mrd-date-field{border-color:var(--mrd-border-color-error)}.mrd-date-field__input--error.sc-mrd-date-field:focus{box-shadow:var(--mrd-shadow-focus-error)}.mrd-date-field__error.sc-mrd-date-field{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}.mrd-date-field__input.sc-mrd-date-field{cursor:pointer}`;
204
+ const mrdDateFieldCss = () => `.sc-mrd-date-field-h{display:block}.mrd-date-field.sc-mrd-date-field{display:flex;flex-direction:column;gap:var(--mrd-space-1);width:100%}.mrd-date-field__label.sc-mrd-date-field{display:block;font-family:var(--mrd-font-family);font-size:var(--mrd-label-font-size);font-weight:var(--mrd-label-font-weight);color:var(--mrd-label-color)}.mrd-date-field__label--required.sc-mrd-date-field::after{content:" *";color:var(--mrd-color-danger)}.mrd-date-field__control.sc-mrd-date-field{position:relative;display:block}.mrd-date-field__input.sc-mrd-date-field{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-input-color);background-color:var(--mrd-input-bg);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);transition:border-color var(--mrd-transition), box-shadow var(--mrd-transition);outline:none;appearance:none;box-sizing:border-box}.mrd-date-field__input.sc-mrd-date-field::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-date-field__input.sc-mrd-date-field:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-date-field__input.sc-mrd-date-field:disabled{background-color:var(--mrd-input-bg-disabled);cursor:not-allowed;opacity:0.7}.mrd-date-field__input--error.sc-mrd-date-field{border-color:var(--mrd-border-color-error)}.mrd-date-field__input--error.sc-mrd-date-field:focus{box-shadow:var(--mrd-shadow-focus-error)}.mrd-date-field__input.sc-mrd-date-field{padding-inline-end:calc(var(--mrd-input-padding-x) + 1.75rem)}.mrd-date-field__picker.sc-mrd-date-field{position:absolute;inset-inline-end:var(--mrd-space-1);top:50%;transform:translateY(-50%);width:1.75rem;height:1.75rem}.mrd-date-field__picker-button.sc-mrd-date-field{display:inline-flex;align-items:center;justify-content:center;width:100%;height:100%;padding:0;border:0;border-radius:var(--mrd-border-radius-sm);background:transparent;color:var(--mrd-color-neutral-500);cursor:pointer;transition:color var(--mrd-transition), background-color var(--mrd-transition)}.mrd-date-field__picker-button.sc-mrd-date-field svg.sc-mrd-date-field{width:1.125rem;height:1.125rem}.mrd-date-field__picker-button.sc-mrd-date-field:hover:not(:disabled){color:var(--mrd-color-primary);background-color:var(--mrd-color-neutral-100)}.mrd-date-field__picker-button.sc-mrd-date-field:focus-visible{outline:2px solid var(--mrd-border-color-focus);outline-offset:1px}.mrd-date-field__picker-button.sc-mrd-date-field:disabled{cursor:not-allowed;opacity:0.5}.mrd-date-field__picker-native.sc-mrd-date-field{position:absolute;inset:0;width:100%;height:100%;padding:0;border:0;opacity:0;pointer-events:none}.mrd-date-field__error.sc-mrd-date-field{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}`;
155
205
 
156
206
  const MrdDateField = class {
157
207
  constructor(hostRef) {
@@ -160,28 +210,114 @@ const MrdDateField = class {
160
210
  this.mrdBlur = index.createEvent(this, "mrdBlur");
161
211
  this.name = '';
162
212
  this.label = '';
213
+ /** ISO date, 'YYYY-MM-DD'. */
163
214
  this.value = '';
215
+ /** Overrides the locale-derived pattern placeholder (e.g. 'dd-mm-jjjj'). */
216
+ this.placeholder = '';
164
217
  this.required = false;
165
218
  this.disabled = false;
166
219
  this.locale = navigator.language;
220
+ /** What the user sees: the value formatted for `locale`, or their raw typing. */
221
+ this.displayValue = '';
167
222
  this.error = '';
168
- this.handleChange = (e) => {
169
- const val = e.target.value;
170
- this.error = requiredError(val, this.required, this.locale);
171
- this.mrdChange.emit({ name: this.name, value: val });
223
+ /** While focused the user owns the text; prop updates must not overwrite it. */
224
+ this.focused = false;
225
+ this.handleFocus = () => {
226
+ this.focused = true;
227
+ };
228
+ this.handleInput = (e) => {
229
+ this.displayValue = e.target.value;
172
230
  };
173
231
  this.handleBlur = (e) => {
174
- const val = e.target.value;
175
- this.mrdBlur.emit({ name: this.name, value: val });
232
+ this.focused = false;
233
+ const value = this.commit(e.target.value);
234
+ this.mrdChange.emit({ name: this.name, value });
235
+ this.mrdBlur.emit({ name: this.name, value });
236
+ };
237
+ this.handleKeyDown = (e) => {
238
+ // Submitting with Enter never fires blur, so commit the typed text here too.
239
+ if (e.key !== 'Enter')
240
+ return;
241
+ const value = this.commit(e.target.value);
242
+ this.mrdChange.emit({ name: this.name, value });
243
+ };
244
+ this.openPicker = () => {
245
+ const native = this.nativeInput;
246
+ if (!native || this.disabled)
247
+ return;
248
+ // The blur commit that precedes this click re-renders asynchronously, so sync by hand first.
249
+ native.value = this.currentIso();
250
+ try {
251
+ native.showPicker();
252
+ }
253
+ catch (_a) {
254
+ // Browsers without showPicker(): focusing at least surfaces the platform control.
255
+ native.focus();
256
+ }
257
+ };
258
+ this.handlePickerChange = (e) => {
259
+ const iso = e.target.value; // native inputs always yield 'YYYY-MM-DD'
260
+ this.displayValue = cellRenderer.formatIsoDate(iso, this.locale);
261
+ this.error = requiredError(iso, this.required, this.locale);
262
+ this.mrdChange.emit({ name: this.name, value: iso });
263
+ this.mrdBlur.emit({ name: this.name, value: iso });
176
264
  };
177
265
  }
266
+ componentWillLoad() {
267
+ this.displayValue = cellRenderer.formatIsoDate(this.value, this.locale);
268
+ }
269
+ valueChanged(newValue) {
270
+ if (!this.focused)
271
+ this.displayValue = cellRenderer.formatIsoDate(newValue, this.locale);
272
+ }
273
+ localeChanged() {
274
+ if (!this.focused)
275
+ this.displayValue = cellRenderer.formatIsoDate(this.value, this.locale);
276
+ }
277
+ patternPlaceholder() {
278
+ if (this.placeholder)
279
+ return this.placeholder;
280
+ return cellRenderer.localeDatePattern(this.locale, {
281
+ day: cellRenderer.t('date_token_day', this.locale),
282
+ month: cellRenderer.t('date_token_month', this.locale),
283
+ year: cellRenderer.t('date_token_year', this.locale),
284
+ });
285
+ }
286
+ /** Parse the typed text, reformat it, and emit the ISO value. */
287
+ commit(raw) {
288
+ const trimmed = raw.trim();
289
+ const iso = trimmed ? cellRenderer.parseLocalizedDate(trimmed, this.locale) : '';
290
+ if (trimmed && iso === null) {
291
+ // Keep the raw text so the user can correct it instead of retyping.
292
+ this.error = cellRenderer.t('invalid_date', this.locale);
293
+ this.displayValue = trimmed;
294
+ }
295
+ else {
296
+ this.error = requiredError(iso, this.required, this.locale);
297
+ this.displayValue = iso ? cellRenderer.formatIsoDate(iso, this.locale) : '';
298
+ }
299
+ return iso !== null && iso !== void 0 ? iso : '';
300
+ }
301
+ /** The ISO value currently shown, so the picker opens on the right date. */
302
+ currentIso() {
303
+ var _a;
304
+ return (_a = (this.displayValue ? cellRenderer.parseLocalizedDate(this.displayValue, this.locale) : '')) !== null && _a !== void 0 ? _a : '';
305
+ }
178
306
  render() {
179
- return (index.h(index.Host, { key: 'd83beef11c2b9402e251a50885b92e7a057f02ee' }, index.h("div", { key: '6a26e4969e9bde8c5c87771d7b8c7b4d6c1dd942', class: "mrd-date-field" }, index.h(FieldLabel, { key: 'a7bc1b1c56e933a51f6b1b1feb794a4678d9d334', base: "mrd-date-field", label: this.label, required: this.required }), index.h("input", { key: '82e3855654f3b3c554f80d647e783234cca8dae1', class: controlClass('mrd-date-field', !!this.error), type: "date", name: this.name, value: this.value, required: this.required, disabled: this.disabled, onChange: this.handleChange, onBlur: this.handleBlur }), index.h(FieldError, { key: '294b3cdc1004725267aa8265366f5009ab324203', base: "mrd-date-field", error: this.error }))));
307
+ return (index.h(index.Host, { key: '06ba48bd538ee4c8de4e071285535451f783c259' }, index.h("div", { key: '73ea6ea23c85fe3325bb151afb755cc11a13cf58', class: "mrd-date-field" }, index.h(FieldLabel, { key: '527848cf72323aef176fc7d5bcd47dcf2f7e46f6', base: "mrd-date-field", label: this.label, required: this.required }), index.h("div", { key: '2ff7586f4e6298d1f9b9b131106044533de82c6d', class: "mrd-date-field__control" }, index.h("input", { key: '68fdf2f1f7961ca049ab6493494c8c0707e6a4af', class: controlClass('mrd-date-field', !!this.error), type: "text", name: this.name, value: this.displayValue, placeholder: this.patternPlaceholder(), autocomplete: "off", required: this.required, disabled: this.disabled, onFocus: this.handleFocus, onInput: this.handleInput, onBlur: this.handleBlur, onKeyDown: this.handleKeyDown }), index.h("span", { key: '9557b7a3f6780b8a05030ab8e7c941c44df9f4a5', class: "mrd-date-field__picker" }, index.h("button", { key: '586973e0440ed0b74e1fa0affae9e462257024c3', type: "button", class: "mrd-date-field__picker-button", title: cellRenderer.t('open_calendar', this.locale), "aria-label": cellRenderer.t('open_calendar', this.locale), disabled: this.disabled, onClick: this.openPicker }, index.h("svg", { key: '144319d3a50d0d38c75c59dd3321d4b9097322a6', viewBox: "0 0 20 20", fill: "none", stroke: "currentColor", "stroke-width": "1.5", "aria-hidden": "true" }, index.h("rect", { key: 'aec01ca5c620bf3116705b7a28052eb3bc210cfd', x: "3", y: "4.5", width: "14", height: "12", rx: "2" }), index.h("path", { key: 'a0e13dd3a2005bfbee40f5a071b6760270d0d58d', d: "M3 8.5h14M7 2.5v3M13 2.5v3", "stroke-linecap": "round" }))), index.h("input", { key: 'be02df44f31a59a26ce166ab9a9eab9db2635d89', class: "mrd-date-field__picker-native", type: "date", ref: el => (this.nativeInput = el), value: this.currentIso(), disabled: this.disabled, tabIndex: -1, "aria-hidden": "true", onChange: this.handlePickerChange }))), index.h(FieldError, { key: '2f8b2072bee32170a35f98ec5c962018774c7e8c', base: "mrd-date-field", error: this.error }))));
180
308
  }
309
+ static get watchers() { return {
310
+ "value": [{
311
+ "valueChanged": 0
312
+ }],
313
+ "locale": [{
314
+ "localeChanged": 0
315
+ }]
316
+ }; }
181
317
  };
182
318
  MrdDateField.style = mrdDateFieldCss();
183
319
 
184
- const mrdDatetimeFieldCss = () => `.sc-mrd-datetime-field-h{display:block}.mrd-datetime-field.sc-mrd-datetime-field{display:flex;flex-direction:column;gap:var(--mrd-space-1);width:100%}.mrd-datetime-field__label.sc-mrd-datetime-field{display:block;font-family:var(--mrd-font-family);font-size:var(--mrd-label-font-size);font-weight:var(--mrd-label-font-weight);color:var(--mrd-label-color)}.mrd-datetime-field__label--required.sc-mrd-datetime-field::after{content:" *";color:var(--mrd-color-danger)}.mrd-datetime-field__input.sc-mrd-datetime-field{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-input-color);background-color:var(--mrd-input-bg);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);transition:border-color var(--mrd-transition), box-shadow var(--mrd-transition);outline:none;appearance:none;box-sizing:border-box}.mrd-datetime-field__input.sc-mrd-datetime-field::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-datetime-field__input.sc-mrd-datetime-field:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-datetime-field__input.sc-mrd-datetime-field:disabled{background-color:var(--mrd-input-bg-disabled);cursor:not-allowed;opacity:0.7}.mrd-datetime-field__input--error.sc-mrd-datetime-field{border-color:var(--mrd-border-color-error)}.mrd-datetime-field__input--error.sc-mrd-datetime-field:focus{box-shadow:var(--mrd-shadow-focus-error)}.mrd-datetime-field__error.sc-mrd-datetime-field{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}.mrd-datetime-field__input.sc-mrd-datetime-field{cursor:pointer}`;
320
+ const mrdDatetimeFieldCss = () => `.sc-mrd-datetime-field-h{display:block}.mrd-datetime-field.sc-mrd-datetime-field{display:flex;flex-direction:column;gap:var(--mrd-space-1);width:100%}.mrd-datetime-field__label.sc-mrd-datetime-field{display:block;font-family:var(--mrd-font-family);font-size:var(--mrd-label-font-size);font-weight:var(--mrd-label-font-weight);color:var(--mrd-label-color)}.mrd-datetime-field__label--required.sc-mrd-datetime-field::after{content:" *";color:var(--mrd-color-danger)}.mrd-datetime-field__control.sc-mrd-datetime-field{position:relative;display:block}.mrd-datetime-field__input.sc-mrd-datetime-field{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-input-color);background-color:var(--mrd-input-bg);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);transition:border-color var(--mrd-transition), box-shadow var(--mrd-transition);outline:none;appearance:none;box-sizing:border-box}.mrd-datetime-field__input.sc-mrd-datetime-field::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-datetime-field__input.sc-mrd-datetime-field:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-datetime-field__input.sc-mrd-datetime-field:disabled{background-color:var(--mrd-input-bg-disabled);cursor:not-allowed;opacity:0.7}.mrd-datetime-field__input--error.sc-mrd-datetime-field{border-color:var(--mrd-border-color-error)}.mrd-datetime-field__input--error.sc-mrd-datetime-field:focus{box-shadow:var(--mrd-shadow-focus-error)}.mrd-datetime-field__input.sc-mrd-datetime-field{padding-inline-end:calc(var(--mrd-input-padding-x) + 1.75rem)}.mrd-datetime-field__picker.sc-mrd-datetime-field{position:absolute;inset-inline-end:var(--mrd-space-1);top:50%;transform:translateY(-50%);width:1.75rem;height:1.75rem}.mrd-datetime-field__picker-button.sc-mrd-datetime-field{display:inline-flex;align-items:center;justify-content:center;width:100%;height:100%;padding:0;border:0;border-radius:var(--mrd-border-radius-sm);background:transparent;color:var(--mrd-color-neutral-500);cursor:pointer;transition:color var(--mrd-transition), background-color var(--mrd-transition)}.mrd-datetime-field__picker-button.sc-mrd-datetime-field svg.sc-mrd-datetime-field{width:1.125rem;height:1.125rem}.mrd-datetime-field__picker-button.sc-mrd-datetime-field:hover:not(:disabled){color:var(--mrd-color-primary);background-color:var(--mrd-color-neutral-100)}.mrd-datetime-field__picker-button.sc-mrd-datetime-field:focus-visible{outline:2px solid var(--mrd-border-color-focus);outline-offset:1px}.mrd-datetime-field__picker-button.sc-mrd-datetime-field:disabled{cursor:not-allowed;opacity:0.5}.mrd-datetime-field__picker-native.sc-mrd-datetime-field{position:absolute;inset:0;width:100%;height:100%;padding:0;border:0;opacity:0;pointer-events:none}.mrd-datetime-field__error.sc-mrd-datetime-field{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}`;
185
321
 
186
322
  const MrdDatetimeField = class {
187
323
  constructor(hostRef) {
@@ -190,30 +326,72 @@ const MrdDatetimeField = class {
190
326
  this.mrdBlur = index.createEvent(this, "mrdBlur");
191
327
  this.name = '';
192
328
  this.label = '';
329
+ /** UTC ISO string, e.g. '2026-07-06T12:30:00Z'. */
193
330
  this.value = '';
331
+ /** Overrides the locale-derived pattern placeholder (e.g. 'dd-mm-jjjj uu:mm'). */
332
+ this.placeholder = '';
194
333
  this.required = false;
195
334
  this.disabled = false;
196
335
  this.locale = navigator.language;
336
+ /** What the user sees: the value formatted for `locale`, or their raw typing. */
337
+ this.displayValue = '';
197
338
  this.error = '';
198
- this.localValue = '';
199
- this.handleChange = (e) => {
200
- const localVal = e.target.value;
201
- this.localValue = localVal;
202
- this.error = requiredError(localVal, this.required, this.locale);
203
- this.mrdChange.emit({ name: this.name, value: this.localToUtc(localVal) });
339
+ /** While focused the user owns the text; prop updates must not overwrite it. */
340
+ this.focused = false;
341
+ this.handleFocus = () => {
342
+ this.focused = true;
343
+ };
344
+ this.handleInput = (e) => {
345
+ this.displayValue = e.target.value;
204
346
  };
205
347
  this.handleBlur = (e) => {
206
- const localVal = e.target.value;
207
- this.mrdBlur.emit({ name: this.name, value: this.localToUtc(localVal) });
348
+ this.focused = false;
349
+ const value = this.commit(e.target.value);
350
+ this.mrdChange.emit({ name: this.name, value });
351
+ this.mrdBlur.emit({ name: this.name, value });
352
+ };
353
+ this.handleKeyDown = (e) => {
354
+ // Submitting with Enter never fires blur, so commit the typed text here too.
355
+ if (e.key !== 'Enter')
356
+ return;
357
+ const value = this.commit(e.target.value);
358
+ this.mrdChange.emit({ name: this.name, value });
359
+ };
360
+ this.openPicker = () => {
361
+ const native = this.nativeInput;
362
+ if (!native || this.disabled)
363
+ return;
364
+ // The blur commit that precedes this click re-renders asynchronously, so sync by hand first.
365
+ native.value = this.currentLocal();
366
+ try {
367
+ native.showPicker();
368
+ }
369
+ catch (_a) {
370
+ // Browsers without showPicker(): focusing at least surfaces the platform control.
371
+ native.focus();
372
+ }
373
+ };
374
+ this.handlePickerChange = (e) => {
375
+ const local = e.target.value; // native inputs always yield 'YYYY-MM-DDTHH:mm'
376
+ this.displayValue = cellRenderer.formatLocalDateTime(local, this.locale);
377
+ this.error = requiredError(local, this.required, this.locale);
378
+ const value = this.localToUtc(local);
379
+ this.mrdChange.emit({ name: this.name, value });
380
+ this.mrdBlur.emit({ name: this.name, value });
208
381
  };
209
382
  }
210
383
  componentWillLoad() {
211
- this.localValue = this.utcToLocal(this.value);
384
+ this.displayValue = this.toDisplay(this.value);
212
385
  }
213
386
  valueChanged(newVal) {
214
- this.localValue = this.utcToLocal(newVal);
387
+ if (!this.focused)
388
+ this.displayValue = this.toDisplay(newVal);
389
+ }
390
+ localeChanged() {
391
+ if (!this.focused)
392
+ this.displayValue = this.toDisplay(this.value);
215
393
  }
216
- // UTC ISO string → "YYYY-MM-DDTHH:mm" in local timezone (for datetime-local input)
394
+ // UTC ISO string → "YYYY-MM-DDTHH:mm" in local timezone
217
395
  utcToLocal(utcStr) {
218
396
  if (!utcStr)
219
397
  return '';
@@ -232,12 +410,50 @@ const MrdDatetimeField = class {
232
410
  return '';
233
411
  return d.toISOString().replace(/\.\d{3}Z$/, 'Z');
234
412
  }
413
+ // UTC ISO string → locale-formatted text for the input
414
+ toDisplay(utcStr) {
415
+ return cellRenderer.formatLocalDateTime(this.utcToLocal(utcStr), this.locale);
416
+ }
417
+ patternPlaceholder() {
418
+ if (this.placeholder)
419
+ return this.placeholder;
420
+ return cellRenderer.localeDatePattern(this.locale, {
421
+ day: cellRenderer.t('date_token_day', this.locale),
422
+ month: cellRenderer.t('date_token_month', this.locale),
423
+ year: cellRenderer.t('date_token_year', this.locale),
424
+ hour: cellRenderer.t('time_token_hour', this.locale),
425
+ minute: cellRenderer.t('time_token_minute', this.locale),
426
+ });
427
+ }
428
+ /** Parse the typed text, reformat it, and return the UTC value to emit. */
429
+ commit(raw) {
430
+ const trimmed = raw.trim();
431
+ const local = trimmed ? cellRenderer.parseLocalizedDateTime(trimmed, this.locale) : '';
432
+ if (trimmed && local === null) {
433
+ // Keep the raw text so the user can correct it instead of retyping.
434
+ this.error = cellRenderer.t('invalid_datetime', this.locale);
435
+ this.displayValue = trimmed;
436
+ return '';
437
+ }
438
+ const localValue = local !== null && local !== void 0 ? local : '';
439
+ this.error = requiredError(localValue, this.required, this.locale);
440
+ this.displayValue = localValue ? cellRenderer.formatLocalDateTime(localValue, this.locale) : '';
441
+ return this.localToUtc(localValue);
442
+ }
443
+ /** The local 'YYYY-MM-DDTHH:mm' currently shown, so the picker opens on the right moment. */
444
+ currentLocal() {
445
+ var _a;
446
+ return (_a = (this.displayValue ? cellRenderer.parseLocalizedDateTime(this.displayValue, this.locale) : '')) !== null && _a !== void 0 ? _a : '';
447
+ }
235
448
  render() {
236
- return (index.h(index.Host, { key: '6f8020590ac879992058aa9547b90c11250fa303' }, index.h("div", { key: '76abff48cae58d156540181a6577729a449bb888', class: "mrd-datetime-field" }, index.h(FieldLabel, { key: 'a8c3688980347a27d6467987f11a3c4135ac5234', base: "mrd-datetime-field", label: this.label, required: this.required }), index.h("input", { key: '1bb1aa7536a6a82313f51240030c828028cafd76', class: controlClass('mrd-datetime-field', !!this.error), type: "datetime-local", name: this.name, value: this.localValue, required: this.required, disabled: this.disabled, onChange: this.handleChange, onBlur: this.handleBlur }), index.h(FieldError, { key: 'c97301640980bf04311751124fc8e87023d59f87', base: "mrd-datetime-field", error: this.error }))));
449
+ return (index.h(index.Host, { key: 'e075e65c76a627a8f19db488c07704e2b1a7270b' }, index.h("div", { key: 'a6b5a5df3168272f1f775933dfc372e1b2ccbd95', class: "mrd-datetime-field" }, index.h(FieldLabel, { key: '39e232c066b8c354eeda7df9bcba4e3f95c18ee5', base: "mrd-datetime-field", label: this.label, required: this.required }), index.h("div", { key: '4ffac4089cbb9e5506aa0854c8b1f15862bc8456', class: "mrd-datetime-field__control" }, index.h("input", { key: 'd33400133173c7f3e8b045339f44fbeba7f0b35a', class: controlClass('mrd-datetime-field', !!this.error), type: "text", name: this.name, value: this.displayValue, placeholder: this.patternPlaceholder(), autocomplete: "off", required: this.required, disabled: this.disabled, onFocus: this.handleFocus, onInput: this.handleInput, onBlur: this.handleBlur, onKeyDown: this.handleKeyDown }), index.h("span", { key: '54d8d3b1f508d6226d1341d87c1fec19d5914a10', class: "mrd-datetime-field__picker" }, index.h("button", { key: '27cd3977984eedd9e3471dd039fc73798f1c7abc', type: "button", class: "mrd-datetime-field__picker-button", title: cellRenderer.t('open_calendar', this.locale), "aria-label": cellRenderer.t('open_calendar', this.locale), disabled: this.disabled, onClick: this.openPicker }, index.h("svg", { key: '634ca817fa001263933795e35e1a215a06da7a77', viewBox: "0 0 20 20", fill: "none", stroke: "currentColor", "stroke-width": "1.5", "aria-hidden": "true" }, index.h("rect", { key: '66eadf6b2cfee53376f6ea0f50dbd2ec04fc5663', x: "3", y: "4.5", width: "14", height: "12", rx: "2" }), index.h("path", { key: '4bb61793e0501bd18bb16c4e203b20f509692970', d: "M3 8.5h14M7 2.5v3M13 2.5v3", "stroke-linecap": "round" }))), index.h("input", { key: '8877da44e4dc527e7c05244359a0caf9d2e81fdd', class: "mrd-datetime-field__picker-native", type: "datetime-local", ref: el => (this.nativeInput = el), value: this.currentLocal(), disabled: this.disabled, tabIndex: -1, "aria-hidden": "true", onChange: this.handlePickerChange }))), index.h(FieldError, { key: '4ee97180614972c4dd334d68873a9fb7f91e48f5', base: "mrd-datetime-field", error: this.error }))));
237
450
  }
238
451
  static get watchers() { return {
239
452
  "value": [{
240
453
  "valueChanged": 0
454
+ }],
455
+ "locale": [{
456
+ "localeChanged": 0
241
457
  }]
242
458
  }; }
243
459
  };
@@ -1461,7 +1677,7 @@ const MrdEmailField = class {
1461
1677
  };
1462
1678
  }
1463
1679
  render() {
1464
- return (index.h(index.Host, { key: '3253124dadc7f0b3f120c11f8c35604a2f671b0a' }, index.h("div", { key: 'db820652452145c30f21b41a65942c0a4c6f45f1', class: "mrd-email-field" }, index.h(FieldLabel, { key: '8b1c5a84afce9fd18c3f644e5c92f07363e116d4', base: "mrd-email-field", label: this.label, required: this.required }), index.h("input", { key: 'dc4bada3208aa6cb7585b1872f53605177371493', class: controlClass('mrd-email-field', !!this.error), type: "email", name: this.name, value: this.value, placeholder: this.placeholder || 'name@example.com', required: this.required, disabled: this.disabled, onInput: this.handleInput, onBlur: this.handleBlur }), index.h(FieldError, { key: 'c44377d1b6a4a4c468b080b23eecd4ba9ca326e1', base: "mrd-email-field", error: this.error }))));
1680
+ return (index.h(index.Host, { key: 'e185145e628e3a23dd338d93dd8e42bf11569728' }, index.h("div", { key: '7d77dd982543a8add5fa1f47aa7985cc15079080', class: "mrd-email-field" }, index.h(FieldLabel, { key: '14eb00a535a052ebe3cb2793cc7dfc05168c402b', base: "mrd-email-field", label: this.label, required: this.required }), index.h("input", { key: '11fb9856144f7da30a054b4433350d80d316de64', class: controlClass('mrd-email-field', !!this.error), type: "email", name: this.name, value: this.value, placeholder: this.placeholder || 'name@example.com', required: this.required, disabled: this.disabled, onInput: this.handleInput, onBlur: this.handleBlur }), index.h(FieldError, { key: 'be33c0a43cd99a7152c1d10b7067ea5e52834742', base: "mrd-email-field", error: this.error }))));
1465
1681
  }
1466
1682
  };
1467
1683
  MrdEmailField.style = mrdEmailFieldCss();
@@ -4094,7 +4310,7 @@ const MrdField = class {
4094
4310
  return (index.h("div", { class: "mrd-field__history-editor" }, this.historyEntries.length > 0 && (index.h("span", { class: "mrd-field__history-editor-label" }, cellRenderer.t('history_badge_tooltip', locale))), this.historyEntries.map((entry, i) => (index.h("div", { key: String(i), class: "mrd-field__history-editor-row" }, index.h("input", { class: "mrd-field__history-editor-value", type: valueType, value: entry.value, onInput: (e) => updateEntry(i, 'value', e.target.value) }), index.h("span", { class: "mrd-field__history-editor-sep" }, cellRenderer.t('history_until', locale)), index.h("input", { class: "mrd-field__history-editor-until", type: "date", value: entry.until, onInput: (e) => updateEntry(i, 'until', e.target.value) }), index.h("button", { type: "button", class: "mrd-field__history-editor-remove", onClick: () => removeEntry(i), "aria-label": cellRenderer.t('remove', locale) }, index.h("svg", { viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true" }, index.h("path", { "fill-rule": "evenodd", d: "M8.75 1A2.75 2.75 0 006 3.75v.443c-.795.077-1.584.176-2.365.298a.75.75 0 10.23 1.482l.149-.022.841 10.518A2.75 2.75 0 007.596 19h4.807a2.75 2.75 0 002.742-2.53l.841-10.52.149.023a.75.75 0 00.23-1.482A41.03 41.03 0 0014 4.193V3.75A2.75 2.75 0 0011.25 1h-2.5zM10 4c.84 0 1.673.025 2.5.075V3.75c0-.69-.56-1.25-1.25-1.25h-2.5c-.69 0-1.25.56-1.25 1.25v.325C8.327 4.025 9.16 4 10 4zM8.58 7.72a.75.75 0 00-1.5.06l.3 7.5a.75.75 0 101.5-.06l-.3-7.5zm4.34.06a.75.75 0 10-1.5-.06l-.3 7.5a.75.75 0 101.5.06l.3-7.5z", "clip-rule": "evenodd" })))))), index.h("button", { type: "button", class: "mrd-field__history-editor-add", onClick: addEntry }, "+ ", cellRenderer.t('add', locale))));
4095
4311
  }
4096
4312
  renderLeafField(displayValue) {
4097
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6;
4313
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8;
4098
4314
  const { item, locale } = this;
4099
4315
  const commonProps = {
4100
4316
  name: item.name,
@@ -4119,25 +4335,25 @@ const MrdField = class {
4119
4335
  case clientLayout.ClientLayoutItemFieldDataType.BOOLEAN:
4120
4336
  return (index.h("mrd-boolean-field", Object.assign({}, commonProps, { value: (_l = displayValue) !== null && _l !== void 0 ? _l : false })));
4121
4337
  case clientLayout.ClientLayoutItemFieldDataType.DATE:
4122
- return (index.h("mrd-date-field", Object.assign({}, commonProps, { value: (_m = displayValue) !== null && _m !== void 0 ? _m : '' })));
4338
+ return (index.h("mrd-date-field", Object.assign({}, commonProps, { value: (_m = displayValue) !== null && _m !== void 0 ? _m : '', placeholder: (_o = item.placeholder) !== null && _o !== void 0 ? _o : '' })));
4123
4339
  case clientLayout.ClientLayoutItemFieldDataType.DATETIME:
4124
- return (index.h("mrd-datetime-field", Object.assign({}, commonProps, { value: (_o = displayValue) !== null && _o !== void 0 ? _o : '' })));
4340
+ return (index.h("mrd-datetime-field", Object.assign({}, commonProps, { value: (_p = displayValue) !== null && _p !== void 0 ? _p : '', placeholder: (_q = item.placeholder) !== null && _q !== void 0 ? _q : '' })));
4125
4341
  case clientLayout.ClientLayoutItemFieldDataType.TIME:
4126
- return (index.h("mrd-time-field", Object.assign({}, commonProps, { value: (_p = displayValue) !== null && _p !== void 0 ? _p : '' })));
4342
+ return (index.h("mrd-time-field", Object.assign({}, commonProps, { value: (_r = displayValue) !== null && _r !== void 0 ? _r : '' })));
4127
4343
  case clientLayout.ClientLayoutItemFieldDataType.EMAIL:
4128
- return (index.h("mrd-email-field", Object.assign({}, commonProps, { value: (_q = displayValue) !== null && _q !== void 0 ? _q : '', placeholder: (_r = item.placeholder) !== null && _r !== void 0 ? _r : '' })));
4344
+ return (index.h("mrd-email-field", Object.assign({}, commonProps, { value: (_s = displayValue) !== null && _s !== void 0 ? _s : '', placeholder: (_t = item.placeholder) !== null && _t !== void 0 ? _t : '' })));
4129
4345
  case clientLayout.ClientLayoutItemFieldDataType.HYPERLINK:
4130
- return (index.h("mrd-hyperlink-field", Object.assign({}, commonProps, { value: (_s = displayValue) !== null && _s !== void 0 ? _s : '', placeholder: (_t = item.placeholder) !== null && _t !== void 0 ? _t : '' })));
4346
+ return (index.h("mrd-hyperlink-field", Object.assign({}, commonProps, { value: (_u = displayValue) !== null && _u !== void 0 ? _u : '', placeholder: (_v = item.placeholder) !== null && _v !== void 0 ? _v : '' })));
4131
4347
  case clientLayout.ClientLayoutItemFieldDataType.LIST:
4132
- return (index.h("mrd-list-field", Object.assign({}, commonProps, { value: (_u = displayValue) !== null && _u !== void 0 ? _u : '', multiple: (_v = item.multiple) !== null && _v !== void 0 ? _v : false, listItems: (_w = item.listItems) !== null && _w !== void 0 ? _w : [] })));
4348
+ return (index.h("mrd-list-field", Object.assign({}, commonProps, { value: (_w = displayValue) !== null && _w !== void 0 ? _w : '', multiple: (_x = item.multiple) !== null && _x !== void 0 ? _x : false, listItems: (_y = item.listItems) !== null && _y !== void 0 ? _y : [] })));
4133
4349
  case clientLayout.ClientLayoutItemFieldDataType.FILE:
4134
- return (index.h("mrd-file-field", Object.assign({}, commonProps, { value: displayValue, accept: (_x = item.accept) !== null && _x !== void 0 ? _x : '', maxSize: (_y = item.maxSize) !== null && _y !== void 0 ? _y : 0, multiple: (_z = item.multiple) !== null && _z !== void 0 ? _z : false, onMrdUpload: this.handleUpload })));
4350
+ return (index.h("mrd-file-field", Object.assign({}, commonProps, { value: displayValue, accept: (_z = item.accept) !== null && _z !== void 0 ? _z : '', maxSize: (_0 = item.maxSize) !== null && _0 !== void 0 ? _0 : 0, multiple: (_1 = item.multiple) !== null && _1 !== void 0 ? _1 : false, onMrdUpload: this.handleUpload })));
4135
4351
  case clientLayout.ClientLayoutItemFieldDataType.IMAGE:
4136
- return (index.h("mrd-image-field", Object.assign({}, commonProps, { value: displayValue, accept: (_0 = item.accept) !== null && _0 !== void 0 ? _0 : 'image/*', maxSize: (_1 = item.maxSize) !== null && _1 !== void 0 ? _1 : 0, multiple: (_2 = item.multiple) !== null && _2 !== void 0 ? _2 : false, onMrdUpload: this.handleUpload })));
4352
+ return (index.h("mrd-image-field", Object.assign({}, commonProps, { value: displayValue, accept: (_2 = item.accept) !== null && _2 !== void 0 ? _2 : 'image/*', maxSize: (_3 = item.maxSize) !== null && _3 !== void 0 ? _3 : 0, multiple: (_4 = item.multiple) !== null && _4 !== void 0 ? _4 : false, onMrdUpload: this.handleUpload })));
4137
4353
  case clientLayout.ClientLayoutItemFieldDataType.LONGTEXT:
4138
- return (index.h("mrd-longtext-field", Object.assign({}, commonProps, { value: (_3 = displayValue) !== null && _3 !== void 0 ? _3 : '', placeholder: (_4 = item.placeholder) !== null && _4 !== void 0 ? _4 : '' })));
4354
+ return (index.h("mrd-longtext-field", Object.assign({}, commonProps, { value: (_5 = displayValue) !== null && _5 !== void 0 ? _5 : '', placeholder: (_6 = item.placeholder) !== null && _6 !== void 0 ? _6 : '' })));
4139
4355
  case clientLayout.ClientLayoutItemFieldDataType.SECRET:
4140
- return (index.h("mrd-secret-field", Object.assign({}, commonProps, { value: (_5 = displayValue) !== null && _5 !== void 0 ? _5 : '', placeholder: (_6 = item.placeholder) !== null && _6 !== void 0 ? _6 : '' })));
4356
+ return (index.h("mrd-secret-field", Object.assign({}, commonProps, { value: (_7 = displayValue) !== null && _7 !== void 0 ? _7 : '', placeholder: (_8 = item.placeholder) !== null && _8 !== void 0 ? _8 : '' })));
4141
4357
  default:
4142
4358
  return null;
4143
4359
  }
@@ -4333,7 +4549,7 @@ const MrdFileField = class {
4333
4549
  error: hasError,
4334
4550
  disabled: this.disabled || this.zoneBusy,
4335
4551
  });
4336
- return (index.h(index.Host, { key: '2e740a0857b069740a6a13616d0a0dfee2b945be' }, index.h("div", { key: '069b25ced3b2f1ce547819086dadbd53ade2378c', class: "mrd-file-field" }, index.h(FieldLabel, { key: 'd13f3cb0af766d6328772dab865b2079c85ec075', base: "mrd-file-field", label: this.label, required: this.required }), index.h("div", { key: '9ffdbb508e3934854034c46e6f719a88d4175920', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.drag.onDragOver, onDragLeave: this.drag.onDragLeave, onDrop: this.drag.onDrop }, index.h("input", { key: 'c5d6954b8fa050889b5b65e15fde229dd64d7cc7', ref: el => (this.fileInputRef = el), class: "mrd-file-field__input", type: "file", name: this.name, accept: this.accept, multiple: this.multiple, disabled: this.disabled || this.zoneBusy, required: this.required && !hasEntries, onChange: this.handleInputChange }), hasEntries && !this.multiple ? (index.h("div", { class: "mrd-file-field__selected" }, this.renderEntry(this.entries[0], 0))) : (index.h("div", { class: "mrd-file-field__prompt" }, index.h("svg", { class: "mrd-file-field__upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, index.h("polyline", { points: "16 16 12 12 8 16" }), index.h("line", { x1: "12", y1: "12", x2: "12", y2: "21" }), index.h("path", { d: "M20.39 18.39A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.3" })), index.h("span", null, cellRenderer.t('drop_file_here', this.locale), ' ', index.h("span", { class: "mrd-file-field__browse" }, cellRenderer.t('browse', this.locale)))))), this.multiple && hasEntries && (index.h("ul", { key: '910a3e89f74d93ab16fb9f677a4276d5ad88897d', class: "mrd-file-field__list" }, this.entries.map((entry, index$1) => (index.h("li", { class: "mrd-file-field__item", key: `${index$1}-${entryLabel(entry)}` }, this.renderEntry(entry, index$1)))))), index.h(FieldError, { key: '4f0f071b0a1460ea1d6067a8fa4f588ebc620f2a', base: "mrd-file-field", error: this.error }))));
4552
+ return (index.h(index.Host, { key: '36f9660fd297e7b2e7b2ac1816f4dcbc70d5cfcb' }, index.h("div", { key: 'a33534d3fedae04bad0eefc9d2d297ea148c5784', class: "mrd-file-field" }, index.h(FieldLabel, { key: '833f8ff178ec259c8066ddf542bdd1930bac486f', base: "mrd-file-field", label: this.label, required: this.required }), index.h("div", { key: 'd3bd00b25329b8cc716c5fcc526919d8f2c14bce', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.drag.onDragOver, onDragLeave: this.drag.onDragLeave, onDrop: this.drag.onDrop }, index.h("input", { key: '4b98ee338e8a5e4e6f94e5b5614ca88c90f802ee', ref: el => (this.fileInputRef = el), class: "mrd-file-field__input", type: "file", name: this.name, accept: this.accept, multiple: this.multiple, disabled: this.disabled || this.zoneBusy, required: this.required && !hasEntries, onChange: this.handleInputChange }), hasEntries && !this.multiple ? (index.h("div", { class: "mrd-file-field__selected" }, this.renderEntry(this.entries[0], 0))) : (index.h("div", { class: "mrd-file-field__prompt" }, index.h("svg", { class: "mrd-file-field__upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, index.h("polyline", { points: "16 16 12 12 8 16" }), index.h("line", { x1: "12", y1: "12", x2: "12", y2: "21" }), index.h("path", { d: "M20.39 18.39A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.3" })), index.h("span", null, cellRenderer.t('drop_file_here', this.locale), ' ', index.h("span", { class: "mrd-file-field__browse" }, cellRenderer.t('browse', this.locale)))))), this.multiple && hasEntries && (index.h("ul", { key: '6e6e1d62738d0a824eb86e0dbb01b63a0227580d', class: "mrd-file-field__list" }, this.entries.map((entry, index$1) => (index.h("li", { class: "mrd-file-field__item", key: `${index$1}-${entryLabel(entry)}` }, this.renderEntry(entry, index$1)))))), index.h(FieldError, { key: 'df6427015d3f813a72e8998f9fa6152f6caef90e', base: "mrd-file-field", error: this.error }))));
4337
4553
  }
4338
4554
  static get watchers() { return {
4339
4555
  "value": [{
@@ -4961,7 +5177,7 @@ const MrdImageField = class {
4961
5177
  error: hasError,
4962
5178
  disabled: this.disabled || this.zoneBusy,
4963
5179
  });
4964
- return (index.h(index.Host, { key: '51d39ea80195565a5dc780ff6a7923a976cfb0a7' }, index.h("div", { key: 'd76edb7ac9f1efea8c7c3d5b04e906ad4ab4c761', class: "mrd-image-field" }, index.h(FieldLabel, { key: 'b46a67a76188047677c40ce3f406daed7d8de141', base: "mrd-image-field", label: this.label, required: this.required }), index.h("div", { key: '0156a9722ea48d84e3ea1a829e4266425a594a6a', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.drag.onDragOver, onDragLeave: this.drag.onDragLeave, onDrop: this.drag.onDrop }, index.h("input", { key: '1b8e41da71bb57254bfd2e5527b05e1aeb32eb2f', ref: el => (this.fileInputRef = el), class: "mrd-image-field__input", type: "file", name: this.name, accept: this.accept, multiple: this.multiple, disabled: this.disabled || this.zoneBusy, required: this.required && !hasEntries, onChange: this.handleInputChange }), hasEntries && !this.multiple ? (this.renderSingle(this.entries[0])) : (index.h("div", { class: "mrd-image-field__prompt" }, index.h("svg", { class: "mrd-image-field__upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, index.h("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }), index.h("circle", { cx: "8.5", cy: "8.5", r: "1.5" }), index.h("polyline", { points: "21 15 16 10 5 21" })), index.h("span", null, cellRenderer.t('drop_file_here', this.locale), ' ', index.h("span", { class: "mrd-image-field__browse" }, cellRenderer.t('browse', this.locale)))))), this.multiple && hasEntries && (index.h("ul", { key: '9211b5212eae0629f7c9b2b49d80e2b658a9ddd3', class: "mrd-image-field__grid" }, this.entries.map((entry, index) => this.renderGridItem(entry, index)))), index.h(FieldError, { key: '5f49c03156ed18e7c8307adff679b149658ca4a6', base: "mrd-image-field", error: this.error }))));
5180
+ return (index.h(index.Host, { key: '5009b2db845c8f85f395c7230e2d5c464c56ea14' }, index.h("div", { key: 'fcae7821876ee3d71aac576cdea44c3c4f169890', class: "mrd-image-field" }, index.h(FieldLabel, { key: '834638e3f7b2073508d98b6dd5ecb437b0bb52ad', base: "mrd-image-field", label: this.label, required: this.required }), index.h("div", { key: '50e9bdaa1ebb3ec87f36e0d37dc6c2f8dc79848d', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.drag.onDragOver, onDragLeave: this.drag.onDragLeave, onDrop: this.drag.onDrop }, index.h("input", { key: '38e115fae5b3e2c3371857d284fbd54ea23812df', ref: el => (this.fileInputRef = el), class: "mrd-image-field__input", type: "file", name: this.name, accept: this.accept, multiple: this.multiple, disabled: this.disabled || this.zoneBusy, required: this.required && !hasEntries, onChange: this.handleInputChange }), hasEntries && !this.multiple ? (this.renderSingle(this.entries[0])) : (index.h("div", { class: "mrd-image-field__prompt" }, index.h("svg", { class: "mrd-image-field__upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, index.h("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }), index.h("circle", { cx: "8.5", cy: "8.5", r: "1.5" }), index.h("polyline", { points: "21 15 16 10 5 21" })), index.h("span", null, cellRenderer.t('drop_file_here', this.locale), ' ', index.h("span", { class: "mrd-image-field__browse" }, cellRenderer.t('browse', this.locale)))))), this.multiple && hasEntries && (index.h("ul", { key: '67bad2f2142f78d7f25b8f35819b6adba48ea597', class: "mrd-image-field__grid" }, this.entries.map((entry, index) => this.renderGridItem(entry, index)))), index.h(FieldError, { key: 'ef07863946f0b4c94aa30b97d0ecb9616303e793', base: "mrd-image-field", error: this.error }))));
4965
5181
  }
4966
5182
  static get watchers() { return {
4967
5183
  "value": [{
@@ -5066,7 +5282,7 @@ const MrdInvoiceView = class {
5066
5282
  const invoiceDateRaw = this.slotValue('invoiceDate');
5067
5283
  const dueDateRaw = this.slotValue('dueDate');
5068
5284
  const hasLines = !!((_b = (_a = this.archetype) === null || _a === void 0 ? void 0 : _a.slots) === null || _b === void 0 ? void 0 : _b['lines']);
5069
- return (index.h(index.Host, { key: 'a97c51e53e39ace913c902ad2ba6813eb85e4561' }, index.h("div", { key: '6938267848bceed5b28b56c3cdd6d6693e57cdbf', class: "mrd-invoice-view" }, index.h("div", { key: '7a0b3346232abfc1e35805e4e92c19d35698f881', class: "mrd-invoice-view__header" }, index.h("div", { key: '5c0471dd8ebd94dd9b374897268c7c03bec66ec7', class: "mrd-invoice-view__title-row" }, invoiceNumber && index.h("h1", { key: '86b4c0ebd0a5b83ae03b731b7e41394645aae954', class: "mrd-invoice-view__title" }, cellRenderer.t('invoice_title', this.locale), " ", invoiceNumber), this.renderStatus()), index.h("div", { key: 'd209bc34d989146b5f510f2bcdc4c484d723378c', class: "mrd-invoice-view__dates" }, invoiceDateRaw != null && invoiceDateRaw !== '' && (index.h("span", { key: '8fffcd1ab10e511c9d939c351ea93e4d8a902688' }, cellRenderer.t('invoice_date', this.locale), ": ", cellRenderer.formatDate(invoiceDateRaw, this.locale))), dueDateRaw != null && dueDateRaw !== '' && (index.h("span", { key: '8d13c6660798108cc2f54137c8415173326d5bf2' }, cellRenderer.t('invoice_due_date', this.locale), ": ", cellRenderer.formatDate(dueDateRaw, this.locale)))), this.renderContainer()), index.h("div", { key: 'cb08c6fd7e6b46a46a69f11aafa960ab5cb35544', class: "mrd-invoice-view__parties" }, this.renderPartyLink('customer', cellRenderer.t('invoice_customer', this.locale)), this.renderPartyLink('supplier', cellRenderer.t('invoice_supplier', this.locale))), hasLines && (index.h("div", { key: '8321e74171fe933a4e10fc202b66cd3720ba959e', class: "mrd-invoice-view__lines" }, index.h("slot", { key: 'eb31d97080173413e74e5b0024984a4b06aa5bdd', name: "lines" }))), this.renderAmounts(), this.renderAttachments())));
5285
+ return (index.h(index.Host, { key: '8005640e6d13004ae2fdf5f48129214fbc8c55fc' }, index.h("div", { key: '992f925691e2455c8888df76f93176cec5866210', class: "mrd-invoice-view" }, index.h("div", { key: 'aa418658cfe830be4e0f8bf77af42a898c9170db', class: "mrd-invoice-view__header" }, index.h("div", { key: 'ce10fef2072c26a0eb8f7ead620cb460af6646f0', class: "mrd-invoice-view__title-row" }, invoiceNumber && index.h("h1", { key: '992486cd5dc0bfb9761bdc94bcd237e6bd6e3d24', class: "mrd-invoice-view__title" }, cellRenderer.t('invoice_title', this.locale), " ", invoiceNumber), this.renderStatus()), index.h("div", { key: 'a8c5d2516b737d4dcd5d0f966aadcda4d47a63ad', class: "mrd-invoice-view__dates" }, invoiceDateRaw != null && invoiceDateRaw !== '' && (index.h("span", { key: 'dd728929fc408c280ad81e212bdfac5905cda02d' }, cellRenderer.t('invoice_date', this.locale), ": ", cellRenderer.formatDate(invoiceDateRaw, this.locale))), dueDateRaw != null && dueDateRaw !== '' && (index.h("span", { key: 'd4226d5cc37f0152950f44a3b63a88f0454919bd' }, cellRenderer.t('invoice_due_date', this.locale), ": ", cellRenderer.formatDate(dueDateRaw, this.locale)))), this.renderContainer()), index.h("div", { key: 'c40b00c852d005963be7b5006e13804e72ba032a', class: "mrd-invoice-view__parties" }, this.renderPartyLink('customer', cellRenderer.t('invoice_customer', this.locale)), this.renderPartyLink('supplier', cellRenderer.t('invoice_supplier', this.locale))), hasLines && (index.h("div", { key: '000e991c64daa582194631b2eac6b1acba418e97', class: "mrd-invoice-view__lines" }, index.h("slot", { key: '97ba2acb750137eeb5ed6b5e9e5d277f638d4f0a', name: "lines" }))), this.renderAmounts(), this.renderAttachments())));
5070
5286
  }
5071
5287
  static get watchers() { return {
5072
5288
  "data": [{
@@ -5594,7 +5810,7 @@ const MrdLayoutSection = class {
5594
5810
  const docArchetype = clientLayout.resolveArchetype(this.archetypes, clientLayout.ARCHETYPE_DOCUMENT);
5595
5811
  const invoiceArchetype = !docArchetype ? clientLayout.resolveArchetype(this.archetypes, clientLayout.ARCHETYPE_INVOICE) : undefined;
5596
5812
  const emailArchetype = !docArchetype && !invoiceArchetype ? clientLayout.resolveArchetype(this.archetypes, clientLayout.ARCHETYPE_EMAIL) : undefined;
5597
- return (index.h(index.Host, { key: 'ccae8e82b4dd549ab24239fe685a6830a508061d' }, index.h("div", { key: '4072cc4ecdd2b087c54a5515e653f7f713b2150f', class: "mrd-layout-section" }, docArchetype && this.renderDocumentObject(docArchetype), invoiceArchetype && this.renderInvoiceObject(invoiceArchetype), emailArchetype && this.renderEmailObject(emailArchetype), !docArchetype && !invoiceArchetype && !emailArchetype && this.items.map(item => this.renderItem(item))), this.renderImageModal()));
5813
+ return (index.h(index.Host, { key: '8c4e0a0e71d777295010702584b4aa8f7817cafb' }, index.h("div", { key: 'fe021021eba48acad3d52ee4849ebe355e83c348', class: "mrd-layout-section" }, docArchetype && this.renderDocumentObject(docArchetype), invoiceArchetype && this.renderInvoiceObject(invoiceArchetype), emailArchetype && this.renderEmailObject(emailArchetype), !docArchetype && !invoiceArchetype && !emailArchetype && this.items.map(item => this.renderItem(item))), this.renderImageModal()));
5598
5814
  }
5599
5815
  get el() { return index.getElement(this); }
5600
5816
  static get watchers() { return {
@@ -5713,7 +5929,7 @@ const MrdLongtextField = class {
5713
5929
  };
5714
5930
  }
5715
5931
  render() {
5716
- return (index.h(index.Host, { key: 'e53fec4d4eafbd68d9cffb1f064d8e0c4c37839c' }, index.h("div", { key: '8843a23e42b0545c269fc6c924e7ae295770064e', class: "mrd-longtext-field" }, index.h(FieldLabel, { key: '8767676dd35f25f9bf5ebdb26887edc0882582e0', base: "mrd-longtext-field", label: this.label, required: this.required }), this.disabled ? (index.h("pre", { class: "mrd-longtext-field__content" }, this.value)) : (index.h("textarea", { class: controlClass('mrd-longtext-field', !!this.error), name: this.name, placeholder: this.placeholder, required: this.required, rows: 10, onInput: this.handleInput, onBlur: this.handleBlur }, this.value)), index.h(FieldError, { key: '54dc790173575e8a02764e5b14040b900c2eb609', base: "mrd-longtext-field", error: this.error }))));
5932
+ return (index.h(index.Host, { key: 'a43ce67cb05e96853193e56c175d99e51d07cbab' }, index.h("div", { key: 'eb7d09bcae010736dd17b5f17bcb1cb32a6b1c4e', class: "mrd-longtext-field" }, index.h(FieldLabel, { key: 'd3a47993cc977c06b845eda4575b93d238eaf15a', base: "mrd-longtext-field", label: this.label, required: this.required }), this.disabled ? (index.h("pre", { class: "mrd-longtext-field__content" }, this.value)) : (index.h("textarea", { class: controlClass('mrd-longtext-field', !!this.error), name: this.name, placeholder: this.placeholder, required: this.required, rows: 10, onInput: this.handleInput, onBlur: this.handleBlur }, this.value)), index.h(FieldError, { key: '89f801af61fc0b874db44dbfca6eb33ffe285a84', base: "mrd-longtext-field", error: this.error }))));
5717
5933
  }
5718
5934
  };
5719
5935
  MrdLongtextField.style = mrdLongtextFieldCss();
@@ -5736,10 +5952,13 @@ const MrdNumberField = class {
5736
5952
  this.decimalPrecision = 2;
5737
5953
  this.displayValue = '';
5738
5954
  this.error = '';
5955
+ /** While focused the user owns the text; prop updates must not overwrite it. */
5956
+ this.focused = false;
5739
5957
  this.handleInput = (e) => {
5740
5958
  this.displayValue = e.target.value;
5741
5959
  };
5742
5960
  this.handleBlur = (e) => {
5961
+ this.focused = false;
5743
5962
  const raw = e.target.value;
5744
5963
  const parsed = cellRenderer.parseLocalizedNumber(raw, this.locale);
5745
5964
  if (this.required && (parsed === null || raw === '')) {
@@ -5758,17 +5977,30 @@ const MrdNumberField = class {
5758
5977
  this.mrdBlur.emit({ name: this.name, value: parsed });
5759
5978
  };
5760
5979
  this.handleFocus = () => {
5761
- // Show raw number on focus
5762
- if (this.value !== null && this.value !== undefined) {
5763
- const str = String(this.value);
5764
- this.displayValue = str;
5980
+ this.focused = true;
5981
+ // Drop the grouping separators while editing, but keep the locale's decimal
5982
+ // separator: String(1234.56) would be re-read as 123456 where '.' groups.
5983
+ const parsed = cellRenderer.parseLocalizedNumber(this.displayValue, this.locale);
5984
+ if (parsed !== null) {
5985
+ this.displayValue = cellRenderer.formatNumber(parsed, this.locale, { useGrouping: false, maximumFractionDigits: 20 });
5765
5986
  }
5766
5987
  };
5767
5988
  }
5768
5989
  componentWillLoad() {
5769
- if (this.value !== null && this.value !== undefined) {
5770
- this.displayValue = this.formatForDisplay(this.value);
5771
- }
5990
+ this.syncFromValue();
5991
+ }
5992
+ /** Edit mode loads the record after mount, so the incoming value must re-sync. */
5993
+ valueChanged() {
5994
+ if (!this.focused)
5995
+ this.syncFromValue();
5996
+ }
5997
+ localeChanged() {
5998
+ if (!this.focused)
5999
+ this.syncFromValue();
6000
+ }
6001
+ syncFromValue() {
6002
+ this.displayValue =
6003
+ this.value !== null && this.value !== undefined ? this.formatForDisplay(this.value) : '';
5772
6004
  }
5773
6005
  formatForDisplay(val) {
5774
6006
  if (this.dataType === clientLayout.ClientLayoutItemFieldDataType.PERCENTAGE) {
@@ -5789,8 +6021,16 @@ const MrdNumberField = class {
5789
6021
  const hasError = !!this.error;
5790
6022
  const suffix = this.dataType === clientLayout.ClientLayoutItemFieldDataType.PERCENTAGE ? '%' :
5791
6023
  this.dataType === clientLayout.ClientLayoutItemFieldDataType.DECIMAL ? '' : '';
5792
- return (index.h(index.Host, { key: '5df5c2e16c85cd54944d95b7a8c340ae1a4ddb34' }, index.h("div", { key: 'e332bd0190d537c002b14090fa96ec6502e34746', class: "mrd-number-field" }, index.h(FieldLabel, { key: 'e26ae85ef6c6d7935b2d34041a7ee2294da392a4', base: "mrd-number-field", label: this.label, required: this.required }), index.h("div", { key: 'fb1a44a363a36b69124a0092e80b67d41b538c03', class: "mrd-number-field__input-wrapper" }, index.h("input", { key: '175c448177bbd46015fc7f47b98b76e16ee3b743', class: controlClass('mrd-number-field', hasError), type: "text", inputMode: "decimal", name: this.name, value: this.displayValue, placeholder: this.placeholder || (suffix ? `0${suffix}` : '0'), required: this.required, disabled: this.disabled, onInput: this.handleInput, onBlur: this.handleBlur, onFocus: this.handleFocus })), index.h(FieldError, { key: 'ecb16ddf655e563f0569e774ab2f2e419f60b0f1', base: "mrd-number-field", error: this.error }))));
6024
+ return (index.h(index.Host, { key: 'bd5eb25cf7b97ef2ddb67a6bc6d6d96c9bff7510' }, index.h("div", { key: '68b15887a045f743a7f177e7a178146a9f4e0400', class: "mrd-number-field" }, index.h(FieldLabel, { key: '72e88a34a390e36ee11f5840d87dedd9d4d7fb12', base: "mrd-number-field", label: this.label, required: this.required }), index.h("div", { key: 'd97dae69eedf4c0ed1c872065754327dbffb5ba7', class: "mrd-number-field__input-wrapper" }, index.h("input", { key: '5767f6c34a08f503a1a157390c679382c857ff01', class: controlClass('mrd-number-field', hasError), type: "text", inputMode: "decimal", name: this.name, value: this.displayValue, placeholder: this.placeholder || (suffix ? `0${suffix}` : '0'), required: this.required, disabled: this.disabled, onInput: this.handleInput, onBlur: this.handleBlur, onFocus: this.handleFocus })), index.h(FieldError, { key: '1d4f8ffd3fcdf2ae2e8eb1eb68c051619d66c954', base: "mrd-number-field", error: this.error }))));
5793
6025
  }
6026
+ static get watchers() { return {
6027
+ "value": [{
6028
+ "valueChanged": 0
6029
+ }],
6030
+ "locale": [{
6031
+ "localeChanged": 0
6032
+ }]
6033
+ }; }
5794
6034
  };
5795
6035
  MrdNumberField.style = mrdNumberFieldCss();
5796
6036
 
@@ -6077,9 +6317,9 @@ const MrdSecretField = class {
6077
6317
  };
6078
6318
  }
6079
6319
  render() {
6080
- return (index.h(index.Host, { key: 'e06d04fdae34b42441976e21605fe94ad935382e' }, index.h("div", { key: '2889e1eb1b6d0887ae531523a0b9b43c49ef6f99', class: "mrd-secret-field" }, index.h(FieldLabel, { key: 'c40907905292cdef8bb0b8b9b0c03e05650bef37', base: "mrd-secret-field", label: this.label, required: this.required }), this.disabled
6320
+ return (index.h(index.Host, { key: 'd3d204242898c1f258b088e7b5428421cde8d7a7' }, index.h("div", { key: '11d284625cdd1e0def58cc31eab9bbe59346649d', class: "mrd-secret-field" }, index.h(FieldLabel, { key: '333e5b23d2379125a393f555b936be7bc521fdb4', base: "mrd-secret-field", label: this.label, required: this.required }), this.disabled
6081
6321
  ? (index.h("span", { class: "mrd-secret-field__masked", "aria-label": this.label }, this.value ? '••••••••' : ''))
6082
- : (index.h("input", { class: controlClass('mrd-secret-field', !!this.error), type: "password", name: this.name, value: this.value, placeholder: this.placeholder, required: this.required, autocomplete: "new-password", onInput: this.handleInput, onBlur: this.handleBlur })), index.h(FieldError, { key: '6353e4b40566852dbc1994c7c9c409d0d0aa1b37', base: "mrd-secret-field", error: this.error }))));
6322
+ : (index.h("input", { class: controlClass('mrd-secret-field', !!this.error), type: "password", name: this.name, value: this.value, placeholder: this.placeholder, required: this.required, autocomplete: "new-password", onInput: this.handleInput, onBlur: this.handleBlur })), index.h(FieldError, { key: 'cc202197fdab62da7b5083e078e69efd86e673ca', base: "mrd-secret-field", error: this.error }))));
6083
6323
  }
6084
6324
  };
6085
6325
  MrdSecretField.style = mrdSecretFieldCss();
@@ -7407,7 +7647,7 @@ const MrdTextField = class {
7407
7647
  };
7408
7648
  }
7409
7649
  render() {
7410
- return (index.h(index.Host, { key: '3153f0c6f8ab4d9dae93306f7507399aeda75eaf' }, index.h("div", { key: '5d9c28023fdfb5472fc115c66bc3df509506e10f', class: "mrd-text-field" }, index.h(FieldLabel, { key: '1e21139aae0cc1ae95aa3297271b618a40043e77', base: "mrd-text-field", label: this.label, required: this.required }), index.h("input", { key: '46f98d5e39bb834075449fac7096b077a1ae7bb3', class: controlClass('mrd-text-field', !!this.error), type: "text", name: this.name, value: this.value, placeholder: this.placeholder, required: this.required, disabled: this.disabled, onInput: this.handleInput, onBlur: this.handleBlur }), index.h(FieldError, { key: '10b6ddae9cd9f36dc9d7176167d79df8e4102c03', base: "mrd-text-field", error: this.error }))));
7650
+ return (index.h(index.Host, { key: '145aa80d06459fe85650702ced893e102762afa8' }, index.h("div", { key: '8f08af9acff56e704d216dc185a5d344b5b9f671', class: "mrd-text-field" }, index.h(FieldLabel, { key: '4e0204ffe7e8460eaf9a4be1535252cc11d0bab7', base: "mrd-text-field", label: this.label, required: this.required }), index.h("input", { key: '4d519077ad96c121ede51e188a2151efe72811db', class: controlClass('mrd-text-field', !!this.error), type: "text", name: this.name, value: this.value, placeholder: this.placeholder, required: this.required, disabled: this.disabled, onInput: this.handleInput, onBlur: this.handleBlur }), index.h(FieldError, { key: '3c5af47037f6d6851503d769429d6c0f786d389d', base: "mrd-text-field", error: this.error }))));
7411
7651
  }
7412
7652
  };
7413
7653
  MrdTextField.style = mrdTextFieldCss();
@@ -7479,7 +7719,7 @@ const MrdTextareaField = class {
7479
7719
  return purify.sanitize(html);
7480
7720
  }
7481
7721
  render() {
7482
- return (index.h(index.Host, { key: 'e132531881f68f373e700617aac8033c8ebccb47' }, index.h("div", { key: 'fec0cf56cd7868d3fcd5a4e8a382b2dcdb6e5c50', class: "mrd-textarea-field" }, index.h(FieldLabel, { key: '333aa2ff57cce9e3178f0c4be4a1df1077884248', base: "mrd-textarea-field", label: this.label, required: this.required }), index.h("div", { key: '40025207580eb5768981b85aaa0a8ff95fce7234', class: controlClass('mrd-textarea-field', !!this.error, 'container') }, index.h("div", { key: '621987b3b2b1d8b4836bff065075ba527a82db81', class: "mrd-textarea-field__editor" })), index.h(FieldError, { key: 'ac2d8de22f008cd1c91842137ccd0cd36eb9ce19', base: "mrd-textarea-field", error: this.error }))));
7722
+ return (index.h(index.Host, { key: 'e7c53e9cf54bd4138b42ca3bc7bb5381aad3e4ac' }, index.h("div", { key: 'bf580a74d2233704852c7d3083ec91c9bbe868ad', class: "mrd-textarea-field" }, index.h(FieldLabel, { key: '7de50cb2865e83c7fe1ef9b6b099b639e165909c', base: "mrd-textarea-field", label: this.label, required: this.required }), index.h("div", { key: 'c78e914091cd70b52c1e9cd0046e7c97bcc7e799', class: controlClass('mrd-textarea-field', !!this.error, 'container') }, index.h("div", { key: '604a157e82ca8a4d98bbd1c928e9f8b41d031227', class: "mrd-textarea-field__editor" })), index.h(FieldError, { key: 'd0263a7285b928be6ed377e7e0fa3f53a555dadd', base: "mrd-textarea-field", error: this.error }))));
7483
7723
  }
7484
7724
  get el() { return index.getElement(this); }
7485
7725
  };
@@ -7510,7 +7750,7 @@ const MrdTimeField = class {
7510
7750
  };
7511
7751
  }
7512
7752
  render() {
7513
- return (index.h(index.Host, { key: 'd521c654bc7beda71a31542a25198edaaf53b838' }, index.h("div", { key: '084ab16ac8aed952bd0ec50e0430591d4db5bd4b', class: "mrd-time-field" }, index.h(FieldLabel, { key: '43938ad7c5a9765353f6523d399d4b74cbb9ec6f', base: "mrd-time-field", label: this.label, required: this.required }), index.h("input", { key: 'e46eda620e7a5f1bb3b433a4c051e913675c33f9', class: controlClass('mrd-time-field', !!this.error), type: "time", name: this.name, value: this.value, required: this.required, disabled: this.disabled, onChange: this.handleChange, onBlur: this.handleBlur }), index.h(FieldError, { key: '34bc1eaa1b969951dffaaacad73af532b6d290fb', base: "mrd-time-field", error: this.error }))));
7753
+ return (index.h(index.Host, { key: 'ef3876dd5c1d72bdbdb65cba00ea0992ba2ab2b6' }, index.h("div", { key: '6b217f6c6ec0dbb8b3249dfab6443b8f6140891c', class: "mrd-time-field" }, index.h(FieldLabel, { key: '87adbcc4bf1ccad07d899a315cb14a00650af09c', base: "mrd-time-field", label: this.label, required: this.required }), index.h("input", { key: '870fcf7e0df2ee2804f95fdc79c890b3e27bba3f', class: controlClass('mrd-time-field', !!this.error), type: "time", name: this.name, value: this.value, required: this.required, disabled: this.disabled, onChange: this.handleChange, onBlur: this.handleBlur }), index.h(FieldError, { key: '03c21d23fbc039ffd79856134d181dffcb9e3621', base: "mrd-time-field", error: this.error }))));
7514
7754
  }
7515
7755
  };
7516
7756
  MrdTimeField.style = mrdTimeFieldCss();