@mmlogic/components 0.1.9 → 0.1.11

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 (45) hide show
  1. package/README.md +196 -61
  2. package/dist/cjs/format-DBr-GTvS.js +308 -0
  3. package/dist/cjs/loader.cjs.js +1 -1
  4. package/dist/cjs/mosterdcomponents.cjs.js +1 -1
  5. package/dist/cjs/mrd-boolean-field_16.cjs.entry.js +108 -117
  6. package/dist/cjs/mrd-table.cjs.entry.js +318 -62
  7. package/dist/collection/components/mrd-field/mrd-field.js +26 -2
  8. package/dist/collection/components/mrd-file-field/mrd-file-field.js +70 -2
  9. package/dist/collection/components/mrd-file-field/mrd-file-field.scss +13 -0
  10. package/dist/collection/components/mrd-form/mrd-form.js +28 -1
  11. package/dist/collection/components/mrd-image-field/mrd-image-field.js +71 -2
  12. package/dist/collection/components/mrd-image-field/mrd-image-field.scss +26 -2
  13. package/dist/collection/components/mrd-table/mrd-table.js +386 -62
  14. package/dist/collection/components/mrd-table/mrd-table.scss +388 -0
  15. package/dist/collection/dev/app.js +48 -4
  16. package/dist/collection/dev/sprites.svg +55 -0
  17. package/dist/collection/utils/i18n.js +144 -0
  18. package/dist/components/i18n.js +1 -1
  19. package/dist/components/mrd-field2.js +1 -1
  20. package/dist/components/mrd-file-field2.js +1 -1
  21. package/dist/components/mrd-form.js +1 -1
  22. package/dist/components/mrd-image-field2.js +1 -1
  23. package/dist/components/mrd-table.js +1 -1
  24. package/dist/esm/format-EzhfM0uw.js +299 -0
  25. package/dist/esm/loader.js +1 -1
  26. package/dist/esm/mosterdcomponents.js +1 -1
  27. package/dist/esm/mrd-boolean-field_16.entry.js +82 -91
  28. package/dist/esm/mrd-table.entry.js +318 -62
  29. package/dist/mosterdcomponents/mosterdcomponents.esm.js +1 -1
  30. package/dist/mosterdcomponents/p-27f6947a.entry.js +1 -0
  31. package/dist/mosterdcomponents/p-EzhfM0uw.js +1 -0
  32. package/dist/mosterdcomponents/p-ca5f9919.entry.js +1 -0
  33. package/dist/types/components/mrd-field/mrd-field.d.ts +5 -0
  34. package/dist/types/components/mrd-file-field/mrd-file-field.d.ts +10 -0
  35. package/dist/types/components/mrd-form/mrd-form.d.ts +5 -0
  36. package/dist/types/components/mrd-image-field/mrd-image-field.d.ts +10 -0
  37. package/dist/types/components/mrd-table/mrd-table.d.ts +52 -18
  38. package/dist/types/components.d.ts +53 -3
  39. package/dist/types/utils/cell-renderer.d.ts +27 -0
  40. package/package.json +1 -1
  41. package/dist/cjs/format-CDw-zie_.js +0 -82
  42. package/dist/esm/format-Dt-aHxkM.js +0 -74
  43. package/dist/mosterdcomponents/p-2a8cb2eb.entry.js +0 -1
  44. package/dist/mosterdcomponents/p-Dt-aHxkM.js +0 -1
  45. package/dist/mosterdcomponents/p-baf08615.entry.js +0 -1
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var index = require('./index-BPj2cBXs.js');
4
+ var format = require('./format-DBr-GTvS.js');
4
5
  var index$1 = require('./index.cjs.js');
5
- var format = require('./format-CDw-zie_.js');
6
6
 
7
7
  const mrdBooleanFieldScss = () => `.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)}`;
8
8
 
@@ -35,87 +35,6 @@ const MrdBooleanField = class {
35
35
  };
36
36
  MrdBooleanField.style = mrdBooleanFieldScss();
37
37
 
38
- const translations = {
39
- nl: {
40
- required: 'Dit veld is verplicht',
41
- select_placeholder: 'Selecteer een optie',
42
- search_placeholder: 'Zoeken...',
43
- upload_file: 'Bestand uploaden',
44
- choose_file: 'Bestand kiezen',
45
- clear: 'Wissen',
46
- today: 'Vandaag',
47
- invalid_email: 'Voer een geldig e-mailadres in',
48
- invalid_url: 'Voer een geldige URL in',
49
- invalid_number: 'Voer een geldig getal in',
50
- drop_file_here: 'Sleep bestand hierheen of',
51
- browse: 'bladeren',
52
- file_too_large: 'Bestand is te groot',
53
- search_results: 'Zoekresultaten',
54
- no_results: 'Geen resultaten gevonden',
55
- loading: 'Laden...',
56
- submit: 'Opslaan',
57
- cancel: 'Annuleren',
58
- remove: 'Verwijderen',
59
- add: 'Toevoegen',
60
- yes: 'Ja',
61
- no: 'Nee',
62
- },
63
- en: {
64
- required: 'This field is required',
65
- select_placeholder: 'Select an option',
66
- search_placeholder: 'Search...',
67
- upload_file: 'Upload file',
68
- choose_file: 'Choose file',
69
- clear: 'Clear',
70
- today: 'Today',
71
- invalid_email: 'Please enter a valid email address',
72
- invalid_url: 'Please enter a valid URL',
73
- invalid_number: 'Please enter a valid number',
74
- drop_file_here: 'Drop file here or',
75
- browse: 'browse',
76
- file_too_large: 'File is too large',
77
- search_results: 'Search results',
78
- no_results: 'No results found',
79
- loading: 'Loading...',
80
- submit: 'Save',
81
- cancel: 'Cancel',
82
- remove: 'Remove',
83
- add: 'Add',
84
- yes: 'Yes',
85
- no: 'No',
86
- },
87
- ar: {
88
- required: 'هذا الحقل مطلوب',
89
- select_placeholder: 'اختر خياراً',
90
- search_placeholder: 'بحث...',
91
- upload_file: 'رفع ملف',
92
- choose_file: 'اختر ملفاً',
93
- clear: 'مسح',
94
- today: 'اليوم',
95
- invalid_email: 'يرجى إدخال عنوان بريد إلكتروني صحيح',
96
- invalid_url: 'يرجى إدخال رابط صحيح',
97
- invalid_number: 'يرجى إدخال رقم صحيح',
98
- drop_file_here: 'اسحب الملف هنا أو',
99
- browse: 'تصفح',
100
- file_too_large: 'الملف كبير جداً',
101
- search_results: 'نتائج البحث',
102
- no_results: 'لم يتم العثور على نتائج',
103
- loading: 'جار التحميل...',
104
- submit: 'حفظ',
105
- cancel: 'إلغاء',
106
- remove: 'إزالة',
107
- add: 'إضافة',
108
- yes: 'نعم',
109
- no: 'لا',
110
- },
111
- };
112
- function t(key, locale) {
113
- var _a, _b, _c;
114
- const lang = locale.split('-')[0].toLowerCase();
115
- const dict = (_a = translations[lang]) !== null && _a !== void 0 ? _a : translations['en'];
116
- return (_c = (_b = dict[key]) !== null && _b !== void 0 ? _b : translations['en'][key]) !== null && _c !== void 0 ? _c : key;
117
- }
118
-
119
38
  function validateRequired(value) {
120
39
  if (value === null || value === undefined)
121
40
  return false;
@@ -190,7 +109,7 @@ const MrdCurrencyField = class {
190
109
  const raw = e.target.value;
191
110
  const parsed = format.parseLocalizedNumber(raw, this.locale);
192
111
  if (this.required && !validateRequired(raw)) {
193
- this.error = t('required', this.locale);
112
+ this.error = format.t('required', this.locale);
194
113
  }
195
114
  else {
196
115
  this.error = '';
@@ -235,7 +154,7 @@ const MrdDateField = class {
235
154
  this.handleChange = (e) => {
236
155
  const val = e.target.value;
237
156
  if (this.required && !validateRequired(val)) {
238
- this.error = t('required', this.locale);
157
+ this.error = format.t('required', this.locale);
239
158
  }
240
159
  else {
241
160
  this.error = '';
@@ -271,7 +190,7 @@ const MrdDatetimeField = class {
271
190
  this.handleChange = (e) => {
272
191
  const val = e.target.value;
273
192
  if (this.required && !validateRequired(val)) {
274
- this.error = t('required', this.locale);
193
+ this.error = format.t('required', this.locale);
275
194
  }
276
195
  else {
277
196
  this.error = '';
@@ -312,10 +231,10 @@ const MrdEmailField = class {
312
231
  this.handleBlur = (e) => {
313
232
  const val = e.target.value;
314
233
  if (this.required && !validateRequired(val)) {
315
- this.error = t('required', this.locale);
234
+ this.error = format.t('required', this.locale);
316
235
  }
317
236
  else if (val && !validateEmail(val)) {
318
- this.error = t('invalid_email', this.locale);
237
+ this.error = format.t('invalid_email', this.locale);
319
238
  }
320
239
  else {
321
240
  this.error = '';
@@ -337,6 +256,7 @@ const MrdField = class {
337
256
  this.mrdBlur = index.createEvent(this, "mrdBlur");
338
257
  this.mrdSearch = index.createEvent(this, "mrdSearch");
339
258
  this.mrdFetchAll = index.createEvent(this, "mrdFetchAll");
259
+ this.mrdUpload = index.createEvent(this, "mrdUpload");
340
260
  this.locale = navigator.language;
341
261
  this.handleChange = (e) => {
342
262
  e.stopPropagation();
@@ -354,6 +274,10 @@ const MrdField = class {
354
274
  e.stopPropagation();
355
275
  this.mrdFetchAll.emit(e.detail);
356
276
  };
277
+ this.handleUpload = (e) => {
278
+ e.stopPropagation();
279
+ this.mrdUpload.emit(e.detail);
280
+ };
357
281
  }
358
282
  render() {
359
283
  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;
@@ -401,24 +325,26 @@ const MrdField = class {
401
325
  case index$1.ClientLayoutItemFieldDataType.LIST:
402
326
  return (index.h(index.Host, null, index.h("mrd-list-field", Object.assign({}, commonProps, { value: (_0 = value) !== null && _0 !== void 0 ? _0 : '', multiple: (_1 = field.multiple) !== null && _1 !== void 0 ? _1 : false, listItems: (_2 = field.listItems) !== null && _2 !== void 0 ? _2 : [] }))));
403
327
  case index$1.ClientLayoutItemFieldDataType.FILE:
404
- return (index.h(index.Host, null, index.h("mrd-file-field", Object.assign({}, commonProps, { accept: (_3 = field.accept) !== null && _3 !== void 0 ? _3 : '', maxSize: (_4 = field.maxSize) !== null && _4 !== void 0 ? _4 : 0 }))));
328
+ return (index.h(index.Host, null, index.h("mrd-file-field", Object.assign({}, commonProps, { value: value, accept: (_3 = field.accept) !== null && _3 !== void 0 ? _3 : '', maxSize: (_4 = field.maxSize) !== null && _4 !== void 0 ? _4 : 0, onMrdUpload: this.handleUpload }))));
405
329
  case index$1.ClientLayoutItemFieldDataType.IMAGE:
406
- return (index.h(index.Host, null, index.h("mrd-image-field", Object.assign({}, commonProps, { accept: (_5 = field.accept) !== null && _5 !== void 0 ? _5 : 'image/*', maxSize: (_6 = field.maxSize) !== null && _6 !== void 0 ? _6 : 0 }))));
330
+ return (index.h(index.Host, null, index.h("mrd-image-field", Object.assign({}, commonProps, { value: value, accept: (_5 = field.accept) !== null && _5 !== void 0 ? _5 : 'image/*', maxSize: (_6 = field.maxSize) !== null && _6 !== void 0 ? _6 : 0, onMrdUpload: this.handleUpload }))));
407
331
  default:
408
332
  return index.h(index.Host, null);
409
333
  }
410
334
  }
411
335
  };
412
336
 
413
- const mrdFileFieldScss = () => `.sc-mrd-file-field-h{display:block}.mrd-file-field.sc-mrd-file-field{display:flex;flex-direction:column;gap:var(--mrd-space-1);width:100%}.mrd-file-field__label.sc-mrd-file-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-file-field__label--required.sc-mrd-file-field::after{content:' *';color:var(--mrd-color-danger)}.mrd-file-field__zone.sc-mrd-file-field{display:flex;align-items:center;justify-content:center;padding:var(--mrd-space-6);border:2px dashed var(--mrd-border-color);border-radius:var(--mrd-border-radius-md);background-color:var(--mrd-color-neutral-50);cursor:pointer;transition:border-color var(--mrd-transition), background-color var(--mrd-transition);min-height:100px;position:relative}.mrd-file-field__zone.sc-mrd-file-field:hover{border-color:var(--mrd-color-primary);background-color:var(--mrd-color-primary-light)}.mrd-file-field__zone--dragging.sc-mrd-file-field{border-color:var(--mrd-color-primary);background-color:var(--mrd-color-primary-light)}.mrd-file-field__zone--error.sc-mrd-file-field{border-color:var(--mrd-border-color-error)}.mrd-file-field__zone--disabled.sc-mrd-file-field{opacity:0.6;cursor:not-allowed}.mrd-file-field__zone--disabled.sc-mrd-file-field:hover{border-color:var(--mrd-border-color);background-color:var(--mrd-color-neutral-50)}.mrd-file-field__input.sc-mrd-file-field{position:absolute;inset:0;opacity:0;width:100%;height:100%;cursor:pointer;pointer-events:none}.mrd-file-field__prompt.sc-mrd-file-field{display:flex;flex-direction:column;align-items:center;gap:var(--mrd-space-2);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-500);text-align:center}.mrd-file-field__upload-icon.sc-mrd-file-field{width:32px;height:32px;color:var(--mrd-color-neutral-400)}.mrd-file-field__browse.sc-mrd-file-field{color:var(--mrd-color-primary);font-weight:var(--mrd-font-weight-medium);text-decoration:underline}.mrd-file-field__selected.sc-mrd-file-field{display:flex;align-items:center;gap:var(--mrd-space-2);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-700)}.mrd-file-field__icon.sc-mrd-file-field{width:20px;height:20px;color:var(--mrd-color-primary);flex-shrink:0}.mrd-file-field__filename.sc-mrd-file-field{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:200px}.mrd-file-field__clear.sc-mrd-file-field{background:none;border:none;cursor:pointer;color:var(--mrd-color-neutral-400);font-size:var(--mrd-font-size-sm);padding:var(--mrd-space-1);border-radius:var(--mrd-border-radius-sm);line-height:1}.mrd-file-field__clear.sc-mrd-file-field:hover{color:var(--mrd-color-danger);background-color:var(--mrd-color-danger-light)}.mrd-file-field__error.sc-mrd-file-field{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}`;
337
+ const mrdFileFieldScss = () => `.sc-mrd-file-field-h{display:block}.mrd-file-field.sc-mrd-file-field{display:flex;flex-direction:column;gap:var(--mrd-space-1);width:100%}.mrd-file-field__label.sc-mrd-file-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-file-field__label--required.sc-mrd-file-field::after{content:' *';color:var(--mrd-color-danger)}.mrd-file-field__zone.sc-mrd-file-field{display:flex;align-items:center;justify-content:center;padding:var(--mrd-space-6);border:2px dashed var(--mrd-border-color);border-radius:var(--mrd-border-radius-md);background-color:var(--mrd-color-neutral-50);cursor:pointer;transition:border-color var(--mrd-transition), background-color var(--mrd-transition);min-height:100px;position:relative}.mrd-file-field__zone.sc-mrd-file-field:hover{border-color:var(--mrd-color-primary);background-color:var(--mrd-color-primary-light)}.mrd-file-field__zone--dragging.sc-mrd-file-field{border-color:var(--mrd-color-primary);background-color:var(--mrd-color-primary-light)}.mrd-file-field__zone--error.sc-mrd-file-field{border-color:var(--mrd-border-color-error)}.mrd-file-field__zone--disabled.sc-mrd-file-field{opacity:0.6;cursor:not-allowed}.mrd-file-field__zone--disabled.sc-mrd-file-field:hover{border-color:var(--mrd-border-color);background-color:var(--mrd-color-neutral-50)}.mrd-file-field__input.sc-mrd-file-field{position:absolute;inset:0;opacity:0;width:100%;height:100%;cursor:pointer;pointer-events:none}.mrd-file-field__prompt.sc-mrd-file-field{display:flex;flex-direction:column;align-items:center;gap:var(--mrd-space-2);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-500);text-align:center}.mrd-file-field__upload-icon.sc-mrd-file-field{width:32px;height:32px;color:var(--mrd-color-neutral-400)}.mrd-file-field__browse.sc-mrd-file-field{color:var(--mrd-color-primary);font-weight:var(--mrd-font-weight-medium);text-decoration:underline}.mrd-file-field__selected.sc-mrd-file-field{display:flex;align-items:center;gap:var(--mrd-space-2);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-700)}.mrd-file-field__icon.sc-mrd-file-field{width:20px;height:20px;color:var(--mrd-color-primary);flex-shrink:0}.mrd-file-field__filename.sc-mrd-file-field{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:200px}.mrd-file-field__clear.sc-mrd-file-field{background:none;border:none;cursor:pointer;color:var(--mrd-color-neutral-400);font-size:var(--mrd-font-size-sm);padding:var(--mrd-space-1);border-radius:var(--mrd-border-radius-sm);line-height:1}.mrd-file-field__clear.sc-mrd-file-field:hover{color:var(--mrd-color-danger);background-color:var(--mrd-color-danger-light)}.mrd-file-field__spinner.sc-mrd-file-field{display:inline-block;flex-shrink:0;width:18px;height:18px;border:2px solid var(--mrd-color-neutral-300);border-top-color:var(--mrd-color-primary);border-radius:50%;animation:mrd-file-spin 0.6s linear infinite}@keyframes mrd-file-spin{to{transform:rotate(360deg)}}.mrd-file-field__error.sc-mrd-file-field{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}`;
414
338
 
415
339
  const MrdFileField = class {
416
340
  constructor(hostRef) {
417
341
  index.registerInstance(this, hostRef);
418
342
  this.mrdChange = index.createEvent(this, "mrdChange");
419
343
  this.mrdBlur = index.createEvent(this, "mrdBlur");
344
+ this.mrdUpload = index.createEvent(this, "mrdUpload");
420
345
  this.name = '';
421
346
  this.label = '';
347
+ this.value = null;
422
348
  this.required = false;
423
349
  this.disabled = false;
424
350
  this.locale = navigator.language;
@@ -426,6 +352,7 @@ const MrdFileField = class {
426
352
  this.maxSize = 0; // bytes, 0 = no limit
427
353
  this.fileName = '';
428
354
  this.isDragging = false;
355
+ this.uploading = false;
429
356
  this.error = '';
430
357
  this.handleInputChange = (e) => {
431
358
  var _a;
@@ -448,7 +375,7 @@ const MrdFileField = class {
448
375
  };
449
376
  this.handleZoneClick = () => {
450
377
  var _a;
451
- if (!this.disabled) {
378
+ if (!this.disabled && !this.uploading) {
452
379
  (_a = this.fileInputRef) === null || _a === void 0 ? void 0 : _a.click();
453
380
  }
454
381
  };
@@ -456,29 +383,55 @@ const MrdFileField = class {
456
383
  e.stopPropagation();
457
384
  this.fileName = '';
458
385
  this.error = '';
386
+ this.uploading = false;
459
387
  if (this.fileInputRef)
460
388
  this.fileInputRef.value = '';
461
389
  this.mrdChange.emit({ name: this.name, value: null });
462
390
  };
463
391
  }
392
+ /** When the host provides a URI back via setFieldValue, the upload is done. */
393
+ valueChanged(newVal) {
394
+ if (typeof newVal === 'string' && newVal) {
395
+ this.uploading = false;
396
+ }
397
+ else if (!newVal) {
398
+ this.uploading = false;
399
+ this.fileName = '';
400
+ }
401
+ }
464
402
  handleFile(file) {
465
403
  if (!file) {
466
404
  this.fileName = '';
405
+ this.uploading = false;
467
406
  this.mrdChange.emit({ name: this.name, value: null });
468
407
  return;
469
408
  }
470
409
  if (this.maxSize > 0 && file.size > this.maxSize) {
471
- this.error = t('file_too_large', this.locale);
410
+ this.error = format.t('file_too_large', this.locale);
472
411
  return;
473
412
  }
474
413
  this.error = '';
475
414
  this.fileName = file.name;
415
+ this.uploading = true;
476
416
  this.mrdChange.emit({ name: this.name, value: file });
417
+ this.mrdUpload.emit({ name: this.name, file });
477
418
  }
478
419
  render() {
420
+ const hasFile = this.uploading || (typeof this.value === 'string' && this.value) || this.fileName;
479
421
  const hasError = !!this.error;
480
- return (index.h(index.Host, { key: '6617c70edaf193c204a951ff8116d54742592f84' }, index.h("div", { key: '69a45446da411c1cfdadd9ee7051e3ceea95a2d2', class: "mrd-file-field" }, this.label && (index.h("label", { key: 'ca415565514c5a3829b1e4a446493916bd1b5b17', class: `mrd-file-field__label${this.required ? ' mrd-file-field__label--required' : ''}` }, this.label)), index.h("div", { key: 'abee0fc6a53c9f1266e6ed2d0ec8ab85a20a81ca', class: `mrd-file-field__zone${this.isDragging ? ' mrd-file-field__zone--dragging' : ''}${hasError ? ' mrd-file-field__zone--error' : ''}${this.disabled ? ' mrd-file-field__zone--disabled' : ''}`, onClick: this.handleZoneClick, onDragOver: this.handleDragOver, onDragLeave: this.handleDragLeave, onDrop: this.handleDrop }, index.h("input", { key: 'c1dbca750d4115b7d8ea3dcd9ed3405ed11c93a2', ref: el => (this.fileInputRef = el), class: "mrd-file-field__input", type: "file", name: this.name, accept: this.accept, disabled: this.disabled, required: this.required && !this.fileName, onChange: this.handleInputChange }), this.fileName ? (index.h("div", { class: "mrd-file-field__selected" }, index.h("svg", { class: "mrd-file-field__icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, index.h("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }), index.h("polyline", { points: "14 2 14 8 20 8" })), index.h("span", { class: "mrd-file-field__filename" }, this.fileName), index.h("button", { class: "mrd-file-field__clear", type: "button", onClick: this.handleClear, "aria-label": t('clear', this.locale) }, "\u2715"))) : (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, t('drop_file_here', this.locale), ' ', index.h("span", { class: "mrd-file-field__browse" }, t('browse', this.locale)))))), hasError && index.h("span", { key: '91ef6a6240f139e161288cb812d17e13a619ec89', class: "mrd-file-field__error" }, this.error))));
422
+ const zoneClass = [
423
+ 'mrd-file-field__zone',
424
+ this.isDragging ? 'mrd-file-field__zone--dragging' : '',
425
+ hasError ? 'mrd-file-field__zone--error' : '',
426
+ this.disabled || this.uploading ? 'mrd-file-field__zone--disabled' : '',
427
+ ].filter(Boolean).join(' ');
428
+ return (index.h(index.Host, { key: '2090102df8169226c1e66f87cbc837296e4b55d4' }, index.h("div", { key: '7a37a09df1bfa2eaf28ed04c806ad5f7c0337bb0', class: "mrd-file-field" }, this.label && (index.h("label", { key: '8f1fcb8adbb66b792be902c7c548e50db99b6a53', class: `mrd-file-field__label${this.required ? ' mrd-file-field__label--required' : ''}` }, this.label)), index.h("div", { key: '66d992298f537b24d69ce3ead3dd229f6d124f3d', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.handleDragOver, onDragLeave: this.handleDragLeave, onDrop: this.handleDrop }, index.h("input", { key: '95ba6560e71ee08c6b2526802727b29a18cdc454', ref: el => (this.fileInputRef = el), class: "mrd-file-field__input", type: "file", name: this.name, accept: this.accept, disabled: this.disabled || this.uploading, required: this.required && !hasFile, onChange: this.handleInputChange }), hasFile ? (index.h("div", { class: "mrd-file-field__selected" }, this.uploading ? (index.h("span", { class: "mrd-file-field__spinner", "aria-label": format.t('loading', this.locale) })) : (index.h("svg", { class: "mrd-file-field__icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, index.h("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }), index.h("polyline", { points: "14 2 14 8 20 8" }))), index.h("span", { class: "mrd-file-field__filename" }, this.fileName), !this.uploading && (index.h("button", { class: "mrd-file-field__clear", type: "button", onClick: this.handleClear, "aria-label": format.t('clear', this.locale) }, "\u2715")))) : (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, format.t('drop_file_here', this.locale), ' ', index.h("span", { class: "mrd-file-field__browse" }, format.t('browse', this.locale)))))), hasError && index.h("span", { key: 'a6020e63bebb01e31a980a903f81badd486585aa', class: "mrd-file-field__error" }, this.error))));
481
429
  }
430
+ static get watchers() { return {
431
+ "value": [{
432
+ "valueChanged": 0
433
+ }]
434
+ }; }
482
435
  };
483
436
  MrdFileField.style = mrdFileFieldScss();
484
437
 
@@ -491,6 +444,7 @@ const MrdForm = class {
491
444
  this.mrdCancel = index.createEvent(this, "mrdCancel");
492
445
  this.mrdSearch = index.createEvent(this, "mrdSearch");
493
446
  this.mrdFetchAll = index.createEvent(this, "mrdFetchAll");
447
+ this.mrdUpload = index.createEvent(this, "mrdUpload");
494
448
  this.locale = navigator.language;
495
449
  this.values = {};
496
450
  /**
@@ -554,6 +508,10 @@ const MrdForm = class {
554
508
  e.stopPropagation();
555
509
  this.mrdFetchAll.emit(e.detail);
556
510
  };
511
+ this.handleUpload = (e) => {
512
+ e.stopPropagation();
513
+ this.mrdUpload.emit(e.detail);
514
+ };
557
515
  this.handleSubmit = (e) => {
558
516
  e.preventDefault();
559
517
  this.submitted = true;
@@ -698,7 +656,7 @@ const MrdForm = class {
698
656
  if (!def)
699
657
  continue;
700
658
  if (def.required && !validateRequired(this.formValues[def.name])) {
701
- newErrors[def.name] = t('required', this.locale);
659
+ newErrors[def.name] = format.t('required', this.locale);
702
660
  }
703
661
  }
704
662
  this.errors = newErrors;
@@ -717,6 +675,9 @@ const MrdForm = class {
717
675
  if (item.type === index$1.ClientLayoutItemType.FIELD && item.field) {
718
676
  const name = item.field.name;
719
677
  const value = this.formValues[name];
678
+ // Skip file/image fields that are still uploading (value is a File object)
679
+ if (value instanceof File)
680
+ continue;
720
681
  // Omit empty strings for optional fields
721
682
  if (value !== '')
722
683
  payload[name] = value !== null && value !== void 0 ? value : null;
@@ -746,7 +707,7 @@ const MrdForm = class {
746
707
  }
747
708
  const fieldName = (_d = (_b = (_a = item.field) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : (_c = item.relation) === null || _c === void 0 ? void 0 : _c.name) !== null && _d !== void 0 ? _d : '';
748
709
  const fieldValue = this.formValues[fieldName];
749
- return (index.h("div", { class: "mrd-form__field" }, index.h("mrd-field", { item: item, locale: this.locale, value: fieldValue, onMrdChange: this.handleFieldChange, onMrdBlur: this.handleFieldChange, onMrdSearch: this.handleSearch, onMrdFetchAll: this.handleFetchAll }), this.errors[fieldName] && (index.h("span", { class: "mrd-form__field-error" }, this.errors[fieldName]))));
710
+ return (index.h("div", { class: "mrd-form__field" }, index.h("mrd-field", { item: item, locale: this.locale, value: fieldValue, onMrdChange: this.handleFieldChange, onMrdBlur: this.handleFieldChange, onMrdSearch: this.handleSearch, onMrdFetchAll: this.handleFetchAll, onMrdUpload: this.handleUpload }), this.errors[fieldName] && (index.h("span", { class: "mrd-form__field-error" }, this.errors[fieldName]))));
750
711
  });
751
712
  }
752
713
  render() {
@@ -754,7 +715,7 @@ const MrdForm = class {
754
715
  return index.h(index.Host, null);
755
716
  }
756
717
  const dir = this.locale.startsWith('ar') ? 'rtl' : 'ltr';
757
- return (index.h(index.Host, null, index.h("form", { class: "mrd-form", dir: dir, onSubmit: this.handleSubmit, noValidate: true }, this.layout.title && index.h("h2", { class: "mrd-form__title" }, this.layout.title), index.h("div", { class: "mrd-form__body" }, this.renderItems(this.layout.items)), index.h("div", { class: "mrd-form__footer" }, index.h("button", { type: "submit", class: "mrd-form__submit" }, t('submit', this.locale)), this.showCancel && (index.h("button", { type: "button", class: "mrd-form__cancel", onClick: () => this.mrdCancel.emit() }, t('cancel', this.locale)))))));
718
+ return (index.h(index.Host, null, index.h("form", { class: "mrd-form", dir: dir, onSubmit: this.handleSubmit, noValidate: true }, this.layout.title && index.h("h2", { class: "mrd-form__title" }, this.layout.title), index.h("div", { class: "mrd-form__body" }, this.renderItems(this.layout.items)), index.h("div", { class: "mrd-form__footer" }, index.h("button", { type: "submit", class: "mrd-form__submit" }, format.t('submit', this.locale)), this.showCancel && (index.h("button", { type: "button", class: "mrd-form__cancel", onClick: () => this.mrdCancel.emit() }, format.t('cancel', this.locale)))))));
758
719
  }
759
720
  static get watchers() { return {
760
721
  "values": [{
@@ -786,10 +747,10 @@ const MrdHyperlinkField = class {
786
747
  this.handleBlur = (e) => {
787
748
  const val = e.target.value;
788
749
  if (this.required && !validateRequired(val)) {
789
- this.error = t('required', this.locale);
750
+ this.error = format.t('required', this.locale);
790
751
  }
791
752
  else if (val && !validateUrl(val)) {
792
- this.error = t('invalid_url', this.locale);
753
+ this.error = format.t('invalid_url', this.locale);
793
754
  }
794
755
  else {
795
756
  this.error = '';
@@ -804,15 +765,17 @@ const MrdHyperlinkField = class {
804
765
  };
805
766
  MrdHyperlinkField.style = mrdHyperlinkFieldScss();
806
767
 
807
- const mrdImageFieldScss = () => `.sc-mrd-image-field-h{display:block}.mrd-image-field.sc-mrd-image-field{display:flex;flex-direction:column;gap:var(--mrd-space-1);width:100%}.mrd-image-field__label.sc-mrd-image-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-image-field__label--required.sc-mrd-image-field::after{content:' *';color:var(--mrd-color-danger)}.mrd-image-field__zone.sc-mrd-image-field{display:flex;align-items:center;justify-content:center;border:2px dashed var(--mrd-border-color);border-radius:var(--mrd-border-radius-md);background-color:var(--mrd-color-neutral-50);cursor:pointer;transition:border-color var(--mrd-transition), background-color var(--mrd-transition);min-height:100px;position:relative}.mrd-image-field__zone.sc-mrd-image-field:hover{border-color:var(--mrd-color-primary);background-color:var(--mrd-color-primary-light)}.mrd-image-field__zone--dragging.sc-mrd-image-field{border-color:var(--mrd-color-primary);background-color:var(--mrd-color-primary-light)}.mrd-image-field__zone--error.sc-mrd-image-field{border-color:var(--mrd-border-color-error)}.mrd-image-field__zone--disabled.sc-mrd-image-field{opacity:0.6;cursor:not-allowed}.mrd-image-field__zone--disabled.sc-mrd-image-field:hover{border-color:var(--mrd-border-color);background-color:var(--mrd-color-neutral-50)}.mrd-image-field__input.sc-mrd-image-field{position:absolute;inset:0;opacity:0;width:100%;height:100%;pointer-events:none}.mrd-image-field__prompt.sc-mrd-image-field{display:flex;flex-direction:column;align-items:center;gap:var(--mrd-space-2);padding:var(--mrd-space-6);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-500);text-align:center}.mrd-image-field__upload-icon.sc-mrd-image-field{width:40px;height:40px;color:var(--mrd-color-neutral-400)}.mrd-image-field__browse.sc-mrd-image-field{color:var(--mrd-color-primary);font-weight:var(--mrd-font-weight-medium);text-decoration:underline}.mrd-image-field__preview-container.sc-mrd-image-field{display:flex;align-items:center;gap:var(--mrd-space-4);padding:var(--mrd-space-4);width:100%}.mrd-image-field__preview-thumb.sc-mrd-image-field{flex-shrink:0;width:80px;height:80px;border-radius:var(--mrd-border-radius);overflow:hidden;border:var(--mrd-border-width) solid var(--mrd-border-color);background-color:var(--mrd-color-neutral-100)}.mrd-image-field__preview.sc-mrd-image-field{width:100%;height:100%;object-fit:cover;display:block}.mrd-image-field__preview-info.sc-mrd-image-field{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--mrd-space-1)}.mrd-image-field__preview-name.sc-mrd-image-field{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-neutral-800);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mrd-image-field__overlay.sc-mrd-image-field{display:none}.mrd-image-field__clear.sc-mrd-image-field{flex-shrink:0;background-color:var(--mrd-color-white);color:var(--mrd-color-danger);border:var(--mrd-border-width) solid var(--mrd-color-danger);border-radius:var(--mrd-border-radius);padding:var(--mrd-space-1) var(--mrd-space-3);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-medium);cursor:pointer;transition:background-color var(--mrd-transition), color var(--mrd-transition)}.mrd-image-field__clear.sc-mrd-image-field:hover{background-color:var(--mrd-color-danger);color:var(--mrd-color-white)}.mrd-image-field__error.sc-mrd-image-field{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}`;
768
+ const mrdImageFieldScss = () => `.sc-mrd-image-field-h{display:block}.mrd-image-field.sc-mrd-image-field{display:flex;flex-direction:column;gap:var(--mrd-space-1);width:100%}.mrd-image-field__label.sc-mrd-image-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-image-field__label--required.sc-mrd-image-field::after{content:' *';color:var(--mrd-color-danger)}.mrd-image-field__zone.sc-mrd-image-field{display:flex;align-items:center;justify-content:center;border:2px dashed var(--mrd-border-color);border-radius:var(--mrd-border-radius-md);background-color:var(--mrd-color-neutral-50);cursor:pointer;transition:border-color var(--mrd-transition), background-color var(--mrd-transition);min-height:100px;position:relative}.mrd-image-field__zone.sc-mrd-image-field:hover{border-color:var(--mrd-color-primary);background-color:var(--mrd-color-primary-light)}.mrd-image-field__zone--dragging.sc-mrd-image-field{border-color:var(--mrd-color-primary);background-color:var(--mrd-color-primary-light)}.mrd-image-field__zone--error.sc-mrd-image-field{border-color:var(--mrd-border-color-error)}.mrd-image-field__zone--disabled.sc-mrd-image-field{opacity:0.6;cursor:not-allowed}.mrd-image-field__zone--disabled.sc-mrd-image-field:hover{border-color:var(--mrd-border-color);background-color:var(--mrd-color-neutral-50)}.mrd-image-field__input.sc-mrd-image-field{position:absolute;inset:0;opacity:0;width:100%;height:100%;pointer-events:none}.mrd-image-field__prompt.sc-mrd-image-field{display:flex;flex-direction:column;align-items:center;gap:var(--mrd-space-2);padding:var(--mrd-space-6);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-500);text-align:center}.mrd-image-field__upload-icon.sc-mrd-image-field{width:40px;height:40px;color:var(--mrd-color-neutral-400)}.mrd-image-field__browse.sc-mrd-image-field{color:var(--mrd-color-primary);font-weight:var(--mrd-font-weight-medium);text-decoration:underline}.mrd-image-field__preview-container.sc-mrd-image-field{display:flex;align-items:center;gap:var(--mrd-space-4);padding:var(--mrd-space-4);width:100%}.mrd-image-field__preview-thumb.sc-mrd-image-field{flex-shrink:0;width:80px;height:80px;border-radius:var(--mrd-border-radius);overflow:hidden;border:var(--mrd-border-width) solid var(--mrd-border-color);background-color:var(--mrd-color-neutral-100)}.mrd-image-field__preview.sc-mrd-image-field{width:100%;height:100%;object-fit:cover;display:block}.mrd-image-field__preview-info.sc-mrd-image-field{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--mrd-space-1)}.mrd-image-field__preview-name.sc-mrd-image-field{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-neutral-800);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mrd-image-field__preview-overlay.sc-mrd-image-field{position:absolute;inset:0;background:rgb(255 255 255 / 0.7);display:flex;align-items:center;justify-content:center;border-radius:var(--mrd-border-radius)}.mrd-image-field__spinner.sc-mrd-image-field{display:inline-block;width:24px;height:24px;border:2px solid var(--mrd-color-neutral-300);border-top-color:var(--mrd-color-primary);border-radius:50%;animation:mrd-image-spin 0.6s linear infinite}@keyframes mrd-image-spin{to{transform:rotate(360deg)}}.mrd-image-field__upload-status.sc-mrd-image-field{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-500)}.mrd-image-field__clear.sc-mrd-image-field{flex-shrink:0;background-color:var(--mrd-color-white);color:var(--mrd-color-danger);border:var(--mrd-border-width) solid var(--mrd-color-danger);border-radius:var(--mrd-border-radius);padding:var(--mrd-space-1) var(--mrd-space-3);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-medium);cursor:pointer;transition:background-color var(--mrd-transition), color var(--mrd-transition)}.mrd-image-field__clear.sc-mrd-image-field:hover{background-color:var(--mrd-color-danger);color:var(--mrd-color-white)}.mrd-image-field__error.sc-mrd-image-field{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}`;
808
769
 
809
770
  const MrdImageField = class {
810
771
  constructor(hostRef) {
811
772
  index.registerInstance(this, hostRef);
812
773
  this.mrdChange = index.createEvent(this, "mrdChange");
813
774
  this.mrdBlur = index.createEvent(this, "mrdBlur");
775
+ this.mrdUpload = index.createEvent(this, "mrdUpload");
814
776
  this.name = '';
815
777
  this.label = '';
778
+ this.value = null;
816
779
  this.required = false;
817
780
  this.disabled = false;
818
781
  this.locale = navigator.language;
@@ -821,6 +784,7 @@ const MrdImageField = class {
821
784
  this.previewUrl = '';
822
785
  this.fileName = '';
823
786
  this.isDragging = false;
787
+ this.uploading = false;
824
788
  this.error = '';
825
789
  this.handleInputChange = (e) => {
826
790
  var _a;
@@ -843,7 +807,7 @@ const MrdImageField = class {
843
807
  };
844
808
  this.handleZoneClick = () => {
845
809
  var _a;
846
- if (!this.disabled) {
810
+ if (!this.disabled && !this.uploading) {
847
811
  (_a = this.fileInputRef) === null || _a === void 0 ? void 0 : _a.click();
848
812
  }
849
813
  };
@@ -852,20 +816,33 @@ const MrdImageField = class {
852
816
  this.previewUrl = '';
853
817
  this.fileName = '';
854
818
  this.error = '';
819
+ this.uploading = false;
855
820
  if (this.fileInputRef)
856
821
  this.fileInputRef.value = '';
857
822
  this.mrdChange.emit({ name: this.name, value: null });
858
823
  };
859
824
  }
825
+ /** When the host provides a URI back via setFieldValue, the upload is done. */
826
+ valueChanged(newVal) {
827
+ if (typeof newVal === 'string' && newVal) {
828
+ this.uploading = false;
829
+ }
830
+ else if (!newVal) {
831
+ this.uploading = false;
832
+ this.previewUrl = '';
833
+ this.fileName = '';
834
+ }
835
+ }
860
836
  handleFile(file) {
861
837
  if (!file) {
862
838
  this.previewUrl = '';
863
839
  this.fileName = '';
840
+ this.uploading = false;
864
841
  this.mrdChange.emit({ name: this.name, value: null });
865
842
  return;
866
843
  }
867
844
  if (this.maxSize > 0 && file.size > this.maxSize) {
868
- this.error = t('file_too_large', this.locale);
845
+ this.error = format.t('file_too_large', this.locale);
869
846
  return;
870
847
  }
871
848
  if (!file.type.startsWith('image/')) {
@@ -874,6 +851,8 @@ const MrdImageField = class {
874
851
  }
875
852
  this.error = '';
876
853
  this.fileName = file.name;
854
+ this.uploading = true;
855
+ // Show local preview immediately while upload is in progress
877
856
  const reader = new FileReader();
878
857
  reader.onload = (ev) => {
879
858
  var _a;
@@ -881,11 +860,23 @@ const MrdImageField = class {
881
860
  };
882
861
  reader.readAsDataURL(file);
883
862
  this.mrdChange.emit({ name: this.name, value: file });
863
+ this.mrdUpload.emit({ name: this.name, file });
884
864
  }
885
865
  render() {
886
866
  const hasError = !!this.error;
887
- return (index.h(index.Host, { key: 'c188d49744b7044d46b6c6f42126032f1ecc8a8f' }, index.h("div", { key: '53990650a5109172addca5ae274b180569b08860', class: "mrd-image-field" }, this.label && (index.h("label", { key: '3dc78faca422fcafed31833a11307cace9f2ff13', class: `mrd-image-field__label${this.required ? ' mrd-image-field__label--required' : ''}` }, this.label)), index.h("div", { key: '4ca9eb1362c999721742ac3d727326078fe844c7', class: `mrd-image-field__zone${this.isDragging ? ' mrd-image-field__zone--dragging' : ''}${hasError ? ' mrd-image-field__zone--error' : ''}${this.disabled ? ' mrd-image-field__zone--disabled' : ''}`, onClick: this.handleZoneClick, onDragOver: this.handleDragOver, onDragLeave: this.handleDragLeave, onDrop: this.handleDrop }, index.h("input", { key: '9e3a237ffb69ce9f6fb20e6b3e603e4db453e7e9', ref: el => (this.fileInputRef = el), class: "mrd-image-field__input", type: "file", name: this.name, accept: this.accept, disabled: this.disabled, required: this.required && !this.previewUrl, onChange: this.handleInputChange }), this.previewUrl ? (index.h("div", { class: "mrd-image-field__preview-container" }, index.h("div", { class: "mrd-image-field__preview-thumb" }, index.h("img", { class: "mrd-image-field__preview", src: this.previewUrl, alt: this.fileName })), index.h("div", { class: "mrd-image-field__preview-info" }, index.h("span", { class: "mrd-image-field__preview-name" }, this.fileName)), index.h("button", { class: "mrd-image-field__clear", type: "button", onClick: this.handleClear, "aria-label": t('clear', this.locale) }, t('remove', this.locale)))) : (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, t('drop_file_here', this.locale), ' ', index.h("span", { class: "mrd-image-field__browse" }, t('browse', this.locale)))))), hasError && index.h("span", { key: '85cf998e1ab26cce7fbf87836df25672971a4eb1', class: "mrd-image-field__error" }, this.error))));
867
+ const zoneClass = [
868
+ 'mrd-image-field__zone',
869
+ this.isDragging ? 'mrd-image-field__zone--dragging' : '',
870
+ hasError ? 'mrd-image-field__zone--error' : '',
871
+ this.disabled || this.uploading ? 'mrd-image-field__zone--disabled' : '',
872
+ ].filter(Boolean).join(' ');
873
+ return (index.h(index.Host, { key: '76b5a36a7f5a420ded3400c8a1481843363d1cbe' }, index.h("div", { key: '3544df84aaf427a25518bafe13d60cf89ed28537', class: "mrd-image-field" }, this.label && (index.h("label", { key: 'dca64c1600cb98526eb4b91a908106087f099ad1', class: `mrd-image-field__label${this.required ? ' mrd-image-field__label--required' : ''}` }, this.label)), index.h("div", { key: 'ce07f32126f0956e47ff6fc41ff231590e0503d3', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.handleDragOver, onDragLeave: this.handleDragLeave, onDrop: this.handleDrop }, index.h("input", { key: '660fbae5f730834c465522a11dd674fc8e50a54e', ref: el => (this.fileInputRef = el), class: "mrd-image-field__input", type: "file", name: this.name, accept: this.accept, disabled: this.disabled || this.uploading, required: this.required && !this.previewUrl, onChange: this.handleInputChange }), this.previewUrl ? (index.h("div", { class: "mrd-image-field__preview-container" }, index.h("div", { class: "mrd-image-field__preview-thumb" }, index.h("img", { class: "mrd-image-field__preview", src: this.previewUrl, alt: this.fileName }), this.uploading && index.h("div", { class: "mrd-image-field__preview-overlay" }, index.h("span", { class: "mrd-image-field__spinner" }))), index.h("div", { class: "mrd-image-field__preview-info" }, index.h("span", { class: "mrd-image-field__preview-name" }, this.fileName), this.uploading && (index.h("span", { class: "mrd-image-field__upload-status" }, format.t('loading', this.locale)))), !this.uploading && (index.h("button", { class: "mrd-image-field__clear", type: "button", onClick: this.handleClear, "aria-label": format.t('clear', this.locale) }, format.t('remove', this.locale))))) : (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, format.t('drop_file_here', this.locale), ' ', index.h("span", { class: "mrd-image-field__browse" }, format.t('browse', this.locale)))))), hasError && index.h("span", { key: '9b8f9563fea63bd12c38f5c480e9cbd24106c3af', class: "mrd-image-field__error" }, this.error))));
888
874
  }
875
+ static get watchers() { return {
876
+ "value": [{
877
+ "valueChanged": 0
878
+ }]
879
+ }; }
889
880
  };
890
881
  MrdImageField.style = mrdImageFieldScss();
891
882
 
@@ -913,7 +904,7 @@ const MrdListField = class {
913
904
  const vals = Array.from(select.selectedOptions).map(o => o.value);
914
905
  this.selected = vals;
915
906
  if (this.required && !validateRequired(vals)) {
916
- this.error = t('required', this.locale);
907
+ this.error = format.t('required', this.locale);
917
908
  }
918
909
  else {
919
910
  this.error = '';
@@ -923,7 +914,7 @@ const MrdListField = class {
923
914
  else {
924
915
  const val = select.value;
925
916
  if (this.required && !validateRequired(val)) {
926
- this.error = t('required', this.locale);
917
+ this.error = format.t('required', this.locale);
927
918
  }
928
919
  else {
929
920
  this.error = '';
@@ -943,7 +934,7 @@ const MrdListField = class {
943
934
  this.selected = [...this.selected, key];
944
935
  }
945
936
  if (this.required && !validateRequired(this.selected)) {
946
- this.error = t('required', this.locale);
937
+ this.error = format.t('required', this.locale);
947
938
  }
948
939
  else {
949
940
  this.error = '';
@@ -976,7 +967,7 @@ const MrdListField = class {
976
967
  return (index.h("label", { key: lv.key, class: "mrd-list-field__checkbox-item" }, index.h("input", { type: "checkbox", checked: this.selected.includes(lv.key), disabled: this.disabled, onChange: () => this.toggleCheckbox(lv.key) }), (lv.color || lv.backgroundColor) && (index.h("span", { class: "mrd-list-field__color-dot", style: { backgroundColor: (_b = (_a = lv.backgroundColor) !== null && _a !== void 0 ? _a : lv.color) !== null && _b !== void 0 ? _b : '' } })), index.h("span", null, lv.label)));
977
968
  })), hasError && index.h("span", { class: "mrd-list-field__error" }, this.error))));
978
969
  }
979
- return (index.h(index.Host, null, index.h("div", { class: "mrd-list-field" }, this.label && (index.h("label", { class: `mrd-list-field__label${this.required ? ' mrd-list-field__label--required' : ''}` }, this.label)), index.h("select", { class: `mrd-list-field__select${hasError ? ' mrd-list-field__select--error' : ''}`, name: this.name, required: this.required, disabled: this.disabled, onChange: this.handleSelectChange, onBlur: this.handleBlur }, index.h("option", { value: "" }, t('select_placeholder', this.locale)), this.listItems.map(lv => {
970
+ return (index.h(index.Host, null, index.h("div", { class: "mrd-list-field" }, this.label && (index.h("label", { class: `mrd-list-field__label${this.required ? ' mrd-list-field__label--required' : ''}` }, this.label)), index.h("select", { class: `mrd-list-field__select${hasError ? ' mrd-list-field__select--error' : ''}`, name: this.name, required: this.required, disabled: this.disabled, onChange: this.handleSelectChange, onBlur: this.handleBlur }, index.h("option", { value: "" }, format.t('select_placeholder', this.locale)), this.listItems.map(lv => {
980
971
  var _a, _b;
981
972
  const bg = (_b = (_a = lv.backgroundColor) !== null && _a !== void 0 ? _a : lv.color) !== null && _b !== void 0 ? _b : null;
982
973
  const style = bg ? { backgroundColor: bg, color: this.getContrastColor(bg) } : {};
@@ -1011,10 +1002,10 @@ const MrdNumberField = class {
1011
1002
  const raw = e.target.value;
1012
1003
  const parsed = format.parseLocalizedNumber(raw, this.locale);
1013
1004
  if (this.required && (parsed === null || raw === '')) {
1014
- this.error = t('required', this.locale);
1005
+ this.error = format.t('required', this.locale);
1015
1006
  }
1016
1007
  else if (raw !== '' && !validateNumber(parsed, this.dataType)) {
1017
- this.error = t('invalid_number', this.locale);
1008
+ this.error = format.t('invalid_number', this.locale);
1018
1009
  }
1019
1010
  else {
1020
1011
  this.error = '';
@@ -1164,7 +1155,7 @@ const MrdRelationField = class {
1164
1155
  this.mrdChange.emit({ name: this.name, value: result.id });
1165
1156
  }
1166
1157
  if (this.required && !validateRequired(this.selectedItems)) {
1167
- this.error = t('required', this.locale);
1158
+ this.error = format.t('required', this.locale);
1168
1159
  }
1169
1160
  else {
1170
1161
  this.error = '';
@@ -1178,7 +1169,7 @@ const MrdRelationField = class {
1178
1169
  this.handleDropdownChange = (e) => {
1179
1170
  const val = e.target.value;
1180
1171
  if (this.required && !validateRequired(val)) {
1181
- this.error = t('required', this.locale);
1172
+ this.error = format.t('required', this.locale);
1182
1173
  }
1183
1174
  else {
1184
1175
  this.error = '';
@@ -1242,19 +1233,19 @@ const MrdRelationField = class {
1242
1233
  const hasError = !!this.error;
1243
1234
  if (this.editBehavior === index$1.ClientLayoutItemRelationEditBehavior.DROPDOWN) {
1244
1235
  const currentValue = Array.isArray(this.value) ? ((_a = this.value[0]) !== null && _a !== void 0 ? _a : '') : ((_b = this.value) !== null && _b !== void 0 ? _b : '');
1245
- return (index.h(index.Host, null, index.h("div", { class: "mrd-relation-field" }, this.label && (index.h("label", { class: `mrd-relation-field__label${this.required ? ' mrd-relation-field__label--required' : ''}` }, this.label)), index.h("select", { class: `mrd-relation-field__select${hasError ? ' mrd-relation-field__select--error' : ''}`, name: this.name, required: this.required, disabled: this.disabled, onChange: this.handleDropdownChange }, index.h("option", { value: "" }, t('select_placeholder', this.locale)), this.allRecords.map(record => (index.h("option", { key: record.id, value: record.id, selected: record.id === currentValue }, record.label)))), hasError && index.h("span", { class: "mrd-relation-field__error" }, this.error))));
1236
+ return (index.h(index.Host, null, index.h("div", { class: "mrd-relation-field" }, this.label && (index.h("label", { class: `mrd-relation-field__label${this.required ? ' mrd-relation-field__label--required' : ''}` }, this.label)), index.h("select", { class: `mrd-relation-field__select${hasError ? ' mrd-relation-field__select--error' : ''}`, name: this.name, required: this.required, disabled: this.disabled, onChange: this.handleDropdownChange }, index.h("option", { value: "" }, format.t('select_placeholder', this.locale)), this.allRecords.map(record => (index.h("option", { key: record.id, value: record.id, selected: record.id === currentValue }, record.label)))), hasError && index.h("span", { class: "mrd-relation-field__error" }, this.error))));
1246
1237
  }
1247
1238
  if (this.displayType === index$1.ClientLayoutItemRelationDisplayType.DROPDOWN) {
1248
1239
  const currentValue = Array.isArray(this.value) ? ((_c = this.value[0]) !== null && _c !== void 0 ? _c : '') : ((_d = this.value) !== null && _d !== void 0 ? _d : '');
1249
- return (index.h(index.Host, null, index.h("div", { class: "mrd-relation-field" }, this.label && (index.h("label", { class: `mrd-relation-field__label${this.required ? ' mrd-relation-field__label--required' : ''}` }, this.label)), index.h("select", { class: `mrd-relation-field__select${hasError ? ' mrd-relation-field__select--error' : ''}`, name: this.name, required: this.required, disabled: this.disabled, onChange: this.handleDropdownChange }, index.h("option", { value: "" }, t('select_placeholder', this.locale)), this.dropdownValues.map(dv => (index.h("option", { key: dv.key, value: dv.key, selected: dv.key === currentValue }, dv.label)))), hasError && index.h("span", { class: "mrd-relation-field__error" }, this.error))));
1240
+ return (index.h(index.Host, null, index.h("div", { class: "mrd-relation-field" }, this.label && (index.h("label", { class: `mrd-relation-field__label${this.required ? ' mrd-relation-field__label--required' : ''}` }, this.label)), index.h("select", { class: `mrd-relation-field__select${hasError ? ' mrd-relation-field__select--error' : ''}`, name: this.name, required: this.required, disabled: this.disabled, onChange: this.handleDropdownChange }, index.h("option", { value: "" }, format.t('select_placeholder', this.locale)), this.dropdownValues.map(dv => (index.h("option", { key: dv.key, value: dv.key, selected: dv.key === currentValue }, dv.label)))), hasError && index.h("span", { class: "mrd-relation-field__error" }, this.error))));
1250
1241
  }
1251
1242
  // SEARCH mode
1252
1243
  const labelEl = this.label && (index.h("label", { class: `mrd-relation-field__label${this.required ? ' mrd-relation-field__label--required' : ''}` }, this.label));
1253
1244
  // Single selection: show selected value as a badge, hide the search input
1254
1245
  if (!this.multiple && this.selectedItems.length > 0) {
1255
- return (index.h(index.Host, null, index.h("div", { class: "mrd-relation-field" }, labelEl, index.h("div", { class: `mrd-relation-field__selected-value${hasError ? ' mrd-relation-field__selected-value--error' : ''}` }, index.h("span", { class: "mrd-relation-field__selected-name" }, this.selectedItems[0].label), index.h("button", { type: "button", class: "mrd-relation-field__selected-clear", onClick: this.clearSelection, "aria-label": t('remove', this.locale) }, "\u2715")), hasError && index.h("span", { class: "mrd-relation-field__error" }, this.error))));
1246
+ return (index.h(index.Host, null, index.h("div", { class: "mrd-relation-field" }, labelEl, index.h("div", { class: `mrd-relation-field__selected-value${hasError ? ' mrd-relation-field__selected-value--error' : ''}` }, index.h("span", { class: "mrd-relation-field__selected-name" }, this.selectedItems[0].label), index.h("button", { type: "button", class: "mrd-relation-field__selected-clear", onClick: this.clearSelection, "aria-label": format.t('remove', this.locale) }, "\u2715")), hasError && index.h("span", { class: "mrd-relation-field__error" }, this.error))));
1256
1247
  }
1257
- return (index.h(index.Host, null, index.h("div", { class: "mrd-relation-field" }, labelEl, this.multiple && this.selectedItems.length > 0 && (index.h("div", { class: "mrd-relation-field__tags" }, this.selectedItems.map(item => (index.h("span", { key: item.id, class: "mrd-relation-field__tag" }, item.label, index.h("button", { type: "button", class: "mrd-relation-field__tag-remove", onClick: () => this.handleRemoveSelected(item.id), "aria-label": t('remove', this.locale) }, "\u2715")))))), index.h("div", { class: "mrd-relation-field__search-wrapper" }, index.h("input", { class: `mrd-relation-field__search${hasError ? ' mrd-relation-field__search--error' : ''}`, type: "text", value: this.searchQuery, placeholder: t('search_placeholder', this.locale), disabled: this.disabled, onInput: this.handleSearchInput, onKeyDown: this.handleKeyDown, onBlur: this.handleBlur }), this.isLoading && (index.h("span", { class: "mrd-relation-field__spinner", "aria-label": t('loading', this.locale) }))), this.showResults && (index.h("div", { class: "mrd-relation-field__results" }, this.searchResults.length === 0 && !this.isLoading ? (index.h("div", { class: "mrd-relation-field__no-results" }, t('no_results', this.locale))) : (this.searchResults.map((result, i) => (index.h("div", { key: result.id, class: `mrd-relation-field__result-item${i === this.highlightedIndex ? ' mrd-relation-field__result-item--highlighted' : ''}`, onMouseDown: () => this.handleResultSelect(result) }, index.h("span", { class: "mrd-relation-field__result-label" }, result.label), result.description && (index.h("span", { class: "mrd-relation-field__result-desc" }, result.description)))))))), hasError && index.h("span", { class: "mrd-relation-field__error" }, this.error))));
1248
+ return (index.h(index.Host, null, index.h("div", { class: "mrd-relation-field" }, labelEl, this.multiple && this.selectedItems.length > 0 && (index.h("div", { class: "mrd-relation-field__tags" }, this.selectedItems.map(item => (index.h("span", { key: item.id, class: "mrd-relation-field__tag" }, item.label, index.h("button", { type: "button", class: "mrd-relation-field__tag-remove", onClick: () => this.handleRemoveSelected(item.id), "aria-label": format.t('remove', this.locale) }, "\u2715")))))), index.h("div", { class: "mrd-relation-field__search-wrapper" }, index.h("input", { class: `mrd-relation-field__search${hasError ? ' mrd-relation-field__search--error' : ''}`, type: "text", value: this.searchQuery, placeholder: format.t('search_placeholder', this.locale), disabled: this.disabled, onInput: this.handleSearchInput, onKeyDown: this.handleKeyDown, onBlur: this.handleBlur }), this.isLoading && (index.h("span", { class: "mrd-relation-field__spinner", "aria-label": format.t('loading', this.locale) }))), this.showResults && (index.h("div", { class: "mrd-relation-field__results" }, this.searchResults.length === 0 && !this.isLoading ? (index.h("div", { class: "mrd-relation-field__no-results" }, format.t('no_results', this.locale))) : (this.searchResults.map((result, i) => (index.h("div", { key: result.id, class: `mrd-relation-field__result-item${i === this.highlightedIndex ? ' mrd-relation-field__result-item--highlighted' : ''}`, onMouseDown: () => this.handleResultSelect(result) }, index.h("span", { class: "mrd-relation-field__result-label" }, result.label), result.description && (index.h("span", { class: "mrd-relation-field__result-desc" }, result.description)))))))), hasError && index.h("span", { class: "mrd-relation-field__error" }, this.error))));
1258
1249
  }
1259
1250
  };
1260
1251
  MrdRelationField.style = mrdRelationFieldScss();
@@ -1281,7 +1272,7 @@ const MrdTextField = class {
1281
1272
  this.handleBlur = (e) => {
1282
1273
  const val = e.target.value;
1283
1274
  if (this.required && !validateRequired(val)) {
1284
- this.error = t('required', this.locale);
1275
+ this.error = format.t('required', this.locale);
1285
1276
  }
1286
1277
  else {
1287
1278
  this.error = '';
@@ -1350,7 +1341,7 @@ const MrdTextareaField = class {
1350
1341
  if (!range) {
1351
1342
  const html = (_b = (_a = this.editorEl.querySelector('.ql-editor')) === null || _a === void 0 ? void 0 : _a.innerHTML) !== null && _b !== void 0 ? _b : '';
1352
1343
  if (this.required && !validateRequired(html)) {
1353
- this.error = t('required', this.locale);
1344
+ this.error = format.t('required', this.locale);
1354
1345
  }
1355
1346
  else {
1356
1347
  this.error = '';
@@ -1388,7 +1379,7 @@ const MrdTimeField = class {
1388
1379
  this.handleChange = (e) => {
1389
1380
  const val = e.target.value;
1390
1381
  if (this.required && !validateRequired(val)) {
1391
- this.error = t('required', this.locale);
1382
+ this.error = format.t('required', this.locale);
1392
1383
  }
1393
1384
  else {
1394
1385
  this.error = '';