@mmlogic/components 0.5.3 → 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 (85) hide show
  1. package/dist/cjs/{cell-renderer-7KX9Qbml.js → cell-renderer-Mx3pwONr.js} +261 -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 +391 -77
  5. package/dist/cjs/mrd-merge-view.cjs.entry.js +3 -3
  6. package/dist/collection/components/documents/mrd-document-container/mrd-document-container.css +3 -0
  7. package/dist/collection/components/documents/mrd-document-container/mrd-document-container.js +23 -3
  8. package/dist/collection/components/documents/mrd-document-list/mrd-document-list.js +76 -2
  9. package/dist/collection/components/fields/mrd-currency-field/mrd-currency-field.js +56 -5
  10. package/dist/collection/components/fields/mrd-date-field/mrd-date-field.css +55 -4
  11. package/dist/collection/components/fields/mrd-date-field/mrd-date-field.js +118 -8
  12. package/dist/collection/components/fields/mrd-datetime-field/mrd-datetime-field.css +55 -4
  13. package/dist/collection/components/fields/mrd-datetime-field/mrd-datetime-field.js +117 -15
  14. package/dist/collection/components/fields/mrd-email-field/mrd-email-field.js +1 -1
  15. package/dist/collection/components/fields/mrd-file-field/mrd-file-field.js +1 -1
  16. package/dist/collection/components/fields/mrd-image-field/mrd-image-field.js +1 -1
  17. package/dist/collection/components/fields/mrd-longtext-field/mrd-longtext-field.js +1 -1
  18. package/dist/collection/components/fields/mrd-number-field/mrd-number-field.js +33 -8
  19. package/dist/collection/components/fields/mrd-relation-field/mrd-relation-field.js +13 -3
  20. package/dist/collection/components/fields/mrd-secret-field/mrd-secret-field.js +2 -2
  21. package/dist/collection/components/fields/mrd-text-field/mrd-text-field.js +1 -1
  22. package/dist/collection/components/fields/mrd-textarea-field/mrd-textarea-field.js +1 -1
  23. package/dist/collection/components/fields/mrd-time-field/mrd-time-field.js +1 -1
  24. package/dist/collection/components/form/mrd-field/mrd-field.js +11 -11
  25. package/dist/collection/components/form/mrd-form/mrd-form.js +8 -4
  26. package/dist/collection/components/invoice/mrd-invoice-view/mrd-invoice-view.js +1 -1
  27. package/dist/collection/components/layout/mrd-layout-section/field-value.js +4 -2
  28. package/dist/collection/components/layout/mrd-layout-section/layout-helpers.js +6 -0
  29. package/dist/collection/components/layout/mrd-layout-section/mrd-layout-section.css +4 -0
  30. package/dist/collection/components/layout/mrd-layout-section/mrd-layout-section.js +8 -8
  31. package/dist/collection/components/merge/mrd-merge-view/mrd-merge-view.js +2 -2
  32. package/dist/collection/dev/app.js +58 -13
  33. package/dist/collection/dev/example-data.js +6 -1
  34. package/dist/collection/utils/format.js +160 -0
  35. package/dist/collection/utils/i18n.js +96 -0
  36. package/dist/components/cell-renderer.js +1 -1
  37. package/dist/components/format.js +1 -1
  38. package/dist/components/i18n.js +1 -1
  39. package/dist/components/mrd-currency-field2.js +1 -1
  40. package/dist/components/mrd-date-field2.js +1 -1
  41. package/dist/components/mrd-datetime-field2.js +1 -1
  42. package/dist/components/mrd-document-container2.js +1 -1
  43. package/dist/components/mrd-document-list2.js +1 -1
  44. package/dist/components/mrd-document-view2.js +1 -1
  45. package/dist/components/mrd-email-field2.js +1 -1
  46. package/dist/components/mrd-email-view2.js +1 -1
  47. package/dist/components/mrd-field2.js +1 -1
  48. package/dist/components/mrd-file-field2.js +1 -1
  49. package/dist/components/mrd-form.js +1 -1
  50. package/dist/components/mrd-image-field2.js +1 -1
  51. package/dist/components/mrd-invoice-view2.js +1 -1
  52. package/dist/components/mrd-layout-section.js +1 -1
  53. package/dist/components/mrd-longtext-field2.js +1 -1
  54. package/dist/components/mrd-merge-view.js +1 -1
  55. package/dist/components/mrd-number-field2.js +1 -1
  56. package/dist/components/mrd-relation-field2.js +1 -1
  57. package/dist/components/mrd-secret-field2.js +1 -1
  58. package/dist/components/mrd-table2.js +1 -1
  59. package/dist/components/mrd-text-field2.js +1 -1
  60. package/dist/components/mrd-textarea-field2.js +1 -1
  61. package/dist/components/mrd-time-field2.js +1 -1
  62. package/dist/esm/{cell-renderer-DIsNX9D7.js → cell-renderer-UQOYlDv7.js} +257 -1
  63. package/dist/esm/loader.js +1 -1
  64. package/dist/esm/mosterdcomponents.js +1 -1
  65. package/dist/esm/mrd-boolean-field_25.entry.js +391 -77
  66. package/dist/esm/mrd-merge-view.entry.js +3 -3
  67. package/dist/mosterdcomponents/mosterdcomponents.esm.js +1 -1
  68. package/dist/mosterdcomponents/p-8cc374e0.entry.js +3 -0
  69. package/dist/mosterdcomponents/p-CF--ScWr.js +1 -0
  70. package/dist/mosterdcomponents/{p-4e061416.entry.js → p-d31b71d9.entry.js} +1 -1
  71. package/dist/types/components/documents/mrd-document-container/mrd-document-container.d.ts +7 -0
  72. package/dist/types/components/documents/mrd-document-list/mrd-document-list.d.ts +17 -0
  73. package/dist/types/components/fields/mrd-currency-field/mrd-currency-field.d.ts +13 -0
  74. package/dist/types/components/fields/mrd-date-field/mrd-date-field.d.ts +22 -1
  75. package/dist/types/components/fields/mrd-datetime-field/mrd-datetime-field.d.ts +21 -2
  76. package/dist/types/components/fields/mrd-number-field/mrd-number-field.d.ts +6 -0
  77. package/dist/types/components/fields/mrd-relation-field/mrd-relation-field.d.ts +7 -0
  78. package/dist/types/components/form/mrd-form/mrd-form.d.ts +3 -2
  79. package/dist/types/components/layout/mrd-layout-section/layout-helpers.d.ts +3 -0
  80. package/dist/types/components.d.ts +35 -0
  81. package/dist/types/types/client-layout.d.ts +7 -0
  82. package/dist/types/utils/format.d.ts +34 -0
  83. package/package.json +1 -1
  84. package/dist/mosterdcomponents/p-910ebfee.entry.js +0 -3
  85. package/dist/mosterdcomponents/p-Ce2QDq0t.js +0 -1
@@ -19,6 +19,10 @@
19
19
  content: " *";
20
20
  color: var(--mrd-color-danger);
21
21
  }
22
+ .mrd-datetime-field__control {
23
+ position: relative;
24
+ display: block;
25
+ }
22
26
  .mrd-datetime-field__input {
23
27
  display: block;
24
28
  width: 100%;
@@ -53,12 +57,59 @@
53
57
  .mrd-datetime-field__input--error:focus {
54
58
  box-shadow: var(--mrd-shadow-focus-error);
55
59
  }
60
+ .mrd-datetime-field__input {
61
+ padding-inline-end: calc(var(--mrd-input-padding-x) + 1.75rem);
62
+ }
63
+ .mrd-datetime-field__picker {
64
+ position: absolute;
65
+ inset-inline-end: var(--mrd-space-1);
66
+ top: 50%;
67
+ transform: translateY(-50%);
68
+ width: 1.75rem;
69
+ height: 1.75rem;
70
+ }
71
+ .mrd-datetime-field__picker-button {
72
+ display: inline-flex;
73
+ align-items: center;
74
+ justify-content: center;
75
+ width: 100%;
76
+ height: 100%;
77
+ padding: 0;
78
+ border: 0;
79
+ border-radius: var(--mrd-border-radius-sm);
80
+ background: transparent;
81
+ color: var(--mrd-color-neutral-500);
82
+ cursor: pointer;
83
+ transition: color var(--mrd-transition), background-color var(--mrd-transition);
84
+ }
85
+ .mrd-datetime-field__picker-button svg {
86
+ width: 1.125rem;
87
+ height: 1.125rem;
88
+ }
89
+ .mrd-datetime-field__picker-button:hover:not(:disabled) {
90
+ color: var(--mrd-color-primary);
91
+ background-color: var(--mrd-color-neutral-100);
92
+ }
93
+ .mrd-datetime-field__picker-button:focus-visible {
94
+ outline: 2px solid var(--mrd-border-color-focus);
95
+ outline-offset: 1px;
96
+ }
97
+ .mrd-datetime-field__picker-button:disabled {
98
+ cursor: not-allowed;
99
+ opacity: 0.5;
100
+ }
101
+ .mrd-datetime-field__picker-native {
102
+ position: absolute;
103
+ inset: 0;
104
+ width: 100%;
105
+ height: 100%;
106
+ padding: 0;
107
+ border: 0;
108
+ opacity: 0;
109
+ pointer-events: none;
110
+ }
56
111
  .mrd-datetime-field__error {
57
112
  font-family: var(--mrd-font-family);
58
113
  font-size: var(--mrd-error-font-size);
59
114
  color: var(--mrd-error-color);
60
- }
61
-
62
- .mrd-datetime-field__input {
63
- cursor: pointer;
64
115
  }
@@ -1,33 +1,77 @@
1
1
  import { Host, h } from "@stencil/core";
2
+ import { t } from "../../../utils/i18n";
3
+ import { formatLocalDateTime, localeDatePattern, parseLocalizedDateTime } from "../../../utils/format";
2
4
  import { FieldLabel, FieldError, controlClass, requiredError } from "../field-helpers";
3
5
  export class MrdDatetimeField {
4
6
  constructor() {
5
7
  this.name = '';
6
8
  this.label = '';
9
+ /** UTC ISO string, e.g. '2026-07-06T12:30:00Z'. */
7
10
  this.value = '';
11
+ /** Overrides the locale-derived pattern placeholder (e.g. 'dd-mm-jjjj uu:mm'). */
12
+ this.placeholder = '';
8
13
  this.required = false;
9
14
  this.disabled = false;
10
15
  this.locale = navigator.language;
16
+ /** What the user sees: the value formatted for `locale`, or their raw typing. */
17
+ this.displayValue = '';
11
18
  this.error = '';
12
- this.localValue = '';
13
- this.handleChange = (e) => {
14
- const localVal = e.target.value;
15
- this.localValue = localVal;
16
- this.error = requiredError(localVal, this.required, this.locale);
17
- this.mrdChange.emit({ name: this.name, value: this.localToUtc(localVal) });
19
+ /** While focused the user owns the text; prop updates must not overwrite it. */
20
+ this.focused = false;
21
+ this.handleFocus = () => {
22
+ this.focused = true;
23
+ };
24
+ this.handleInput = (e) => {
25
+ this.displayValue = e.target.value;
18
26
  };
19
27
  this.handleBlur = (e) => {
20
- const localVal = e.target.value;
21
- this.mrdBlur.emit({ name: this.name, value: this.localToUtc(localVal) });
28
+ this.focused = false;
29
+ const value = this.commit(e.target.value);
30
+ this.mrdChange.emit({ name: this.name, value });
31
+ this.mrdBlur.emit({ name: this.name, value });
32
+ };
33
+ this.handleKeyDown = (e) => {
34
+ // Submitting with Enter never fires blur, so commit the typed text here too.
35
+ if (e.key !== 'Enter')
36
+ return;
37
+ const value = this.commit(e.target.value);
38
+ this.mrdChange.emit({ name: this.name, value });
39
+ };
40
+ this.openPicker = () => {
41
+ const native = this.nativeInput;
42
+ if (!native || this.disabled)
43
+ return;
44
+ // The blur commit that precedes this click re-renders asynchronously, so sync by hand first.
45
+ native.value = this.currentLocal();
46
+ try {
47
+ native.showPicker();
48
+ }
49
+ catch (_a) {
50
+ // Browsers without showPicker(): focusing at least surfaces the platform control.
51
+ native.focus();
52
+ }
53
+ };
54
+ this.handlePickerChange = (e) => {
55
+ const local = e.target.value; // native inputs always yield 'YYYY-MM-DDTHH:mm'
56
+ this.displayValue = formatLocalDateTime(local, this.locale);
57
+ this.error = requiredError(local, this.required, this.locale);
58
+ const value = this.localToUtc(local);
59
+ this.mrdChange.emit({ name: this.name, value });
60
+ this.mrdBlur.emit({ name: this.name, value });
22
61
  };
23
62
  }
24
63
  componentWillLoad() {
25
- this.localValue = this.utcToLocal(this.value);
64
+ this.displayValue = this.toDisplay(this.value);
26
65
  }
27
66
  valueChanged(newVal) {
28
- this.localValue = this.utcToLocal(newVal);
67
+ if (!this.focused)
68
+ this.displayValue = this.toDisplay(newVal);
29
69
  }
30
- // UTC ISO string → "YYYY-MM-DDTHH:mm" in local timezone (for datetime-local input)
70
+ localeChanged() {
71
+ if (!this.focused)
72
+ this.displayValue = this.toDisplay(this.value);
73
+ }
74
+ // UTC ISO string → "YYYY-MM-DDTHH:mm" in local timezone
31
75
  utcToLocal(utcStr) {
32
76
  if (!utcStr)
33
77
  return '';
@@ -46,8 +90,43 @@ export class MrdDatetimeField {
46
90
  return '';
47
91
  return d.toISOString().replace(/\.\d{3}Z$/, 'Z');
48
92
  }
93
+ // UTC ISO string → locale-formatted text for the input
94
+ toDisplay(utcStr) {
95
+ return formatLocalDateTime(this.utcToLocal(utcStr), this.locale);
96
+ }
97
+ patternPlaceholder() {
98
+ if (this.placeholder)
99
+ return this.placeholder;
100
+ return localeDatePattern(this.locale, {
101
+ day: t('date_token_day', this.locale),
102
+ month: t('date_token_month', this.locale),
103
+ year: t('date_token_year', this.locale),
104
+ hour: t('time_token_hour', this.locale),
105
+ minute: t('time_token_minute', this.locale),
106
+ });
107
+ }
108
+ /** Parse the typed text, reformat it, and return the UTC value to emit. */
109
+ commit(raw) {
110
+ const trimmed = raw.trim();
111
+ const local = trimmed ? parseLocalizedDateTime(trimmed, this.locale) : '';
112
+ if (trimmed && local === null) {
113
+ // Keep the raw text so the user can correct it instead of retyping.
114
+ this.error = t('invalid_datetime', this.locale);
115
+ this.displayValue = trimmed;
116
+ return '';
117
+ }
118
+ const localValue = local !== null && local !== void 0 ? local : '';
119
+ this.error = requiredError(localValue, this.required, this.locale);
120
+ this.displayValue = localValue ? formatLocalDateTime(localValue, this.locale) : '';
121
+ return this.localToUtc(localValue);
122
+ }
123
+ /** The local 'YYYY-MM-DDTHH:mm' currently shown, so the picker opens on the right moment. */
124
+ currentLocal() {
125
+ var _a;
126
+ return (_a = (this.displayValue ? parseLocalizedDateTime(this.displayValue, this.locale) : '')) !== null && _a !== void 0 ? _a : '';
127
+ }
49
128
  render() {
50
- return (h(Host, { key: '6f8020590ac879992058aa9547b90c11250fa303' }, h("div", { key: '76abff48cae58d156540181a6577729a449bb888', class: "mrd-datetime-field" }, h(FieldLabel, { key: 'a8c3688980347a27d6467987f11a3c4135ac5234', base: "mrd-datetime-field", label: this.label, required: this.required }), 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 }), h(FieldError, { key: 'c97301640980bf04311751124fc8e87023d59f87', base: "mrd-datetime-field", error: this.error }))));
129
+ return (h(Host, { key: 'e075e65c76a627a8f19db488c07704e2b1a7270b' }, h("div", { key: 'a6b5a5df3168272f1f775933dfc372e1b2ccbd95', class: "mrd-datetime-field" }, h(FieldLabel, { key: '39e232c066b8c354eeda7df9bcba4e3f95c18ee5', base: "mrd-datetime-field", label: this.label, required: this.required }), h("div", { key: '4ffac4089cbb9e5506aa0854c8b1f15862bc8456', class: "mrd-datetime-field__control" }, 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 }), h("span", { key: '54d8d3b1f508d6226d1341d87c1fec19d5914a10', class: "mrd-datetime-field__picker" }, h("button", { key: '27cd3977984eedd9e3471dd039fc73798f1c7abc', type: "button", class: "mrd-datetime-field__picker-button", title: t('open_calendar', this.locale), "aria-label": t('open_calendar', this.locale), disabled: this.disabled, onClick: this.openPicker }, h("svg", { key: '634ca817fa001263933795e35e1a215a06da7a77', viewBox: "0 0 20 20", fill: "none", stroke: "currentColor", "stroke-width": "1.5", "aria-hidden": "true" }, h("rect", { key: '66eadf6b2cfee53376f6ea0f50dbd2ec04fc5663', x: "3", y: "4.5", width: "14", height: "12", rx: "2" }), h("path", { key: '4bb61793e0501bd18bb16c4e203b20f509692970', d: "M3 8.5h14M7 2.5v3M13 2.5v3", "stroke-linecap": "round" }))), 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 }))), h(FieldError, { key: '4ee97180614972c4dd334d68873a9fb7f91e48f5', base: "mrd-datetime-field", error: this.error }))));
51
130
  }
52
131
  static get is() { return "mrd-datetime-field"; }
53
132
  static get encapsulation() { return "scoped"; }
@@ -115,7 +194,7 @@ export class MrdDatetimeField {
115
194
  "optional": false,
116
195
  "docs": {
117
196
  "tags": [],
118
- "text": ""
197
+ "text": "UTC ISO string, e.g. '2026-07-06T12:30:00Z'."
119
198
  },
120
199
  "getter": false,
121
200
  "setter": false,
@@ -123,6 +202,26 @@ export class MrdDatetimeField {
123
202
  "attribute": "value",
124
203
  "defaultValue": "''"
125
204
  },
205
+ "placeholder": {
206
+ "type": "string",
207
+ "mutable": false,
208
+ "complexType": {
209
+ "original": "string",
210
+ "resolved": "string",
211
+ "references": {}
212
+ },
213
+ "required": false,
214
+ "optional": false,
215
+ "docs": {
216
+ "tags": [],
217
+ "text": "Overrides the locale-derived pattern placeholder (e.g. 'dd-mm-jjjj uu:mm')."
218
+ },
219
+ "getter": false,
220
+ "setter": false,
221
+ "reflect": false,
222
+ "attribute": "placeholder",
223
+ "defaultValue": "''"
224
+ },
126
225
  "required": {
127
226
  "type": "boolean",
128
227
  "mutable": false,
@@ -187,8 +286,8 @@ export class MrdDatetimeField {
187
286
  }
188
287
  static get states() {
189
288
  return {
190
- "error": {},
191
- "localValue": {}
289
+ "displayValue": {},
290
+ "error": {}
192
291
  };
193
292
  }
194
293
  static get events() {
@@ -228,6 +327,9 @@ export class MrdDatetimeField {
228
327
  return [{
229
328
  "propName": "value",
230
329
  "methodName": "valueChanged"
330
+ }, {
331
+ "propName": "locale",
332
+ "methodName": "localeChanged"
231
333
  }];
232
334
  }
233
335
  }
@@ -24,7 +24,7 @@ export class MrdEmailField {
24
24
  };
25
25
  }
26
26
  render() {
27
- return (h(Host, { key: '3253124dadc7f0b3f120c11f8c35604a2f671b0a' }, h("div", { key: 'db820652452145c30f21b41a65942c0a4c6f45f1', class: "mrd-email-field" }, h(FieldLabel, { key: '8b1c5a84afce9fd18c3f644e5c92f07363e116d4', base: "mrd-email-field", label: this.label, required: this.required }), 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 }), h(FieldError, { key: 'c44377d1b6a4a4c468b080b23eecd4ba9ca326e1', base: "mrd-email-field", error: this.error }))));
27
+ return (h(Host, { key: 'e185145e628e3a23dd338d93dd8e42bf11569728' }, h("div", { key: '7d77dd982543a8add5fa1f47aa7985cc15079080', class: "mrd-email-field" }, h(FieldLabel, { key: '14eb00a535a052ebe3cb2793cc7dfc05168c402b', base: "mrd-email-field", label: this.label, required: this.required }), 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 }), h(FieldError, { key: 'be33c0a43cd99a7152c1d10b7067ea5e52834742', base: "mrd-email-field", error: this.error }))));
28
28
  }
29
29
  static get is() { return "mrd-email-field"; }
30
30
  static get encapsulation() { return "scoped"; }
@@ -112,7 +112,7 @@ export class MrdFileField {
112
112
  error: hasError,
113
113
  disabled: this.disabled || this.zoneBusy,
114
114
  });
115
- return (h(Host, { key: '2e740a0857b069740a6a13616d0a0dfee2b945be' }, h("div", { key: '069b25ced3b2f1ce547819086dadbd53ade2378c', class: "mrd-file-field" }, h(FieldLabel, { key: 'd13f3cb0af766d6328772dab865b2079c85ec075', base: "mrd-file-field", label: this.label, required: this.required }), h("div", { key: '9ffdbb508e3934854034c46e6f719a88d4175920', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.drag.onDragOver, onDragLeave: this.drag.onDragLeave, onDrop: this.drag.onDrop }, 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 ? (h("div", { class: "mrd-file-field__selected" }, this.renderEntry(this.entries[0], 0))) : (h("div", { class: "mrd-file-field__prompt" }, h("svg", { class: "mrd-file-field__upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("polyline", { points: "16 16 12 12 8 16" }), h("line", { x1: "12", y1: "12", x2: "12", y2: "21" }), h("path", { d: "M20.39 18.39A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.3" })), h("span", null, t('drop_file_here', this.locale), ' ', h("span", { class: "mrd-file-field__browse" }, t('browse', this.locale)))))), this.multiple && hasEntries && (h("ul", { key: '910a3e89f74d93ab16fb9f677a4276d5ad88897d', class: "mrd-file-field__list" }, this.entries.map((entry, index) => (h("li", { class: "mrd-file-field__item", key: `${index}-${entryLabel(entry)}` }, this.renderEntry(entry, index)))))), h(FieldError, { key: '4f0f071b0a1460ea1d6067a8fa4f588ebc620f2a', base: "mrd-file-field", error: this.error }))));
115
+ return (h(Host, { key: '36f9660fd297e7b2e7b2ac1816f4dcbc70d5cfcb' }, h("div", { key: 'a33534d3fedae04bad0eefc9d2d297ea148c5784', class: "mrd-file-field" }, h(FieldLabel, { key: '833f8ff178ec259c8066ddf542bdd1930bac486f', base: "mrd-file-field", label: this.label, required: this.required }), h("div", { key: 'd3bd00b25329b8cc716c5fcc526919d8f2c14bce', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.drag.onDragOver, onDragLeave: this.drag.onDragLeave, onDrop: this.drag.onDrop }, 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 ? (h("div", { class: "mrd-file-field__selected" }, this.renderEntry(this.entries[0], 0))) : (h("div", { class: "mrd-file-field__prompt" }, h("svg", { class: "mrd-file-field__upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("polyline", { points: "16 16 12 12 8 16" }), h("line", { x1: "12", y1: "12", x2: "12", y2: "21" }), h("path", { d: "M20.39 18.39A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.3" })), h("span", null, t('drop_file_here', this.locale), ' ', h("span", { class: "mrd-file-field__browse" }, t('browse', this.locale)))))), this.multiple && hasEntries && (h("ul", { key: '6e6e1d62738d0a824eb86e0dbb01b63a0227580d', class: "mrd-file-field__list" }, this.entries.map((entry, index) => (h("li", { class: "mrd-file-field__item", key: `${index}-${entryLabel(entry)}` }, this.renderEntry(entry, index)))))), h(FieldError, { key: 'df6427015d3f813a72e8998f9fa6152f6caef90e', base: "mrd-file-field", error: this.error }))));
116
116
  }
117
117
  static get is() { return "mrd-file-field"; }
118
118
  static get encapsulation() { return "scoped"; }
@@ -130,7 +130,7 @@ export class MrdImageField {
130
130
  error: hasError,
131
131
  disabled: this.disabled || this.zoneBusy,
132
132
  });
133
- return (h(Host, { key: '51d39ea80195565a5dc780ff6a7923a976cfb0a7' }, h("div", { key: 'd76edb7ac9f1efea8c7c3d5b04e906ad4ab4c761', class: "mrd-image-field" }, h(FieldLabel, { key: 'b46a67a76188047677c40ce3f406daed7d8de141', base: "mrd-image-field", label: this.label, required: this.required }), h("div", { key: '0156a9722ea48d84e3ea1a829e4266425a594a6a', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.drag.onDragOver, onDragLeave: this.drag.onDragLeave, onDrop: this.drag.onDrop }, 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])) : (h("div", { class: "mrd-image-field__prompt" }, h("svg", { class: "mrd-image-field__upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }), h("circle", { cx: "8.5", cy: "8.5", r: "1.5" }), h("polyline", { points: "21 15 16 10 5 21" })), h("span", null, t('drop_file_here', this.locale), ' ', h("span", { class: "mrd-image-field__browse" }, t('browse', this.locale)))))), this.multiple && hasEntries && (h("ul", { key: '9211b5212eae0629f7c9b2b49d80e2b658a9ddd3', class: "mrd-image-field__grid" }, this.entries.map((entry, index) => this.renderGridItem(entry, index)))), h(FieldError, { key: '5f49c03156ed18e7c8307adff679b149658ca4a6', base: "mrd-image-field", error: this.error }))));
133
+ return (h(Host, { key: '5009b2db845c8f85f395c7230e2d5c464c56ea14' }, h("div", { key: 'fcae7821876ee3d71aac576cdea44c3c4f169890', class: "mrd-image-field" }, h(FieldLabel, { key: '834638e3f7b2073508d98b6dd5ecb437b0bb52ad', base: "mrd-image-field", label: this.label, required: this.required }), h("div", { key: '50e9bdaa1ebb3ec87f36e0d37dc6c2f8dc79848d', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.drag.onDragOver, onDragLeave: this.drag.onDragLeave, onDrop: this.drag.onDrop }, 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])) : (h("div", { class: "mrd-image-field__prompt" }, h("svg", { class: "mrd-image-field__upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }), h("circle", { cx: "8.5", cy: "8.5", r: "1.5" }), h("polyline", { points: "21 15 16 10 5 21" })), h("span", null, t('drop_file_here', this.locale), ' ', h("span", { class: "mrd-image-field__browse" }, t('browse', this.locale)))))), this.multiple && hasEntries && (h("ul", { key: '67bad2f2142f78d7f25b8f35819b6adba48ea597', class: "mrd-image-field__grid" }, this.entries.map((entry, index) => this.renderGridItem(entry, index)))), h(FieldError, { key: 'ef07863946f0b4c94aa30b97d0ecb9616303e793', base: "mrd-image-field", error: this.error }))));
134
134
  }
135
135
  static get is() { return "mrd-image-field"; }
136
136
  static get encapsulation() { return "scoped"; }
@@ -21,7 +21,7 @@ export class MrdLongtextField {
21
21
  };
22
22
  }
23
23
  render() {
24
- return (h(Host, { key: 'e53fec4d4eafbd68d9cffb1f064d8e0c4c37839c' }, h("div", { key: '8843a23e42b0545c269fc6c924e7ae295770064e', class: "mrd-longtext-field" }, h(FieldLabel, { key: '8767676dd35f25f9bf5ebdb26887edc0882582e0', base: "mrd-longtext-field", label: this.label, required: this.required }), this.disabled ? (h("pre", { class: "mrd-longtext-field__content" }, this.value)) : (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)), h(FieldError, { key: '54dc790173575e8a02764e5b14040b900c2eb609', base: "mrd-longtext-field", error: this.error }))));
24
+ return (h(Host, { key: 'a43ce67cb05e96853193e56c175d99e51d07cbab' }, h("div", { key: 'eb7d09bcae010736dd17b5f17bcb1cb32a6b1c4e', class: "mrd-longtext-field" }, h(FieldLabel, { key: 'd3a47993cc977c06b845eda4575b93d238eaf15a', base: "mrd-longtext-field", label: this.label, required: this.required }), this.disabled ? (h("pre", { class: "mrd-longtext-field__content" }, this.value)) : (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)), h(FieldError, { key: '89f801af61fc0b874db44dbfca6eb33ffe285a84', base: "mrd-longtext-field", error: this.error }))));
25
25
  }
26
26
  static get is() { return "mrd-longtext-field"; }
27
27
  static get encapsulation() { return "scoped"; }
@@ -17,10 +17,13 @@ export class MrdNumberField {
17
17
  this.decimalPrecision = 2;
18
18
  this.displayValue = '';
19
19
  this.error = '';
20
+ /** While focused the user owns the text; prop updates must not overwrite it. */
21
+ this.focused = false;
20
22
  this.handleInput = (e) => {
21
23
  this.displayValue = e.target.value;
22
24
  };
23
25
  this.handleBlur = (e) => {
26
+ this.focused = false;
24
27
  const raw = e.target.value;
25
28
  const parsed = parseLocalizedNumber(raw, this.locale);
26
29
  if (this.required && (parsed === null || raw === '')) {
@@ -39,17 +42,30 @@ export class MrdNumberField {
39
42
  this.mrdBlur.emit({ name: this.name, value: parsed });
40
43
  };
41
44
  this.handleFocus = () => {
42
- // Show raw number on focus
43
- if (this.value !== null && this.value !== undefined) {
44
- const str = String(this.value);
45
- this.displayValue = str;
45
+ this.focused = true;
46
+ // Drop the grouping separators while editing, but keep the locale's decimal
47
+ // separator: String(1234.56) would be re-read as 123456 where '.' groups.
48
+ const parsed = parseLocalizedNumber(this.displayValue, this.locale);
49
+ if (parsed !== null) {
50
+ this.displayValue = formatNumber(parsed, this.locale, { useGrouping: false, maximumFractionDigits: 20 });
46
51
  }
47
52
  };
48
53
  }
49
54
  componentWillLoad() {
50
- if (this.value !== null && this.value !== undefined) {
51
- this.displayValue = this.formatForDisplay(this.value);
52
- }
55
+ this.syncFromValue();
56
+ }
57
+ /** Edit mode loads the record after mount, so the incoming value must re-sync. */
58
+ valueChanged() {
59
+ if (!this.focused)
60
+ this.syncFromValue();
61
+ }
62
+ localeChanged() {
63
+ if (!this.focused)
64
+ this.syncFromValue();
65
+ }
66
+ syncFromValue() {
67
+ this.displayValue =
68
+ this.value !== null && this.value !== undefined ? this.formatForDisplay(this.value) : '';
53
69
  }
54
70
  formatForDisplay(val) {
55
71
  if (this.dataType === ClientLayoutItemFieldDataType.PERCENTAGE) {
@@ -70,7 +86,7 @@ export class MrdNumberField {
70
86
  const hasError = !!this.error;
71
87
  const suffix = this.dataType === ClientLayoutItemFieldDataType.PERCENTAGE ? '%' :
72
88
  this.dataType === ClientLayoutItemFieldDataType.DECIMAL ? '' : '';
73
- return (h(Host, { key: '5df5c2e16c85cd54944d95b7a8c340ae1a4ddb34' }, h("div", { key: 'e332bd0190d537c002b14090fa96ec6502e34746', class: "mrd-number-field" }, h(FieldLabel, { key: 'e26ae85ef6c6d7935b2d34041a7ee2294da392a4', base: "mrd-number-field", label: this.label, required: this.required }), h("div", { key: 'fb1a44a363a36b69124a0092e80b67d41b538c03', class: "mrd-number-field__input-wrapper" }, 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 })), h(FieldError, { key: 'ecb16ddf655e563f0569e774ab2f2e419f60b0f1', base: "mrd-number-field", error: this.error }))));
89
+ return (h(Host, { key: 'bd5eb25cf7b97ef2ddb67a6bc6d6d96c9bff7510' }, h("div", { key: '68b15887a045f743a7f177e7a178146a9f4e0400', class: "mrd-number-field" }, h(FieldLabel, { key: '72e88a34a390e36ee11f5840d87dedd9d4d7fb12', base: "mrd-number-field", label: this.label, required: this.required }), h("div", { key: 'd97dae69eedf4c0ed1c872065754327dbffb5ba7', class: "mrd-number-field__input-wrapper" }, 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 })), h(FieldError, { key: '1d4f8ffd3fcdf2ae2e8eb1eb68c051619d66c954', base: "mrd-number-field", error: this.error }))));
74
90
  }
75
91
  static get is() { return "mrd-number-field"; }
76
92
  static get encapsulation() { return "scoped"; }
@@ -314,4 +330,13 @@ export class MrdNumberField {
314
330
  }
315
331
  }];
316
332
  }
333
+ static get watchers() {
334
+ return [{
335
+ "propName": "value",
336
+ "methodName": "valueChanged"
337
+ }, {
338
+ "propName": "locale",
339
+ "methodName": "localeChanged"
340
+ }];
341
+ }
317
342
  }
@@ -121,16 +121,22 @@ export class MrdRelationField {
121
121
  async setAllRecords(records) {
122
122
  this.allRecords = records;
123
123
  }
124
+ /** Href of the current single value. Accepts both a RelationSearchResult
125
+ * (`id`) and the raw API link shape (`{ href, name }`) a host puts in the
126
+ * form values for edit mode — same tolerance as `toSearchResult()`. */
124
127
  getValueHref() {
125
- var _a, _b, _c;
128
+ var _a, _b, _c, _d;
126
129
  const v = Array.isArray(this.value) ? ((_a = this.value[0]) !== null && _a !== void 0 ? _a : '') : ((_b = this.value) !== null && _b !== void 0 ? _b : '');
127
130
  if (!v)
128
131
  return '';
129
132
  if (typeof v === 'object')
130
- return (_c = v.id) !== null && _c !== void 0 ? _c : '';
133
+ return (_d = (_c = v.id) !== null && _c !== void 0 ? _c : v.href) !== null && _d !== void 0 ? _d : '';
131
134
  return v;
132
135
  }
133
- allRecordsChanged() {
136
+ /** Push the current value onto the rendered <select>. Options and value arrive
137
+ * independently in edit mode (fetched records vs. the async `values` prop), so
138
+ * this runs on both — whichever lands last completes the preselection. */
139
+ syncDropdownSelection() {
134
140
  if (this.editBehavior !== ClientLayoutItemRelationEditBehavior.DROPDOWN)
135
141
  return;
136
142
  const current = this.getValueHref();
@@ -146,6 +152,9 @@ export class MrdRelationField {
146
152
  select.value = current;
147
153
  }, 0);
148
154
  }
155
+ allRecordsChanged() {
156
+ this.syncDropdownSelection();
157
+ }
149
158
  async setSearchResults(results) {
150
159
  this.searchResults = results;
151
160
  this.isLoading = false;
@@ -197,6 +206,7 @@ export class MrdRelationField {
197
206
  // (host pre-fill). Plain href strings from user interaction are ignored.
198
207
  valueChanged(newValue) {
199
208
  this.applyValuePrefill(newValue);
209
+ this.syncDropdownSelection();
200
210
  }
201
211
  componentDidLoad() {
202
212
  // Only emit when there is no commonRelation dependency — the form orchestrates those.
@@ -21,9 +21,9 @@ export class MrdSecretField {
21
21
  };
22
22
  }
23
23
  render() {
24
- return (h(Host, { key: 'e06d04fdae34b42441976e21605fe94ad935382e' }, h("div", { key: '2889e1eb1b6d0887ae531523a0b9b43c49ef6f99', class: "mrd-secret-field" }, h(FieldLabel, { key: 'c40907905292cdef8bb0b8b9b0c03e05650bef37', base: "mrd-secret-field", label: this.label, required: this.required }), this.disabled
24
+ return (h(Host, { key: 'd3d204242898c1f258b088e7b5428421cde8d7a7' }, h("div", { key: '11d284625cdd1e0def58cc31eab9bbe59346649d', class: "mrd-secret-field" }, h(FieldLabel, { key: '333e5b23d2379125a393f555b936be7bc521fdb4', base: "mrd-secret-field", label: this.label, required: this.required }), this.disabled
25
25
  ? (h("span", { class: "mrd-secret-field__masked", "aria-label": this.label }, this.value ? '••••••••' : ''))
26
- : (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 })), h(FieldError, { key: '6353e4b40566852dbc1994c7c9c409d0d0aa1b37', base: "mrd-secret-field", error: this.error }))));
26
+ : (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 })), h(FieldError, { key: 'cc202197fdab62da7b5083e078e69efd86e673ca', base: "mrd-secret-field", error: this.error }))));
27
27
  }
28
28
  static get is() { return "mrd-secret-field"; }
29
29
  static get encapsulation() { return "scoped"; }
@@ -21,7 +21,7 @@ export class MrdTextField {
21
21
  };
22
22
  }
23
23
  render() {
24
- return (h(Host, { key: '3153f0c6f8ab4d9dae93306f7507399aeda75eaf' }, h("div", { key: '5d9c28023fdfb5472fc115c66bc3df509506e10f', class: "mrd-text-field" }, h(FieldLabel, { key: '1e21139aae0cc1ae95aa3297271b618a40043e77', base: "mrd-text-field", label: this.label, required: this.required }), 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 }), h(FieldError, { key: '10b6ddae9cd9f36dc9d7176167d79df8e4102c03', base: "mrd-text-field", error: this.error }))));
24
+ return (h(Host, { key: '145aa80d06459fe85650702ced893e102762afa8' }, h("div", { key: '8f08af9acff56e704d216dc185a5d344b5b9f671', class: "mrd-text-field" }, h(FieldLabel, { key: '4e0204ffe7e8460eaf9a4be1535252cc11d0bab7', base: "mrd-text-field", label: this.label, required: this.required }), 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 }), h(FieldError, { key: '3c5af47037f6d6851503d769429d6c0f786d389d', base: "mrd-text-field", error: this.error }))));
25
25
  }
26
26
  static get is() { return "mrd-text-field"; }
27
27
  static get encapsulation() { return "scoped"; }
@@ -64,7 +64,7 @@ export class MrdTextareaField {
64
64
  return DOMPurify.sanitize(html);
65
65
  }
66
66
  render() {
67
- return (h(Host, { key: 'e132531881f68f373e700617aac8033c8ebccb47' }, h("div", { key: 'fec0cf56cd7868d3fcd5a4e8a382b2dcdb6e5c50', class: "mrd-textarea-field" }, h(FieldLabel, { key: '333aa2ff57cce9e3178f0c4be4a1df1077884248', base: "mrd-textarea-field", label: this.label, required: this.required }), h("div", { key: '40025207580eb5768981b85aaa0a8ff95fce7234', class: controlClass('mrd-textarea-field', !!this.error, 'container') }, h("div", { key: '621987b3b2b1d8b4836bff065075ba527a82db81', class: "mrd-textarea-field__editor" })), h(FieldError, { key: 'ac2d8de22f008cd1c91842137ccd0cd36eb9ce19', base: "mrd-textarea-field", error: this.error }))));
67
+ return (h(Host, { key: 'e7c53e9cf54bd4138b42ca3bc7bb5381aad3e4ac' }, h("div", { key: 'bf580a74d2233704852c7d3083ec91c9bbe868ad', class: "mrd-textarea-field" }, h(FieldLabel, { key: '7de50cb2865e83c7fe1ef9b6b099b639e165909c', base: "mrd-textarea-field", label: this.label, required: this.required }), h("div", { key: 'c78e914091cd70b52c1e9cd0046e7c97bcc7e799', class: controlClass('mrd-textarea-field', !!this.error, 'container') }, h("div", { key: '604a157e82ca8a4d98bbd1c928e9f8b41d031227', class: "mrd-textarea-field__editor" })), h(FieldError, { key: 'd0263a7285b928be6ed377e7e0fa3f53a555dadd', base: "mrd-textarea-field", error: this.error }))));
68
68
  }
69
69
  static get is() { return "mrd-textarea-field"; }
70
70
  static get encapsulation() { return "scoped"; }
@@ -20,7 +20,7 @@ export class MrdTimeField {
20
20
  };
21
21
  }
22
22
  render() {
23
- return (h(Host, { key: 'd521c654bc7beda71a31542a25198edaaf53b838' }, h("div", { key: '084ab16ac8aed952bd0ec50e0430591d4db5bd4b', class: "mrd-time-field" }, h(FieldLabel, { key: '43938ad7c5a9765353f6523d399d4b74cbb9ec6f', base: "mrd-time-field", label: this.label, required: this.required }), 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 }), h(FieldError, { key: '34bc1eaa1b969951dffaaacad73af532b6d290fb', base: "mrd-time-field", error: this.error }))));
23
+ return (h(Host, { key: 'ef3876dd5c1d72bdbdb65cba00ea0992ba2ab2b6' }, h("div", { key: '6b217f6c6ec0dbb8b3249dfab6443b8f6140891c', class: "mrd-time-field" }, h(FieldLabel, { key: '87adbcc4bf1ccad07d899a315cb14a00650af09c', base: "mrd-time-field", label: this.label, required: this.required }), 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 }), h(FieldError, { key: '03c21d23fbc039ffd79856134d181dffcb9e3621', base: "mrd-time-field", error: this.error }))));
24
24
  }
25
25
  static get is() { return "mrd-time-field"; }
26
26
  static get encapsulation() { return "scoped"; }
@@ -111,7 +111,7 @@ export class MrdField {
111
111
  return (h("div", { class: "mrd-field__history-editor" }, this.historyEntries.length > 0 && (h("span", { class: "mrd-field__history-editor-label" }, t('history_badge_tooltip', locale))), this.historyEntries.map((entry, i) => (h("div", { key: String(i), class: "mrd-field__history-editor-row" }, h("input", { class: "mrd-field__history-editor-value", type: valueType, value: entry.value, onInput: (e) => updateEntry(i, 'value', e.target.value) }), h("span", { class: "mrd-field__history-editor-sep" }, t('history_until', locale)), h("input", { class: "mrd-field__history-editor-until", type: "date", value: entry.until, onInput: (e) => updateEntry(i, 'until', e.target.value) }), h("button", { type: "button", class: "mrd-field__history-editor-remove", onClick: () => removeEntry(i), "aria-label": t('remove', locale) }, h("svg", { viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true" }, 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" })))))), h("button", { type: "button", class: "mrd-field__history-editor-add", onClick: addEntry }, "+ ", t('add', locale))));
112
112
  }
113
113
  renderLeafField(displayValue) {
114
- 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;
114
+ 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;
115
115
  const { item, locale } = this;
116
116
  const commonProps = {
117
117
  name: item.name,
@@ -136,25 +136,25 @@ export class MrdField {
136
136
  case ClientLayoutItemFieldDataType.BOOLEAN:
137
137
  return (h("mrd-boolean-field", Object.assign({}, commonProps, { value: (_l = displayValue) !== null && _l !== void 0 ? _l : false })));
138
138
  case ClientLayoutItemFieldDataType.DATE:
139
- return (h("mrd-date-field", Object.assign({}, commonProps, { value: (_m = displayValue) !== null && _m !== void 0 ? _m : '' })));
139
+ return (h("mrd-date-field", Object.assign({}, commonProps, { value: (_m = displayValue) !== null && _m !== void 0 ? _m : '', placeholder: (_o = item.placeholder) !== null && _o !== void 0 ? _o : '' })));
140
140
  case ClientLayoutItemFieldDataType.DATETIME:
141
- return (h("mrd-datetime-field", Object.assign({}, commonProps, { value: (_o = displayValue) !== null && _o !== void 0 ? _o : '' })));
141
+ return (h("mrd-datetime-field", Object.assign({}, commonProps, { value: (_p = displayValue) !== null && _p !== void 0 ? _p : '', placeholder: (_q = item.placeholder) !== null && _q !== void 0 ? _q : '' })));
142
142
  case ClientLayoutItemFieldDataType.TIME:
143
- return (h("mrd-time-field", Object.assign({}, commonProps, { value: (_p = displayValue) !== null && _p !== void 0 ? _p : '' })));
143
+ return (h("mrd-time-field", Object.assign({}, commonProps, { value: (_r = displayValue) !== null && _r !== void 0 ? _r : '' })));
144
144
  case ClientLayoutItemFieldDataType.EMAIL:
145
- return (h("mrd-email-field", Object.assign({}, commonProps, { value: (_q = displayValue) !== null && _q !== void 0 ? _q : '', placeholder: (_r = item.placeholder) !== null && _r !== void 0 ? _r : '' })));
145
+ return (h("mrd-email-field", Object.assign({}, commonProps, { value: (_s = displayValue) !== null && _s !== void 0 ? _s : '', placeholder: (_t = item.placeholder) !== null && _t !== void 0 ? _t : '' })));
146
146
  case ClientLayoutItemFieldDataType.HYPERLINK:
147
- return (h("mrd-hyperlink-field", Object.assign({}, commonProps, { value: (_s = displayValue) !== null && _s !== void 0 ? _s : '', placeholder: (_t = item.placeholder) !== null && _t !== void 0 ? _t : '' })));
147
+ return (h("mrd-hyperlink-field", Object.assign({}, commonProps, { value: (_u = displayValue) !== null && _u !== void 0 ? _u : '', placeholder: (_v = item.placeholder) !== null && _v !== void 0 ? _v : '' })));
148
148
  case ClientLayoutItemFieldDataType.LIST:
149
- return (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 : [] })));
149
+ return (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 : [] })));
150
150
  case ClientLayoutItemFieldDataType.FILE:
151
- return (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 })));
151
+ return (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 })));
152
152
  case ClientLayoutItemFieldDataType.IMAGE:
153
- return (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 })));
153
+ return (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 })));
154
154
  case ClientLayoutItemFieldDataType.LONGTEXT:
155
- return (h("mrd-longtext-field", Object.assign({}, commonProps, { value: (_3 = displayValue) !== null && _3 !== void 0 ? _3 : '', placeholder: (_4 = item.placeholder) !== null && _4 !== void 0 ? _4 : '' })));
155
+ return (h("mrd-longtext-field", Object.assign({}, commonProps, { value: (_5 = displayValue) !== null && _5 !== void 0 ? _5 : '', placeholder: (_6 = item.placeholder) !== null && _6 !== void 0 ? _6 : '' })));
156
156
  case ClientLayoutItemFieldDataType.SECRET:
157
- return (h("mrd-secret-field", Object.assign({}, commonProps, { value: (_5 = displayValue) !== null && _5 !== void 0 ? _5 : '', placeholder: (_6 = item.placeholder) !== null && _6 !== void 0 ? _6 : '' })));
157
+ return (h("mrd-secret-field", Object.assign({}, commonProps, { value: (_7 = displayValue) !== null && _7 !== void 0 ? _7 : '', placeholder: (_8 = item.placeholder) !== null && _8 !== void 0 ? _8 : '' })));
158
158
  default:
159
159
  return null;
160
160
  }
@@ -253,15 +253,19 @@ export class MrdForm {
253
253
  }
254
254
  }
255
255
  }
256
- /** Extract a plain href string from a form value, which can be a string or
257
- * a RelationSearchResult-like object with an `id` field. */
256
+ /** Extract a plain href string from a form value: a string, a
257
+ * RelationSearchResult-like object (`id`), or the raw API link shape
258
+ * (`{ href, name }`) hosts spread into `values` for edit mode. */
258
259
  getHref(value) {
260
+ var _a, _b;
259
261
  if (!value)
260
262
  return '';
261
263
  if (typeof value === 'string')
262
264
  return value;
263
- if (typeof value === 'object' && 'id' in value)
264
- return value.id;
265
+ if (typeof value === 'object') {
266
+ const v = value;
267
+ return (_b = (_a = v.id) !== null && _a !== void 0 ? _a : v.href) !== null && _b !== void 0 ? _b : '';
268
+ }
265
269
  return '';
266
270
  }
267
271
  collectFields(items) {
@@ -107,7 +107,7 @@ export class MrdInvoiceView {
107
107
  const invoiceDateRaw = this.slotValue('invoiceDate');
108
108
  const dueDateRaw = this.slotValue('dueDate');
109
109
  const hasLines = !!((_b = (_a = this.archetype) === null || _a === void 0 ? void 0 : _a.slots) === null || _b === void 0 ? void 0 : _b['lines']);
110
- return (h(Host, { key: 'a97c51e53e39ace913c902ad2ba6813eb85e4561' }, h("div", { key: '6938267848bceed5b28b56c3cdd6d6693e57cdbf', class: "mrd-invoice-view" }, h("div", { key: '7a0b3346232abfc1e35805e4e92c19d35698f881', class: "mrd-invoice-view__header" }, h("div", { key: '5c0471dd8ebd94dd9b374897268c7c03bec66ec7', class: "mrd-invoice-view__title-row" }, invoiceNumber && h("h1", { key: '86b4c0ebd0a5b83ae03b731b7e41394645aae954', class: "mrd-invoice-view__title" }, t('invoice_title', this.locale), " ", invoiceNumber), this.renderStatus()), h("div", { key: 'd209bc34d989146b5f510f2bcdc4c484d723378c', class: "mrd-invoice-view__dates" }, invoiceDateRaw != null && invoiceDateRaw !== '' && (h("span", { key: '8fffcd1ab10e511c9d939c351ea93e4d8a902688' }, t('invoice_date', this.locale), ": ", formatDate(invoiceDateRaw, this.locale))), dueDateRaw != null && dueDateRaw !== '' && (h("span", { key: '8d13c6660798108cc2f54137c8415173326d5bf2' }, t('invoice_due_date', this.locale), ": ", formatDate(dueDateRaw, this.locale)))), this.renderContainer()), h("div", { key: 'cb08c6fd7e6b46a46a69f11aafa960ab5cb35544', class: "mrd-invoice-view__parties" }, this.renderPartyLink('customer', t('invoice_customer', this.locale)), this.renderPartyLink('supplier', t('invoice_supplier', this.locale))), hasLines && (h("div", { key: '8321e74171fe933a4e10fc202b66cd3720ba959e', class: "mrd-invoice-view__lines" }, h("slot", { key: 'eb31d97080173413e74e5b0024984a4b06aa5bdd', name: "lines" }))), this.renderAmounts(), this.renderAttachments())));
110
+ return (h(Host, { key: '8005640e6d13004ae2fdf5f48129214fbc8c55fc' }, h("div", { key: '992f925691e2455c8888df76f93176cec5866210', class: "mrd-invoice-view" }, h("div", { key: 'aa418658cfe830be4e0f8bf77af42a898c9170db', class: "mrd-invoice-view__header" }, h("div", { key: 'ce10fef2072c26a0eb8f7ead620cb460af6646f0', class: "mrd-invoice-view__title-row" }, invoiceNumber && h("h1", { key: '992486cd5dc0bfb9761bdc94bcd237e6bd6e3d24', class: "mrd-invoice-view__title" }, t('invoice_title', this.locale), " ", invoiceNumber), this.renderStatus()), h("div", { key: 'a8c5d2516b737d4dcd5d0f966aadcda4d47a63ad', class: "mrd-invoice-view__dates" }, invoiceDateRaw != null && invoiceDateRaw !== '' && (h("span", { key: 'dd728929fc408c280ad81e212bdfac5905cda02d' }, t('invoice_date', this.locale), ": ", formatDate(invoiceDateRaw, this.locale))), dueDateRaw != null && dueDateRaw !== '' && (h("span", { key: 'd4226d5cc37f0152950f44a3b63a88f0454919bd' }, t('invoice_due_date', this.locale), ": ", formatDate(dueDateRaw, this.locale)))), this.renderContainer()), h("div", { key: 'c40b00c852d005963be7b5006e13804e72ba032a', class: "mrd-invoice-view__parties" }, this.renderPartyLink('customer', t('invoice_customer', this.locale)), this.renderPartyLink('supplier', t('invoice_supplier', this.locale))), hasLines && (h("div", { key: '000e991c64daa582194631b2eac6b1acba418e97', class: "mrd-invoice-view__lines" }, h("slot", { key: '97ba2acb750137eeb5ed6b5e9e5d277f638d4f0a', name: "lines" }))), this.renderAmounts(), this.renderAttachments())));
111
111
  }
112
112
  static get is() { return "mrd-invoice-view"; }
113
113
  static get encapsulation() { return "scoped"; }