@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
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var index = require('./index-DVbdkYO3.js');
4
- var cellRenderer = require('./cell-renderer-7KX9Qbml.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
  };
@@ -277,7 +493,7 @@ function attachmentsKey(attachments) {
277
493
  return attachments.map(a => a.href).join('|');
278
494
  }
279
495
 
280
- const mrdDocumentContainerCss = () => `.sc-mrd-document-container-h{display:block}.mrd-document-container__toolbar.sc-mrd-document-container{display:flex;align-items:center;justify-content:flex-end;gap:var(--mrd-space-2);padding:var(--mrd-space-2) 0;border-bottom:1px solid var(--mrd-color-neutral-100)}.mrd-document-container__body--tree.sc-mrd-document-container{border:1px solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);overflow:hidden}.mrd-document-container__action.sc-mrd-document-container{display:inline-flex;align-items:center;gap:var(--mrd-space-2);height:1.625rem;padding:0 var(--mrd-space-3);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-700);background:var(--mrd-color-white);border:1px solid var(--mrd-color-neutral-200);border-radius:var(--mrd-border-radius);cursor:pointer;transition:background var(--mrd-transition-fast), border-color var(--mrd-transition-fast)}.mrd-document-container__action.sc-mrd-document-container svg.sc-mrd-document-container{width:1rem;height:1rem;color:var(--mrd-color-folder)}.mrd-document-container__action.sc-mrd-document-container:hover:not(:disabled){background:var(--mrd-color-neutral-50);border-color:var(--mrd-color-neutral-300)}.mrd-document-container__action.sc-mrd-document-container:disabled{opacity:0.5;cursor:not-allowed}.mrd-document-container__seg.sc-mrd-document-container{display:inline-flex;gap:2px;padding:2px;background:var(--mrd-color-neutral-100);border-radius:var(--mrd-border-radius)}.mrd-document-container__seg-btn.sc-mrd-document-container{width:1.875rem;height:1.625rem;display:grid;place-items:center;border:none;background:none;border-radius:var(--mrd-border-radius-sm);color:var(--mrd-color-neutral-500);cursor:pointer;transition:color var(--mrd-transition-fast), background var(--mrd-transition-fast)}.mrd-document-container__seg-btn.sc-mrd-document-container:hover{color:var(--mrd-color-neutral-800)}.mrd-document-container__seg-btn[aria-pressed=true].sc-mrd-document-container{background:var(--mrd-color-white);color:var(--mrd-color-primary-dark);box-shadow:var(--mrd-shadow-sm)}.mrd-document-container__seg-btn.sc-mrd-document-container svg.sc-mrd-document-container{width:1rem;height:1rem}`;
496
+ const mrdDocumentContainerCss = () => `.sc-mrd-document-container-h{display:block}.mrd-document-container__toolbar.sc-mrd-document-container{display:flex;align-items:center;justify-content:flex-end;gap:var(--mrd-space-2);padding:var(--mrd-space-2) 0;border-bottom:1px solid var(--mrd-color-neutral-100)}.mrd-document-container__body--tree.sc-mrd-document-container{border:1px solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);overflow:hidden}.mrd-document-container__action.sc-mrd-document-container{display:inline-flex;align-items:center;gap:var(--mrd-space-2);height:1.625rem;padding:0 var(--mrd-space-3);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-700);background:var(--mrd-color-white);border:1px solid var(--mrd-color-neutral-200);border-radius:var(--mrd-border-radius);cursor:pointer;transition:background var(--mrd-transition-fast), border-color var(--mrd-transition-fast)}.mrd-document-container__action.sc-mrd-document-container svg.sc-mrd-document-container{width:1rem;height:1rem;color:var(--mrd-color-folder)}.mrd-document-container__action.sc-mrd-document-container:hover:not(:disabled){background:var(--mrd-color-neutral-50);border-color:var(--mrd-color-neutral-300)}.mrd-document-container__action.sc-mrd-document-container:disabled{opacity:0.5;cursor:not-allowed}.mrd-document-container__file-input.sc-mrd-document-container{display:none}.mrd-document-container__seg.sc-mrd-document-container{display:inline-flex;gap:2px;padding:2px;background:var(--mrd-color-neutral-100);border-radius:var(--mrd-border-radius)}.mrd-document-container__seg-btn.sc-mrd-document-container{width:1.875rem;height:1.625rem;display:grid;place-items:center;border:none;background:none;border-radius:var(--mrd-border-radius-sm);color:var(--mrd-color-neutral-500);cursor:pointer;transition:color var(--mrd-transition-fast), background var(--mrd-transition-fast)}.mrd-document-container__seg-btn.sc-mrd-document-container:hover{color:var(--mrd-color-neutral-800)}.mrd-document-container__seg-btn[aria-pressed=true].sc-mrd-document-container{background:var(--mrd-color-white);color:var(--mrd-color-primary-dark);box-shadow:var(--mrd-shadow-sm)}.mrd-document-container__seg-btn.sc-mrd-document-container svg.sc-mrd-document-container{width:1rem;height:1rem}`;
281
497
 
282
498
  const MrdDocumentContainer = class {
283
499
  constructor(hostRef) {
@@ -306,12 +522,28 @@ const MrdDocumentContainer = class {
306
522
  this.mode = 'tree';
307
523
  /** Whether the folder tree currently has a valid target for "New folder". */
308
524
  this.canCreate = false;
525
+ /** Name of that target (folder path, or the container's label), for the upload tooltip. */
526
+ this.targetLabel = '';
309
527
  /** Whether the currently mounted table has been init()'d. Reset on every mode switch. */
310
528
  this.tableInited = false;
311
529
  this.createFolder = () => {
312
530
  var _a;
313
531
  (_a = this.listEl) === null || _a === void 0 ? void 0 : _a.createFolder();
314
532
  };
533
+ this.pickFile = () => {
534
+ var _a;
535
+ (_a = this.fileInputEl) === null || _a === void 0 ? void 0 : _a.click();
536
+ };
537
+ /** One file per upload, matching the drop handler. Reset the input afterwards
538
+ * so picking the same file twice in a row still fires a change event. */
539
+ this.onFilePicked = (e) => {
540
+ var _a, _b;
541
+ const input = e.target;
542
+ const file = (_a = input.files) === null || _a === void 0 ? void 0 : _a[0];
543
+ if (file)
544
+ (_b = this.listEl) === null || _b === void 0 ? void 0 : _b.uploadFile(file);
545
+ input.value = '';
546
+ };
315
547
  }
316
548
  /** The embedded table does not self-load: like every mrd-table it waits for the
317
549
  * host to call init() (which emits mrdLoadPage, and — once page 0 lands —
@@ -336,7 +568,7 @@ const MrdDocumentContainer = class {
336
568
  }
337
569
  // ── Toolbar ────────────────────────────────────────────────────────────────
338
570
  renderToolbar() {
339
- return (index.h("div", { class: "mrd-document-container__toolbar" }, this.mode === 'tree' && (index.h("button", { type: "button", class: "mrd-document-container__action", disabled: !this.canCreate, onClick: this.createFolder }, index.h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, index.h("path", { d: "M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" }), index.h("path", { d: "M12 11v4M10 13h4" })), cellRenderer.t('new_folder', this.locale))), index.h("div", { class: "mrd-document-container__seg", role: "group", "aria-label": cellRenderer.t('doc_view_switch', this.locale) }, index.h("button", { class: "mrd-document-container__seg-btn", "aria-pressed": String(this.mode === 'tree'), title: cellRenderer.t('doc_view_tree', this.locale), "aria-label": cellRenderer.t('doc_view_tree', this.locale), onClick: () => this.setMode('tree') }, index.h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, index.h("path", { d: "M3 5h6M3 12h9M3 19h6" }), index.h("circle", { cx: "18", cy: "5", r: "1.6" }), index.h("circle", { cx: "18", cy: "19", r: "1.6" }), index.h("path", { d: "M16 12h4" }))), index.h("button", { class: "mrd-document-container__seg-btn", "aria-pressed": String(this.mode === 'list'), title: cellRenderer.t('doc_view_list', this.locale), "aria-label": cellRenderer.t('doc_view_list', this.locale), onClick: () => this.setMode('list') }, index.h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, index.h("path", { d: "M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01" }))))));
571
+ return (index.h("div", { class: "mrd-document-container__toolbar" }, this.mode === 'tree' && (index.h("button", { type: "button", class: "mrd-document-container__action", disabled: !this.canCreate, onClick: this.createFolder }, index.h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, index.h("path", { d: "M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" }), index.h("path", { d: "M12 11v4M10 13h4" })), cellRenderer.t('new_folder', this.locale))), this.mode === 'tree' && (index.h("button", { type: "button", class: "mrd-document-container__action", disabled: !this.canCreate, title: this.targetLabel ? `${cellRenderer.t('doc_upload_to', this.locale)} ${this.targetLabel}` : undefined, onClick: this.pickFile }, index.h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, index.h("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }), index.h("path", { d: "M12 3v13M7 8l5-5 5 5" })), cellRenderer.t('doc_upload', this.locale))), index.h("input", { type: "file", class: "mrd-document-container__file-input", ref: el => (this.fileInputEl = el), onChange: this.onFilePicked }), index.h("div", { class: "mrd-document-container__seg", role: "group", "aria-label": cellRenderer.t('doc_view_switch', this.locale) }, index.h("button", { class: "mrd-document-container__seg-btn", "aria-pressed": String(this.mode === 'tree'), title: cellRenderer.t('doc_view_tree', this.locale), "aria-label": cellRenderer.t('doc_view_tree', this.locale), onClick: () => this.setMode('tree') }, index.h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, index.h("path", { d: "M3 5h6M3 12h9M3 19h6" }), index.h("circle", { cx: "18", cy: "5", r: "1.6" }), index.h("circle", { cx: "18", cy: "19", r: "1.6" }), index.h("path", { d: "M16 12h4" }))), index.h("button", { class: "mrd-document-container__seg-btn", "aria-pressed": String(this.mode === 'list'), title: cellRenderer.t('doc_view_list', this.locale), "aria-label": cellRenderer.t('doc_view_list', this.locale), onClick: () => this.setMode('list') }, index.h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, index.h("path", { d: "M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01" }))))));
340
572
  }
341
573
  // ── Bodies ───────────────────────────────────────────────────────────────
342
574
  renderTree() {
@@ -352,6 +584,9 @@ const MrdDocumentContainer = class {
352
584
  }, onMrdCanCreate: (e) => {
353
585
  e.stopPropagation();
354
586
  this.canCreate = e.detail;
587
+ }, onMrdTargetLabel: (e) => {
588
+ e.stopPropagation();
589
+ this.targetLabel = e.detail;
355
590
  }, onMrdUpdateObject: (e) => {
356
591
  e.stopPropagation();
357
592
  this.mrdUpdateObject.emit(e.detail);
@@ -388,7 +623,7 @@ const MrdDocumentContainer = class {
388
623
  }
389
624
  render() {
390
625
  const treeMode = this.mode === 'tree';
391
- return (index.h(index.Host, { key: '4d21f26c956773c63cbf5118394c6afa29d6014d' }, this.renderToolbar(), index.h("div", { key: 'bc070236bf9a7d0eba57aa2cd70fa3ae36cbf5f1', class: {
626
+ return (index.h(index.Host, { key: 'ae948e2458d9087179e850b527802c489067d93f' }, this.renderToolbar(), index.h("div", { key: 'a04e1a78413aa794d0bda551aeb9c6245f1aafa2', class: {
392
627
  'mrd-document-container__body': true,
393
628
  'mrd-document-container__body--tree': treeMode,
394
629
  }, style: treeMode ? { height: `${this.height}px`, overflowY: 'auto' } : {} }, treeMode ? this.renderTree() : this.renderList())));
@@ -641,6 +876,7 @@ const MrdDocumentList = class {
641
876
  this.mrdLoadPage = index.createEvent(this, "mrdLoadPage");
642
877
  this.mrdNavigate = index.createEvent(this, "mrdNavigate");
643
878
  this.mrdCanCreate = index.createEvent(this, "mrdCanCreate");
879
+ this.mrdTargetLabel = index.createEvent(this, "mrdTargetLabel");
644
880
  this.mrdUpdateObject = index.createEvent(this, "mrdUpdateObject");
645
881
  this.mrdUpload = index.createEvent(this, "mrdUpload");
646
882
  this.mrdCreateObject = index.createEvent(this, "mrdCreateObject");
@@ -684,6 +920,8 @@ const MrdDocumentList = class {
684
920
  this.newFolderSeq = 0;
685
921
  /** Last emitted canCreateFolder value, to only emit mrdCanCreate on change. */
686
922
  this.lastCanCreate = false;
923
+ /** Last emitted upload-target label, to only emit mrdTargetLabel on change. */
924
+ this.lastTargetLabel = '';
687
925
  // ── Drag & drop (move a document into another folder) ──────────────────────
688
926
  /** The document row currently being dragged. */
689
927
  this.dragDoc = null;
@@ -857,6 +1095,22 @@ const MrdDocumentList = class {
857
1095
  this.lastCanCreate = can;
858
1096
  this.mrdCanCreate.emit(can);
859
1097
  }
1098
+ const label = this.targetLabel;
1099
+ if (label !== this.lastTargetLabel) {
1100
+ this.lastTargetLabel = label;
1101
+ this.mrdTargetLabel.emit(label);
1102
+ }
1103
+ }
1104
+ /** Human-readable name of the node a new folder or upload lands in — the
1105
+ * folder path when one is selected, otherwise the container's own label.
1106
+ * Empty when there is no target at all. */
1107
+ get targetLabel() {
1108
+ var _a;
1109
+ const resolved = this.resolveTarget();
1110
+ if (!resolved)
1111
+ return '';
1112
+ const { target, container } = resolved;
1113
+ return (_a = folderStringOf(target, container)) !== null && _a !== void 0 ? _a : target.label;
860
1114
  }
861
1115
  // ── Slot field names ─────────────────────────────────────────────────────
862
1116
  get containerField() {
@@ -1130,12 +1384,28 @@ const MrdDocumentList = class {
1130
1384
  this.dropTargetId = null;
1131
1385
  if (!file)
1132
1386
  return;
1387
+ this.beginUpload(file, node, container);
1388
+ }
1389
+ /** Shared by the file drop and the host toolbar's upload button. */
1390
+ beginUpload(file, node, container) {
1133
1391
  this.pendingUpload = { file, node, container };
1134
1392
  node.open = true;
1135
1393
  this.uploadingNodeId = node.id;
1136
1394
  this.bump();
1137
1395
  this.mrdUpload.emit({ file });
1138
1396
  }
1397
+ /** Upload a file into the current target — the selected folder/container, or
1398
+ * the only container when there is just one. Called by the host toolbar
1399
+ * (mrd-document-container). No-op without a target, or while another upload
1400
+ * is still awaiting its setFileReference. */
1401
+ async uploadFile(file) {
1402
+ if (!file || this.pendingUpload)
1403
+ return;
1404
+ const resolved = this.resolveTarget();
1405
+ if (!resolved)
1406
+ return;
1407
+ this.beginUpload(file, resolved.target, resolved.container);
1408
+ }
1139
1409
  /** Host callback with the uploaded file reference. Builds the create payload
1140
1410
  * from the archetype slots and requests the new document. */
1141
1411
  async setFileReference(uri) {
@@ -1270,7 +1540,7 @@ const MrdDocumentList = class {
1270
1540
  body = renderLoadingRow(ctx, 0);
1271
1541
  }
1272
1542
  else if (this.containers.length === 0) {
1273
- body = index.h("div", { key: '308725d741deb384082bd514edd34593f7d662a2', class: "mrd-document-list__empty" }, cellRenderer.t('no_results', this.locale));
1543
+ body = index.h("div", { key: '63604a99fc62d9108f61b8efc126c0cd3e8fc5ed', class: "mrd-document-list__empty" }, cellRenderer.t('no_results', this.locale));
1274
1544
  }
1275
1545
  else if (this.singleContainer) {
1276
1546
  // Dossier context: render the single container's folder tree at the root.
@@ -1288,7 +1558,7 @@ const MrdDocumentList = class {
1288
1558
  else {
1289
1559
  body = this.containers.map(c => renderContainerNode(ctx, c, 0));
1290
1560
  }
1291
- return (index.h(index.Host, { key: '9d5fde912999b57a0f0b737980d59e94f385f11d' }, index.h("div", { key: '17191411c2e626995f08b66bad755342fe3b13ae', class: 'mrd-document-list' + (this.rootDropActive ? ' mrd-document-list--drop-active' : ''), onDragOver: this.onRootDragOver, onDragLeave: this.onRootDragLeave, onDrop: this.onRootDrop }, body)));
1561
+ return (index.h(index.Host, { key: '2a092e3a7483deb1fb30753b0c0428aaf75c303a' }, index.h("div", { key: '2b716c912a272b925a95133de5b1ff2abedd9dbc', class: 'mrd-document-list' + (this.rootDropActive ? ' mrd-document-list--drop-active' : ''), onDragOver: this.onRootDragOver, onDragLeave: this.onRootDragLeave, onDrop: this.onRootDrop }, body)));
1292
1562
  }
1293
1563
  get el() { return index.getElement(this); }
1294
1564
  };
@@ -1407,7 +1677,7 @@ const MrdEmailField = class {
1407
1677
  };
1408
1678
  }
1409
1679
  render() {
1410
- 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 }))));
1411
1681
  }
1412
1682
  };
1413
1683
  MrdEmailField.style = mrdEmailFieldCss();
@@ -4040,7 +4310,7 @@ const MrdField = class {
4040
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))));
4041
4311
  }
4042
4312
  renderLeafField(displayValue) {
4043
- 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;
4044
4314
  const { item, locale } = this;
4045
4315
  const commonProps = {
4046
4316
  name: item.name,
@@ -4065,25 +4335,25 @@ const MrdField = class {
4065
4335
  case clientLayout.ClientLayoutItemFieldDataType.BOOLEAN:
4066
4336
  return (index.h("mrd-boolean-field", Object.assign({}, commonProps, { value: (_l = displayValue) !== null && _l !== void 0 ? _l : false })));
4067
4337
  case clientLayout.ClientLayoutItemFieldDataType.DATE:
4068
- 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 : '' })));
4069
4339
  case clientLayout.ClientLayoutItemFieldDataType.DATETIME:
4070
- 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 : '' })));
4071
4341
  case clientLayout.ClientLayoutItemFieldDataType.TIME:
4072
- 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 : '' })));
4073
4343
  case clientLayout.ClientLayoutItemFieldDataType.EMAIL:
4074
- 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 : '' })));
4075
4345
  case clientLayout.ClientLayoutItemFieldDataType.HYPERLINK:
4076
- 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 : '' })));
4077
4347
  case clientLayout.ClientLayoutItemFieldDataType.LIST:
4078
- 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 : [] })));
4079
4349
  case clientLayout.ClientLayoutItemFieldDataType.FILE:
4080
- 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 })));
4081
4351
  case clientLayout.ClientLayoutItemFieldDataType.IMAGE:
4082
- 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 })));
4083
4353
  case clientLayout.ClientLayoutItemFieldDataType.LONGTEXT:
4084
- 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 : '' })));
4085
4355
  case clientLayout.ClientLayoutItemFieldDataType.SECRET:
4086
- 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 : '' })));
4087
4357
  default:
4088
4358
  return null;
4089
4359
  }
@@ -4279,7 +4549,7 @@ const MrdFileField = class {
4279
4549
  error: hasError,
4280
4550
  disabled: this.disabled || this.zoneBusy,
4281
4551
  });
4282
- 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 }))));
4283
4553
  }
4284
4554
  static get watchers() { return {
4285
4555
  "value": [{
@@ -4548,15 +4818,19 @@ const MrdForm = class {
4548
4818
  }
4549
4819
  }
4550
4820
  }
4551
- /** Extract a plain href string from a form value, which can be a string or
4552
- * a RelationSearchResult-like object with an `id` field. */
4821
+ /** Extract a plain href string from a form value: a string, a
4822
+ * RelationSearchResult-like object (`id`), or the raw API link shape
4823
+ * (`{ href, name }`) hosts spread into `values` for edit mode. */
4553
4824
  getHref(value) {
4825
+ var _a, _b;
4554
4826
  if (!value)
4555
4827
  return '';
4556
4828
  if (typeof value === 'string')
4557
4829
  return value;
4558
- if (typeof value === 'object' && 'id' in value)
4559
- return value.id;
4830
+ if (typeof value === 'object') {
4831
+ const v = value;
4832
+ return (_b = (_a = v.id) !== null && _a !== void 0 ? _a : v.href) !== null && _b !== void 0 ? _b : '';
4833
+ }
4560
4834
  return '';
4561
4835
  }
4562
4836
  collectFields(items) {
@@ -4903,7 +5177,7 @@ const MrdImageField = class {
4903
5177
  error: hasError,
4904
5178
  disabled: this.disabled || this.zoneBusy,
4905
5179
  });
4906
- 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 }))));
4907
5181
  }
4908
5182
  static get watchers() { return {
4909
5183
  "value": [{
@@ -5008,7 +5282,7 @@ const MrdInvoiceView = class {
5008
5282
  const invoiceDateRaw = this.slotValue('invoiceDate');
5009
5283
  const dueDateRaw = this.slotValue('dueDate');
5010
5284
  const hasLines = !!((_b = (_a = this.archetype) === null || _a === void 0 ? void 0 : _a.slots) === null || _b === void 0 ? void 0 : _b['lines']);
5011
- 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())));
5012
5286
  }
5013
5287
  static get watchers() { return {
5014
5288
  "data": [{
@@ -5025,6 +5299,12 @@ function viewKeyFor(item) {
5025
5299
  return (_b = (_a = item.relatedClass) !== null && _a !== void 0 ? _a : item.name) !== null && _b !== void 0 ? _b : '';
5026
5300
  return (_d = (_c = item.dataClass) !== null && _c !== void 0 ? _c : item.name) !== null && _d !== void 0 ? _d : '';
5027
5301
  }
5302
+ /** Whether a FIELD/RELATION item stays visible on an OBJECT_DASHBOARD when it
5303
+ * has no value. Reads the flat API flag, falling back to the nested wrappers. */
5304
+ function showsEmpty(item) {
5305
+ var _a, _b, _c, _d, _e;
5306
+ return (_e = (_c = (_a = item.showEmpty) !== null && _a !== void 0 ? _a : (_b = item.field) === null || _b === void 0 ? void 0 : _b.showEmpty) !== null && _c !== void 0 ? _c : (_d = item.relation) === null || _d === void 0 ? void 0 : _d.showEmpty) !== null && _e !== void 0 ? _e : false;
5307
+ }
5028
5308
  /** Depth-first flatten of the SECTION/GROUP tree. */
5029
5309
  function flattenItems(items) {
5030
5310
  const result = [];
@@ -5150,15 +5430,16 @@ function renderField(ctx, item) {
5150
5430
  if (item.header) {
5151
5431
  return (index.h("h1", { class: "mrd-layout-section__field-header", key: item.name }, typeof renderedValue === 'string' ? renderedValue : rawValue != null ? String(rawValue) : item.label));
5152
5432
  }
5153
- if (renderedValue == null)
5433
+ const isEmpty = renderedValue == null;
5434
+ if (isEmpty && !showsEmpty(item))
5154
5435
  return null;
5155
5436
  const isBlock = item.dataType === clientLayout.ClientLayoutItemFieldDataType.TEXTBLOCK
5156
5437
  || item.dataType === clientLayout.ClientLayoutItemFieldDataType.LONGTEXT
5157
5438
  || item.dataType === clientLayout.ClientLayoutItemFieldDataType.JSON;
5158
- return (index.h("div", { class: `mrd-layout-section__field${isBlock ? ' mrd-layout-section__field--block' : ''}`, key: item.name }, index.h("span", { class: "mrd-layout-section__field-label" }, item.label), index.h("span", { class: "mrd-layout-section__field-value" }, renderedValue, renderHistoryBadge(ctx, item, raw))));
5439
+ return (index.h("div", { class: `mrd-layout-section__field${isBlock ? ' mrd-layout-section__field--block' : ''}${isEmpty ? ' mrd-layout-section__field--empty' : ''}`, key: item.name }, index.h("span", { class: "mrd-layout-section__field-label" }, item.label), index.h("span", { class: "mrd-layout-section__field-value" }, isEmpty ? cellRenderer.t('value_empty', ctx.locale) : renderedValue, renderHistoryBadge(ctx, item, raw))));
5159
5440
  }
5160
5441
 
5161
- const mrdLayoutSectionCss = () => `.sc-mrd-layout-section-h{display:block;width:100%}.mrd-layout-section.sc-mrd-layout-section{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-color-neutral-800)}.mrd-layout-section__field.sc-mrd-layout-section{display:grid;grid-template-columns:200px 1fr;align-items:baseline;gap:0 var(--mrd-space-2);padding:var(--mrd-space-1) 0}.mrd-layout-section__field--block.sc-mrd-layout-section{grid-template-columns:1fr}.mrd-layout-section__field-label.sc-mrd-layout-section{font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-normal);color:var(--mrd-color-neutral-500);padding-top:1px}.mrd-layout-section__field-value.sc-mrd-layout-section{font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-neutral-800);word-break:break-word;display:inline-flex;align-items:center;gap:var(--mrd-space-1)}.mrd-layout-section__history-wrap.sc-mrd-layout-section{position:relative;display:inline-flex;align-items:center}.mrd-layout-section__history-btn.sc-mrd-layout-section{display:inline-flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;padding:0;background:transparent;border:none;border-radius:var(--mrd-border-radius-sm);color:var(--mrd-color-neutral-400);cursor:pointer;flex-shrink:0;transition:color var(--mrd-transition-fast), background-color var(--mrd-transition-fast)}.mrd-layout-section__history-btn.sc-mrd-layout-section:hover{color:var(--mrd-color-neutral-700);background-color:var(--mrd-color-neutral-100)}.mrd-layout-section__history-btn.sc-mrd-layout-section:focus{outline:none;box-shadow:var(--mrd-shadow-focus)}.mrd-layout-section__history-icon.sc-mrd-layout-section{width:0.875rem;height:0.875rem}.mrd-layout-section__history-popover.sc-mrd-layout-section{position:absolute;top:calc(100% + 0.25rem);left:0;min-width:24rem;max-width:24rem;background-color:var(--mrd-color-white);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius-md);box-shadow:var(--mrd-shadow-md);padding:var(--mrd-space-1) 0;z-index:var(--mrd-z-dropdown)}.mrd-layout-section__history-entry.sc-mrd-layout-section{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-normal);color:var(--mrd-color-neutral-700);padding:var(--mrd-space-2) var(--mrd-space-3);line-height:var(--mrd-line-height-normal)}.mrd-layout-section__history-entry.sc-mrd-layout-section:not(:last-child){border-bottom:var(--mrd-border-width) solid var(--mrd-color-neutral-100)}.mrd-layout-section__field-header.sc-mrd-layout-section{font-size:var(--mrd-font-size-2xl);font-weight:var(--mrd-font-weight-bold);color:var(--mrd-color-neutral-900);margin:0 0 var(--mrd-space-4) 0;padding:0}.mrd-layout-section__header.sc-mrd-layout-section{font-size:var(--mrd-font-size-xl);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-neutral-800);margin:var(--mrd-space-4) 0 var(--mrd-space-2) 0;padding:0}.mrd-layout-section__text.sc-mrd-layout-section{font-size:var(--mrd-font-size-base);color:var(--mrd-color-neutral-700);line-height:var(--mrd-line-height-relaxed);margin:var(--mrd-space-2) 0}.mrd-layout-section__navigate.sc-mrd-layout-section{display:inline-flex;align-items:center;gap:var(--mrd-space-2);padding:var(--mrd-space-2) var(--mrd-space-3);background:none;border:1px solid var(--mrd-color-neutral-300);border-radius:var(--mrd-border-radius);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-primary);cursor:pointer;margin:var(--mrd-space-2) 0}.mrd-layout-section__navigate.sc-mrd-layout-section:hover{background-color:var(--mrd-color-primary-light);border-color:var(--mrd-color-primary)}.mrd-layout-section__link.sc-mrd-layout-section{color:var(--mrd-color-primary);text-decoration:none}.mrd-layout-section__link.sc-mrd-layout-section:hover{text-decoration:underline}.mrd-layout-section__relation-link.sc-mrd-layout-section{background:none;border:none;padding:0;font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-primary);cursor:pointer;text-align:left}.mrd-layout-section__relation-link.sc-mrd-layout-section:hover{text-decoration:underline}.mrd-layout-section__download-link.sc-mrd-layout-section{display:inline-flex;align-items:center;gap:var(--mrd-space-1);background:none;border:none;padding:0;font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-primary);cursor:pointer;text-align:left}.mrd-layout-section__download-link.sc-mrd-layout-section:hover{text-decoration:underline;color:var(--mrd-color-primary-dark)}.mrd-layout-section__file-icon.sc-mrd-layout-section{flex-shrink:0;width:1rem;height:1rem}.mrd-layout-section__file-list.sc-mrd-layout-section{display:flex;flex-direction:column;align-items:flex-start;gap:var(--mrd-space-1)}.mrd-layout-section__file-list-item.sc-mrd-layout-section{min-width:0;max-width:100%}.mrd-layout-section__boolean--true.sc-mrd-layout-section{color:var(--mrd-color-success);font-weight:var(--mrd-font-weight-semibold)}.mrd-layout-section__boolean--false.sc-mrd-layout-section{color:var(--mrd-color-neutral-400)}.mrd-layout-section__badge.sc-mrd-layout-section{display:inline-block;font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-medium);padding:2px var(--mrd-space-3);border-radius:10px}.mrd-layout-section__badge-dot-row.sc-mrd-layout-section{display:inline-flex;align-items:center;gap:var(--mrd-space-2)}.mrd-layout-section__badge-dot.sc-mrd-layout-section{display:inline-block;width:10px;height:10px;border-radius:50%;flex-shrink:0}.mrd-layout-section__secret-masked.sc-mrd-layout-section{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-label-color);letter-spacing:0.15em;user-select:none;pointer-events:none}.mrd-layout-section__pre.sc-mrd-layout-section{font-family:var(--mrd-font-family-mono);font-size:var(--mrd-font-size-xs);background-color:var(--mrd-color-neutral-50);border:1px solid var(--mrd-color-neutral-200);border-radius:var(--mrd-border-radius);padding:var(--mrd-space-3);margin:0;max-height:calc(15 * var(--mrd-font-size-xs));overflow-x:auto;overflow-y:auto;white-space:pre-wrap;word-break:break-word}.mrd-layout-section__group.sc-mrd-layout-section{margin:var(--mrd-space-4) 0}.mrd-layout-section__group-title.sc-mrd-layout-section{font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-neutral-500);margin:0 0 var(--mrd-space-2) 0;padding-bottom:0;letter-spacing:0.01em}.mrd-layout-section__related-view.sc-mrd-layout-section{margin:var(--mrd-space-4) 0}.mrd-layout-section__related-view-title.sc-mrd-layout-section{font-size:var(--mrd-font-size-lg);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-neutral-800);margin:0 0 var(--mrd-space-3) 0}.mrd-layout-section__search.sc-mrd-layout-section{position:relative;margin:var(--mrd-space-2) 0}.mrd-layout-section__search-wrap.sc-mrd-layout-section{position:relative}.mrd-layout-section__search-icon.sc-mrd-layout-section{position:absolute;left:var(--mrd-input-padding-x);top:50%;transform:translateY(-50%);width:1rem;height:1rem;color:var(--mrd-color-neutral-400);pointer-events:none}.mrd-layout-section__search-input.sc-mrd-layout-section{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x) var(--mrd-input-padding-y) calc(var(--mrd-input-padding-x) + 1rem + var(--mrd-space-2));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);outline:none;appearance:none;box-sizing:border-box}.mrd-layout-section__search-input.sc-mrd-layout-section:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-layout-section__search-input.sc-mrd-layout-section::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-layout-section__search-results.sc-mrd-layout-section{position:absolute;top:100%;left:0;right:0;background-color:var(--mrd-color-white);border:1px solid var(--mrd-color-neutral-300);border-top:none;border-radius:0 0 var(--mrd-border-radius) var(--mrd-border-radius);box-shadow:var(--mrd-shadow-sm);z-index:100;max-height:300px;overflow-y:auto;list-style:none;margin:0;padding:var(--mrd-space-1) 0}.mrd-layout-section__search-result.sc-mrd-layout-section{margin:0;padding:0}.mrd-layout-section__search-result-btn.sc-mrd-layout-section{display:flex;flex-direction:column;width:100%;padding:var(--mrd-space-2) var(--mrd-space-3);background:none;border:none;text-align:left;cursor:pointer;font-family:var(--mrd-font-family)}.mrd-layout-section__search-result-btn.sc-mrd-layout-section:hover{background-color:var(--mrd-color-primary-light)}.mrd-layout-section__search-result-label.sc-mrd-layout-section{font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-neutral-800)}.mrd-layout-section__search-result-desc.sc-mrd-layout-section{font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-500);margin-top:var(--mrd-space-1)}.mrd-layout-section__image-thumb-btn.sc-mrd-layout-section{background:none;border:none;padding:0;cursor:pointer;display:inline-block;border-radius:var(--mrd-border-radius);overflow:hidden;line-height:0}.mrd-layout-section__image-thumb-btn.sc-mrd-layout-section:hover .mrd-layout-section__image-thumb.sc-mrd-layout-section{opacity:0.85}.mrd-layout-section__image-thumb.sc-mrd-layout-section{display:block;max-width:160px;max-height:100px;border-radius:var(--mrd-border-radius);object-fit:cover;transition:opacity 0.15s}.mrd-layout-section__modal-backdrop.sc-mrd-layout-section{position:fixed;inset:0;background:rgba(0, 0, 0, 0.6);z-index:300;display:flex;align-items:center;justify-content:center}.mrd-layout-section__modal.sc-mrd-layout-section{position:relative;background:var(--mrd-color-white);border-radius:var(--mrd-border-radius);padding:var(--mrd-space-3);max-width:min(90vw, 900px);max-height:90vh;display:flex;align-items:center;justify-content:center;box-shadow:var(--mrd-shadow-lg)}.mrd-layout-section__modal-close.sc-mrd-layout-section{position:absolute;top:var(--mrd-space-2);right:var(--mrd-space-2);background:rgba(0, 0, 0, 0.5);border:none;border-radius:50%;width:28px;height:28px;display:flex;align-items:center;justify-content:center;color:var(--mrd-color-white);cursor:pointer;font-size:var(--mrd-font-size-sm);line-height:1;z-index:1}.mrd-layout-section__modal-close.sc-mrd-layout-section:hover{background:rgba(0, 0, 0, 0.8)}.mrd-layout-section__modal-image.sc-mrd-layout-section{display:block;max-width:100%;max-height:calc(90vh - 2rem);border-radius:var(--mrd-border-radius);object-fit:contain}`;
5442
+ const mrdLayoutSectionCss = () => `.sc-mrd-layout-section-h{display:block;width:100%}.mrd-layout-section.sc-mrd-layout-section{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-color-neutral-800)}.mrd-layout-section__field.sc-mrd-layout-section{display:grid;grid-template-columns:200px 1fr;align-items:baseline;gap:0 var(--mrd-space-2);padding:var(--mrd-space-1) 0}.mrd-layout-section__field--block.sc-mrd-layout-section{grid-template-columns:1fr}.mrd-layout-section__field-label.sc-mrd-layout-section{font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-normal);color:var(--mrd-color-neutral-500);padding-top:1px}.mrd-layout-section__field-value.sc-mrd-layout-section{font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-neutral-800);word-break:break-word;display:inline-flex;align-items:center;gap:var(--mrd-space-1)}.mrd-layout-section__field--empty.sc-mrd-layout-section .mrd-layout-section__field-value.sc-mrd-layout-section{color:var(--mrd-color-neutral-400);font-weight:var(--mrd-font-weight-normal)}.mrd-layout-section__history-wrap.sc-mrd-layout-section{position:relative;display:inline-flex;align-items:center}.mrd-layout-section__history-btn.sc-mrd-layout-section{display:inline-flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;padding:0;background:transparent;border:none;border-radius:var(--mrd-border-radius-sm);color:var(--mrd-color-neutral-400);cursor:pointer;flex-shrink:0;transition:color var(--mrd-transition-fast), background-color var(--mrd-transition-fast)}.mrd-layout-section__history-btn.sc-mrd-layout-section:hover{color:var(--mrd-color-neutral-700);background-color:var(--mrd-color-neutral-100)}.mrd-layout-section__history-btn.sc-mrd-layout-section:focus{outline:none;box-shadow:var(--mrd-shadow-focus)}.mrd-layout-section__history-icon.sc-mrd-layout-section{width:0.875rem;height:0.875rem}.mrd-layout-section__history-popover.sc-mrd-layout-section{position:absolute;top:calc(100% + 0.25rem);left:0;min-width:24rem;max-width:24rem;background-color:var(--mrd-color-white);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius-md);box-shadow:var(--mrd-shadow-md);padding:var(--mrd-space-1) 0;z-index:var(--mrd-z-dropdown)}.mrd-layout-section__history-entry.sc-mrd-layout-section{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-normal);color:var(--mrd-color-neutral-700);padding:var(--mrd-space-2) var(--mrd-space-3);line-height:var(--mrd-line-height-normal)}.mrd-layout-section__history-entry.sc-mrd-layout-section:not(:last-child){border-bottom:var(--mrd-border-width) solid var(--mrd-color-neutral-100)}.mrd-layout-section__field-header.sc-mrd-layout-section{font-size:var(--mrd-font-size-2xl);font-weight:var(--mrd-font-weight-bold);color:var(--mrd-color-neutral-900);margin:0 0 var(--mrd-space-4) 0;padding:0}.mrd-layout-section__header.sc-mrd-layout-section{font-size:var(--mrd-font-size-xl);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-neutral-800);margin:var(--mrd-space-4) 0 var(--mrd-space-2) 0;padding:0}.mrd-layout-section__text.sc-mrd-layout-section{font-size:var(--mrd-font-size-base);color:var(--mrd-color-neutral-700);line-height:var(--mrd-line-height-relaxed);margin:var(--mrd-space-2) 0}.mrd-layout-section__navigate.sc-mrd-layout-section{display:inline-flex;align-items:center;gap:var(--mrd-space-2);padding:var(--mrd-space-2) var(--mrd-space-3);background:none;border:1px solid var(--mrd-color-neutral-300);border-radius:var(--mrd-border-radius);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-primary);cursor:pointer;margin:var(--mrd-space-2) 0}.mrd-layout-section__navigate.sc-mrd-layout-section:hover{background-color:var(--mrd-color-primary-light);border-color:var(--mrd-color-primary)}.mrd-layout-section__link.sc-mrd-layout-section{color:var(--mrd-color-primary);text-decoration:none}.mrd-layout-section__link.sc-mrd-layout-section:hover{text-decoration:underline}.mrd-layout-section__relation-link.sc-mrd-layout-section{background:none;border:none;padding:0;font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-primary);cursor:pointer;text-align:left}.mrd-layout-section__relation-link.sc-mrd-layout-section:hover{text-decoration:underline}.mrd-layout-section__download-link.sc-mrd-layout-section{display:inline-flex;align-items:center;gap:var(--mrd-space-1);background:none;border:none;padding:0;font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-primary);cursor:pointer;text-align:left}.mrd-layout-section__download-link.sc-mrd-layout-section:hover{text-decoration:underline;color:var(--mrd-color-primary-dark)}.mrd-layout-section__file-icon.sc-mrd-layout-section{flex-shrink:0;width:1rem;height:1rem}.mrd-layout-section__file-list.sc-mrd-layout-section{display:flex;flex-direction:column;align-items:flex-start;gap:var(--mrd-space-1)}.mrd-layout-section__file-list-item.sc-mrd-layout-section{min-width:0;max-width:100%}.mrd-layout-section__boolean--true.sc-mrd-layout-section{color:var(--mrd-color-success);font-weight:var(--mrd-font-weight-semibold)}.mrd-layout-section__boolean--false.sc-mrd-layout-section{color:var(--mrd-color-neutral-400)}.mrd-layout-section__badge.sc-mrd-layout-section{display:inline-block;font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-medium);padding:2px var(--mrd-space-3);border-radius:10px}.mrd-layout-section__badge-dot-row.sc-mrd-layout-section{display:inline-flex;align-items:center;gap:var(--mrd-space-2)}.mrd-layout-section__badge-dot.sc-mrd-layout-section{display:inline-block;width:10px;height:10px;border-radius:50%;flex-shrink:0}.mrd-layout-section__secret-masked.sc-mrd-layout-section{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-label-color);letter-spacing:0.15em;user-select:none;pointer-events:none}.mrd-layout-section__pre.sc-mrd-layout-section{font-family:var(--mrd-font-family-mono);font-size:var(--mrd-font-size-xs);background-color:var(--mrd-color-neutral-50);border:1px solid var(--mrd-color-neutral-200);border-radius:var(--mrd-border-radius);padding:var(--mrd-space-3);margin:0;max-height:calc(15 * var(--mrd-font-size-xs));overflow-x:auto;overflow-y:auto;white-space:pre-wrap;word-break:break-word}.mrd-layout-section__group.sc-mrd-layout-section{margin:var(--mrd-space-4) 0}.mrd-layout-section__group-title.sc-mrd-layout-section{font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-neutral-500);margin:0 0 var(--mrd-space-2) 0;padding-bottom:0;letter-spacing:0.01em}.mrd-layout-section__related-view.sc-mrd-layout-section{margin:var(--mrd-space-4) 0}.mrd-layout-section__related-view-title.sc-mrd-layout-section{font-size:var(--mrd-font-size-lg);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-neutral-800);margin:0 0 var(--mrd-space-3) 0}.mrd-layout-section__search.sc-mrd-layout-section{position:relative;margin:var(--mrd-space-2) 0}.mrd-layout-section__search-wrap.sc-mrd-layout-section{position:relative}.mrd-layout-section__search-icon.sc-mrd-layout-section{position:absolute;left:var(--mrd-input-padding-x);top:50%;transform:translateY(-50%);width:1rem;height:1rem;color:var(--mrd-color-neutral-400);pointer-events:none}.mrd-layout-section__search-input.sc-mrd-layout-section{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x) var(--mrd-input-padding-y) calc(var(--mrd-input-padding-x) + 1rem + var(--mrd-space-2));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);outline:none;appearance:none;box-sizing:border-box}.mrd-layout-section__search-input.sc-mrd-layout-section:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-layout-section__search-input.sc-mrd-layout-section::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-layout-section__search-results.sc-mrd-layout-section{position:absolute;top:100%;left:0;right:0;background-color:var(--mrd-color-white);border:1px solid var(--mrd-color-neutral-300);border-top:none;border-radius:0 0 var(--mrd-border-radius) var(--mrd-border-radius);box-shadow:var(--mrd-shadow-sm);z-index:100;max-height:300px;overflow-y:auto;list-style:none;margin:0;padding:var(--mrd-space-1) 0}.mrd-layout-section__search-result.sc-mrd-layout-section{margin:0;padding:0}.mrd-layout-section__search-result-btn.sc-mrd-layout-section{display:flex;flex-direction:column;width:100%;padding:var(--mrd-space-2) var(--mrd-space-3);background:none;border:none;text-align:left;cursor:pointer;font-family:var(--mrd-font-family)}.mrd-layout-section__search-result-btn.sc-mrd-layout-section:hover{background-color:var(--mrd-color-primary-light)}.mrd-layout-section__search-result-label.sc-mrd-layout-section{font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-neutral-800)}.mrd-layout-section__search-result-desc.sc-mrd-layout-section{font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-500);margin-top:var(--mrd-space-1)}.mrd-layout-section__image-thumb-btn.sc-mrd-layout-section{background:none;border:none;padding:0;cursor:pointer;display:inline-block;border-radius:var(--mrd-border-radius);overflow:hidden;line-height:0}.mrd-layout-section__image-thumb-btn.sc-mrd-layout-section:hover .mrd-layout-section__image-thumb.sc-mrd-layout-section{opacity:0.85}.mrd-layout-section__image-thumb.sc-mrd-layout-section{display:block;max-width:160px;max-height:100px;border-radius:var(--mrd-border-radius);object-fit:cover;transition:opacity 0.15s}.mrd-layout-section__modal-backdrop.sc-mrd-layout-section{position:fixed;inset:0;background:rgba(0, 0, 0, 0.6);z-index:300;display:flex;align-items:center;justify-content:center}.mrd-layout-section__modal.sc-mrd-layout-section{position:relative;background:var(--mrd-color-white);border-radius:var(--mrd-border-radius);padding:var(--mrd-space-3);max-width:min(90vw, 900px);max-height:90vh;display:flex;align-items:center;justify-content:center;box-shadow:var(--mrd-shadow-lg)}.mrd-layout-section__modal-close.sc-mrd-layout-section{position:absolute;top:var(--mrd-space-2);right:var(--mrd-space-2);background:rgba(0, 0, 0, 0.5);border:none;border-radius:50%;width:28px;height:28px;display:flex;align-items:center;justify-content:center;color:var(--mrd-color-white);cursor:pointer;font-size:var(--mrd-font-size-sm);line-height:1;z-index:1}.mrd-layout-section__modal-close.sc-mrd-layout-section:hover{background:rgba(0, 0, 0, 0.8)}.mrd-layout-section__modal-image.sc-mrd-layout-section{display:block;max-width:100%;max-height:calc(90vh - 2rem);border-radius:var(--mrd-border-radius);object-fit:contain}`;
5162
5443
 
5163
5444
  const MrdLayoutSection = class {
5164
5445
  constructor(hostRef) {
@@ -5344,19 +5625,18 @@ const MrdLayoutSection = class {
5344
5625
  return null;
5345
5626
  const links = ((_b = (_a = this.data) === null || _a === void 0 ? void 0 : _a._links) !== null && _b !== void 0 ? _b : {});
5346
5627
  const link = links[item.name];
5347
- if (!link)
5348
- return null;
5349
5628
  const makeBtn = (href, name) => (index.h("button", { key: href, class: "mrd-layout-section__relation-link", onClick: () => this.mrdNavigate.emit({ href, label: name }) }, name));
5350
5629
  let valueContent;
5351
- if ((_c = link.values) === null || _c === void 0 ? void 0 : _c.length) {
5630
+ if ((_c = link === null || link === void 0 ? void 0 : link.values) === null || _c === void 0 ? void 0 : _c.length) {
5352
5631
  valueContent = link.values.map(v => makeBtn(v.href, v.name));
5353
5632
  }
5354
- else if (link.name) {
5633
+ else if (link === null || link === void 0 ? void 0 : link.name) {
5355
5634
  valueContent = makeBtn(link.href, link.name);
5356
5635
  }
5357
- if (!valueContent)
5636
+ const isEmpty = !valueContent;
5637
+ if (isEmpty && !showsEmpty(item))
5358
5638
  return null;
5359
- return (index.h("div", { class: "mrd-layout-section__field", key: item.name }, index.h("span", { class: "mrd-layout-section__field-label" }, item.label), index.h("span", { class: "mrd-layout-section__field-value" }, valueContent)));
5639
+ return (index.h("div", { class: `mrd-layout-section__field${isEmpty ? ' mrd-layout-section__field--empty' : ''}`, key: item.name }, index.h("span", { class: "mrd-layout-section__field-label" }, item.label), index.h("span", { class: "mrd-layout-section__field-value" }, isEmpty ? cellRenderer.t('value_empty', this.locale) : valueContent)));
5360
5640
  }
5361
5641
  renderSearch(item) {
5362
5642
  var _a, _b, _c;
@@ -5530,7 +5810,7 @@ const MrdLayoutSection = class {
5530
5810
  const docArchetype = clientLayout.resolveArchetype(this.archetypes, clientLayout.ARCHETYPE_DOCUMENT);
5531
5811
  const invoiceArchetype = !docArchetype ? clientLayout.resolveArchetype(this.archetypes, clientLayout.ARCHETYPE_INVOICE) : undefined;
5532
5812
  const emailArchetype = !docArchetype && !invoiceArchetype ? clientLayout.resolveArchetype(this.archetypes, clientLayout.ARCHETYPE_EMAIL) : undefined;
5533
- return (index.h(index.Host, { key: '0078764a136e7ca9561632718c1b527ec3bc01c5' }, index.h("div", { key: '0c1428ce20bd7d2bbce467a36b6c25ffa0e6367e', 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()));
5534
5814
  }
5535
5815
  get el() { return index.getElement(this); }
5536
5816
  static get watchers() { return {
@@ -5649,7 +5929,7 @@ const MrdLongtextField = class {
5649
5929
  };
5650
5930
  }
5651
5931
  render() {
5652
- 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 }))));
5653
5933
  }
5654
5934
  };
5655
5935
  MrdLongtextField.style = mrdLongtextFieldCss();
@@ -5672,10 +5952,13 @@ const MrdNumberField = class {
5672
5952
  this.decimalPrecision = 2;
5673
5953
  this.displayValue = '';
5674
5954
  this.error = '';
5955
+ /** While focused the user owns the text; prop updates must not overwrite it. */
5956
+ this.focused = false;
5675
5957
  this.handleInput = (e) => {
5676
5958
  this.displayValue = e.target.value;
5677
5959
  };
5678
5960
  this.handleBlur = (e) => {
5961
+ this.focused = false;
5679
5962
  const raw = e.target.value;
5680
5963
  const parsed = cellRenderer.parseLocalizedNumber(raw, this.locale);
5681
5964
  if (this.required && (parsed === null || raw === '')) {
@@ -5694,17 +5977,30 @@ const MrdNumberField = class {
5694
5977
  this.mrdBlur.emit({ name: this.name, value: parsed });
5695
5978
  };
5696
5979
  this.handleFocus = () => {
5697
- // Show raw number on focus
5698
- if (this.value !== null && this.value !== undefined) {
5699
- const str = String(this.value);
5700
- 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 });
5701
5986
  }
5702
5987
  };
5703
5988
  }
5704
5989
  componentWillLoad() {
5705
- if (this.value !== null && this.value !== undefined) {
5706
- this.displayValue = this.formatForDisplay(this.value);
5707
- }
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) : '';
5708
6004
  }
5709
6005
  formatForDisplay(val) {
5710
6006
  if (this.dataType === clientLayout.ClientLayoutItemFieldDataType.PERCENTAGE) {
@@ -5725,8 +6021,16 @@ const MrdNumberField = class {
5725
6021
  const hasError = !!this.error;
5726
6022
  const suffix = this.dataType === clientLayout.ClientLayoutItemFieldDataType.PERCENTAGE ? '%' :
5727
6023
  this.dataType === clientLayout.ClientLayoutItemFieldDataType.DECIMAL ? '' : '';
5728
- 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 }))));
5729
6025
  }
6026
+ static get watchers() { return {
6027
+ "value": [{
6028
+ "valueChanged": 0
6029
+ }],
6030
+ "locale": [{
6031
+ "localeChanged": 0
6032
+ }]
6033
+ }; }
5730
6034
  };
5731
6035
  MrdNumberField.style = mrdNumberFieldCss();
5732
6036
 
@@ -5856,16 +6160,22 @@ const MrdRelationField = class {
5856
6160
  async setAllRecords(records) {
5857
6161
  this.allRecords = records;
5858
6162
  }
6163
+ /** Href of the current single value. Accepts both a RelationSearchResult
6164
+ * (`id`) and the raw API link shape (`{ href, name }`) a host puts in the
6165
+ * form values for edit mode — same tolerance as `toSearchResult()`. */
5859
6166
  getValueHref() {
5860
- var _a, _b, _c;
6167
+ var _a, _b, _c, _d;
5861
6168
  const v = Array.isArray(this.value) ? ((_a = this.value[0]) !== null && _a !== void 0 ? _a : '') : ((_b = this.value) !== null && _b !== void 0 ? _b : '');
5862
6169
  if (!v)
5863
6170
  return '';
5864
6171
  if (typeof v === 'object')
5865
- return (_c = v.id) !== null && _c !== void 0 ? _c : '';
6172
+ return (_d = (_c = v.id) !== null && _c !== void 0 ? _c : v.href) !== null && _d !== void 0 ? _d : '';
5866
6173
  return v;
5867
6174
  }
5868
- allRecordsChanged() {
6175
+ /** Push the current value onto the rendered <select>. Options and value arrive
6176
+ * independently in edit mode (fetched records vs. the async `values` prop), so
6177
+ * this runs on both — whichever lands last completes the preselection. */
6178
+ syncDropdownSelection() {
5869
6179
  if (this.editBehavior !== clientLayout.ClientLayoutItemRelationEditBehavior.DROPDOWN)
5870
6180
  return;
5871
6181
  const current = this.getValueHref();
@@ -5881,6 +6191,9 @@ const MrdRelationField = class {
5881
6191
  select.value = current;
5882
6192
  }, 0);
5883
6193
  }
6194
+ allRecordsChanged() {
6195
+ this.syncDropdownSelection();
6196
+ }
5884
6197
  async setSearchResults(results) {
5885
6198
  this.searchResults = results;
5886
6199
  this.isLoading = false;
@@ -5932,6 +6245,7 @@ const MrdRelationField = class {
5932
6245
  // (host pre-fill). Plain href strings from user interaction are ignored.
5933
6246
  valueChanged(newValue) {
5934
6247
  this.applyValuePrefill(newValue);
6248
+ this.syncDropdownSelection();
5935
6249
  }
5936
6250
  componentDidLoad() {
5937
6251
  // Only emit when there is no commonRelation dependency — the form orchestrates those.
@@ -6003,9 +6317,9 @@ const MrdSecretField = class {
6003
6317
  };
6004
6318
  }
6005
6319
  render() {
6006
- 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
6007
6321
  ? (index.h("span", { class: "mrd-secret-field__masked", "aria-label": this.label }, this.value ? '••••••••' : ''))
6008
- : (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 }))));
6009
6323
  }
6010
6324
  };
6011
6325
  MrdSecretField.style = mrdSecretFieldCss();
@@ -7333,7 +7647,7 @@ const MrdTextField = class {
7333
7647
  };
7334
7648
  }
7335
7649
  render() {
7336
- 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 }))));
7337
7651
  }
7338
7652
  };
7339
7653
  MrdTextField.style = mrdTextFieldCss();
@@ -7405,7 +7719,7 @@ const MrdTextareaField = class {
7405
7719
  return purify.sanitize(html);
7406
7720
  }
7407
7721
  render() {
7408
- 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 }))));
7409
7723
  }
7410
7724
  get el() { return index.getElement(this); }
7411
7725
  };
@@ -7436,7 +7750,7 @@ const MrdTimeField = class {
7436
7750
  };
7437
7751
  }
7438
7752
  render() {
7439
- 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 }))));
7440
7754
  }
7441
7755
  };
7442
7756
  MrdTimeField.style = mrdTimeFieldCss();