@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
@@ -19,6 +19,10 @@ export class MrdField {
19
19
  e.stopPropagation();
20
20
  this.mrdFetchAll.emit(e.detail);
21
21
  };
22
+ this.handleUpload = (e) => {
23
+ e.stopPropagation();
24
+ this.mrdUpload.emit(e.detail);
25
+ };
22
26
  }
23
27
  render() {
24
28
  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;
@@ -66,9 +70,9 @@ export class MrdField {
66
70
  case ClientLayoutItemFieldDataType.LIST:
67
71
  return (h(Host, null, 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 : [] }))));
68
72
  case ClientLayoutItemFieldDataType.FILE:
69
- return (h(Host, null, 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 }))));
73
+ return (h(Host, null, 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 }))));
70
74
  case ClientLayoutItemFieldDataType.IMAGE:
71
- return (h(Host, null, 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 }))));
75
+ return (h(Host, null, 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 }))));
72
76
  default:
73
77
  return h(Host, null);
74
78
  }
@@ -201,6 +205,26 @@ export class MrdField {
201
205
  "resolved": "{ name: string; relatedClass: string; mostSignificantClass?: string | undefined; commonRelation?: string | undefined; filter?: string | undefined; filterValue?: string | undefined; }",
202
206
  "references": {}
203
207
  }
208
+ }, {
209
+ "method": "mrdUpload",
210
+ "name": "mrdUpload",
211
+ "bubbles": true,
212
+ "cancelable": true,
213
+ "composed": true,
214
+ "docs": {
215
+ "tags": [],
216
+ "text": ""
217
+ },
218
+ "complexType": {
219
+ "original": "{ name: string; file: File }",
220
+ "resolved": "{ name: string; file: File; }",
221
+ "references": {
222
+ "File": {
223
+ "location": "global",
224
+ "id": "global::File"
225
+ }
226
+ }
227
+ }
204
228
  }];
205
229
  }
206
230
  }
@@ -4,6 +4,7 @@ export class MrdFileField {
4
4
  constructor() {
5
5
  this.name = '';
6
6
  this.label = '';
7
+ this.value = null;
7
8
  this.required = false;
8
9
  this.disabled = false;
9
10
  this.locale = navigator.language;
@@ -11,6 +12,7 @@ export class MrdFileField {
11
12
  this.maxSize = 0; // bytes, 0 = no limit
12
13
  this.fileName = '';
13
14
  this.isDragging = false;
15
+ this.uploading = false;
14
16
  this.error = '';
15
17
  this.handleInputChange = (e) => {
16
18
  var _a;
@@ -33,7 +35,7 @@ export class MrdFileField {
33
35
  };
34
36
  this.handleZoneClick = () => {
35
37
  var _a;
36
- if (!this.disabled) {
38
+ if (!this.disabled && !this.uploading) {
37
39
  (_a = this.fileInputRef) === null || _a === void 0 ? void 0 : _a.click();
38
40
  }
39
41
  };
@@ -41,14 +43,26 @@ export class MrdFileField {
41
43
  e.stopPropagation();
42
44
  this.fileName = '';
43
45
  this.error = '';
46
+ this.uploading = false;
44
47
  if (this.fileInputRef)
45
48
  this.fileInputRef.value = '';
46
49
  this.mrdChange.emit({ name: this.name, value: null });
47
50
  };
48
51
  }
52
+ /** When the host provides a URI back via setFieldValue, the upload is done. */
53
+ valueChanged(newVal) {
54
+ if (typeof newVal === 'string' && newVal) {
55
+ this.uploading = false;
56
+ }
57
+ else if (!newVal) {
58
+ this.uploading = false;
59
+ this.fileName = '';
60
+ }
61
+ }
49
62
  handleFile(file) {
50
63
  if (!file) {
51
64
  this.fileName = '';
65
+ this.uploading = false;
52
66
  this.mrdChange.emit({ name: this.name, value: null });
53
67
  return;
54
68
  }
@@ -58,11 +72,20 @@ export class MrdFileField {
58
72
  }
59
73
  this.error = '';
60
74
  this.fileName = file.name;
75
+ this.uploading = true;
61
76
  this.mrdChange.emit({ name: this.name, value: file });
77
+ this.mrdUpload.emit({ name: this.name, file });
62
78
  }
63
79
  render() {
80
+ const hasFile = this.uploading || (typeof this.value === 'string' && this.value) || this.fileName;
64
81
  const hasError = !!this.error;
65
- return (h(Host, { key: '6617c70edaf193c204a951ff8116d54742592f84' }, h("div", { key: '69a45446da411c1cfdadd9ee7051e3ceea95a2d2', class: "mrd-file-field" }, this.label && (h("label", { key: 'ca415565514c5a3829b1e4a446493916bd1b5b17', class: `mrd-file-field__label${this.required ? ' mrd-file-field__label--required' : ''}` }, this.label)), 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 }, 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 ? (h("div", { class: "mrd-file-field__selected" }, h("svg", { class: "mrd-file-field__icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }), h("polyline", { points: "14 2 14 8 20 8" })), h("span", { class: "mrd-file-field__filename" }, this.fileName), h("button", { class: "mrd-file-field__clear", type: "button", onClick: this.handleClear, "aria-label": t('clear', this.locale) }, "\u2715"))) : (h("div", { class: "mrd-file-field__prompt" }, h("svg", { class: "mrd-file-field__upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("polyline", { points: "16 16 12 12 8 16" }), h("line", { x1: "12", y1: "12", x2: "12", y2: "21" }), h("path", { d: "M20.39 18.39A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.3" })), h("span", null, t('drop_file_here', this.locale), ' ', h("span", { class: "mrd-file-field__browse" }, t('browse', this.locale)))))), hasError && h("span", { key: '91ef6a6240f139e161288cb812d17e13a619ec89', class: "mrd-file-field__error" }, this.error))));
82
+ const zoneClass = [
83
+ 'mrd-file-field__zone',
84
+ this.isDragging ? 'mrd-file-field__zone--dragging' : '',
85
+ hasError ? 'mrd-file-field__zone--error' : '',
86
+ this.disabled || this.uploading ? 'mrd-file-field__zone--disabled' : '',
87
+ ].filter(Boolean).join(' ');
88
+ return (h(Host, { key: '2090102df8169226c1e66f87cbc837296e4b55d4' }, h("div", { key: '7a37a09df1bfa2eaf28ed04c806ad5f7c0337bb0', class: "mrd-file-field" }, this.label && (h("label", { key: '8f1fcb8adbb66b792be902c7c548e50db99b6a53', class: `mrd-file-field__label${this.required ? ' mrd-file-field__label--required' : ''}` }, this.label)), h("div", { key: '66d992298f537b24d69ce3ead3dd229f6d124f3d', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.handleDragOver, onDragLeave: this.handleDragLeave, onDrop: this.handleDrop }, 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 ? (h("div", { class: "mrd-file-field__selected" }, this.uploading ? (h("span", { class: "mrd-file-field__spinner", "aria-label": t('loading', this.locale) })) : (h("svg", { class: "mrd-file-field__icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }), h("polyline", { points: "14 2 14 8 20 8" }))), h("span", { class: "mrd-file-field__filename" }, this.fileName), !this.uploading && (h("button", { class: "mrd-file-field__clear", type: "button", onClick: this.handleClear, "aria-label": t('clear', this.locale) }, "\u2715")))) : (h("div", { class: "mrd-file-field__prompt" }, h("svg", { class: "mrd-file-field__upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("polyline", { points: "16 16 12 12 8 16" }), h("line", { x1: "12", y1: "12", x2: "12", y2: "21" }), h("path", { d: "M20.39 18.39A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.3" })), h("span", null, t('drop_file_here', this.locale), ' ', h("span", { class: "mrd-file-field__browse" }, t('browse', this.locale)))))), hasError && h("span", { key: 'a6020e63bebb01e31a980a903f81badd486585aa', class: "mrd-file-field__error" }, this.error))));
66
89
  }
67
90
  static get is() { return "mrd-file-field"; }
68
91
  static get encapsulation() { return "scoped"; }
@@ -118,6 +141,24 @@ export class MrdFileField {
118
141
  "attribute": "label",
119
142
  "defaultValue": "''"
120
143
  },
144
+ "value": {
145
+ "type": "unknown",
146
+ "mutable": false,
147
+ "complexType": {
148
+ "original": "unknown",
149
+ "resolved": "unknown",
150
+ "references": {}
151
+ },
152
+ "required": false,
153
+ "optional": false,
154
+ "docs": {
155
+ "tags": [],
156
+ "text": ""
157
+ },
158
+ "getter": false,
159
+ "setter": false,
160
+ "defaultValue": "null"
161
+ },
121
162
  "required": {
122
163
  "type": "boolean",
123
164
  "mutable": false,
@@ -224,6 +265,7 @@ export class MrdFileField {
224
265
  return {
225
266
  "fileName": {},
226
267
  "isDragging": {},
268
+ "uploading": {},
227
269
  "error": {}
228
270
  };
229
271
  }
@@ -268,6 +310,32 @@ export class MrdFileField {
268
310
  }
269
311
  }
270
312
  }
313
+ }, {
314
+ "method": "mrdUpload",
315
+ "name": "mrdUpload",
316
+ "bubbles": true,
317
+ "cancelable": true,
318
+ "composed": true,
319
+ "docs": {
320
+ "tags": [],
321
+ "text": "Emitted when a file is selected and needs to be uploaded.\nHost should upload the file and call form.setFieldValue(name, uri) with the result."
322
+ },
323
+ "complexType": {
324
+ "original": "{ name: string; file: File }",
325
+ "resolved": "{ name: string; file: File; }",
326
+ "references": {
327
+ "File": {
328
+ "location": "global",
329
+ "id": "global::File"
330
+ }
331
+ }
332
+ }
333
+ }];
334
+ }
335
+ static get watchers() {
336
+ return [{
337
+ "propName": "value",
338
+ "methodName": "valueChanged"
271
339
  }];
272
340
  }
273
341
  }
@@ -133,6 +133,19 @@
133
133
  background-color: var(--mrd-color-danger-light);
134
134
  }
135
135
 
136
+ .mrd-file-field__spinner {
137
+ display: inline-block;
138
+ flex-shrink: 0;
139
+ width: 18px;
140
+ height: 18px;
141
+ border: 2px solid var(--mrd-color-neutral-300);
142
+ border-top-color: var(--mrd-color-primary);
143
+ border-radius: 50%;
144
+ animation: mrd-file-spin 0.6s linear infinite;
145
+ }
146
+
147
+ @keyframes mrd-file-spin { to { transform: rotate(360deg); } }
148
+
136
149
  .mrd-file-field__error {
137
150
  font-family: var(--mrd-font-family);
138
151
  font-size: var(--mrd-error-font-size);
@@ -67,6 +67,10 @@ export class MrdForm {
67
67
  e.stopPropagation();
68
68
  this.mrdFetchAll.emit(e.detail);
69
69
  };
70
+ this.handleUpload = (e) => {
71
+ e.stopPropagation();
72
+ this.mrdUpload.emit(e.detail);
73
+ };
70
74
  this.handleSubmit = (e) => {
71
75
  e.preventDefault();
72
76
  this.submitted = true;
@@ -230,6 +234,9 @@ export class MrdForm {
230
234
  if (item.type === ClientLayoutItemType.FIELD && item.field) {
231
235
  const name = item.field.name;
232
236
  const value = this.formValues[name];
237
+ // Skip file/image fields that are still uploading (value is a File object)
238
+ if (value instanceof File)
239
+ continue;
233
240
  // Omit empty strings for optional fields
234
241
  if (value !== '')
235
242
  payload[name] = value !== null && value !== void 0 ? value : null;
@@ -259,7 +266,7 @@ export class MrdForm {
259
266
  }
260
267
  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 : '';
261
268
  const fieldValue = this.formValues[fieldName];
262
- return (h("div", { class: "mrd-form__field" }, 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] && (h("span", { class: "mrd-form__field-error" }, this.errors[fieldName]))));
269
+ return (h("div", { class: "mrd-form__field" }, 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] && (h("span", { class: "mrd-form__field-error" }, this.errors[fieldName]))));
263
270
  });
264
271
  }
265
272
  render() {
@@ -485,6 +492,26 @@ export class MrdForm {
485
492
  "resolved": "{ name: string; relatedClass: string; mostSignificantClass?: string | undefined; commonRelation?: string | undefined; filter?: string | undefined; filterValue?: string | undefined; }",
486
493
  "references": {}
487
494
  }
495
+ }, {
496
+ "method": "mrdUpload",
497
+ "name": "mrdUpload",
498
+ "bubbles": true,
499
+ "cancelable": true,
500
+ "composed": true,
501
+ "docs": {
502
+ "tags": [],
503
+ "text": ""
504
+ },
505
+ "complexType": {
506
+ "original": "{ name: string; file: File }",
507
+ "resolved": "{ name: string; file: File; }",
508
+ "references": {
509
+ "File": {
510
+ "location": "global",
511
+ "id": "global::File"
512
+ }
513
+ }
514
+ }
488
515
  }];
489
516
  }
490
517
  static get methods() {
@@ -4,6 +4,7 @@ export class MrdImageField {
4
4
  constructor() {
5
5
  this.name = '';
6
6
  this.label = '';
7
+ this.value = null;
7
8
  this.required = false;
8
9
  this.disabled = false;
9
10
  this.locale = navigator.language;
@@ -12,6 +13,7 @@ export class MrdImageField {
12
13
  this.previewUrl = '';
13
14
  this.fileName = '';
14
15
  this.isDragging = false;
16
+ this.uploading = false;
15
17
  this.error = '';
16
18
  this.handleInputChange = (e) => {
17
19
  var _a;
@@ -34,7 +36,7 @@ export class MrdImageField {
34
36
  };
35
37
  this.handleZoneClick = () => {
36
38
  var _a;
37
- if (!this.disabled) {
39
+ if (!this.disabled && !this.uploading) {
38
40
  (_a = this.fileInputRef) === null || _a === void 0 ? void 0 : _a.click();
39
41
  }
40
42
  };
@@ -43,15 +45,28 @@ export class MrdImageField {
43
45
  this.previewUrl = '';
44
46
  this.fileName = '';
45
47
  this.error = '';
48
+ this.uploading = false;
46
49
  if (this.fileInputRef)
47
50
  this.fileInputRef.value = '';
48
51
  this.mrdChange.emit({ name: this.name, value: null });
49
52
  };
50
53
  }
54
+ /** When the host provides a URI back via setFieldValue, the upload is done. */
55
+ valueChanged(newVal) {
56
+ if (typeof newVal === 'string' && newVal) {
57
+ this.uploading = false;
58
+ }
59
+ else if (!newVal) {
60
+ this.uploading = false;
61
+ this.previewUrl = '';
62
+ this.fileName = '';
63
+ }
64
+ }
51
65
  handleFile(file) {
52
66
  if (!file) {
53
67
  this.previewUrl = '';
54
68
  this.fileName = '';
69
+ this.uploading = false;
55
70
  this.mrdChange.emit({ name: this.name, value: null });
56
71
  return;
57
72
  }
@@ -65,6 +80,8 @@ export class MrdImageField {
65
80
  }
66
81
  this.error = '';
67
82
  this.fileName = file.name;
83
+ this.uploading = true;
84
+ // Show local preview immediately while upload is in progress
68
85
  const reader = new FileReader();
69
86
  reader.onload = (ev) => {
70
87
  var _a;
@@ -72,10 +89,17 @@ export class MrdImageField {
72
89
  };
73
90
  reader.readAsDataURL(file);
74
91
  this.mrdChange.emit({ name: this.name, value: file });
92
+ this.mrdUpload.emit({ name: this.name, file });
75
93
  }
76
94
  render() {
77
95
  const hasError = !!this.error;
78
- return (h(Host, { key: 'c188d49744b7044d46b6c6f42126032f1ecc8a8f' }, h("div", { key: '53990650a5109172addca5ae274b180569b08860', class: "mrd-image-field" }, this.label && (h("label", { key: '3dc78faca422fcafed31833a11307cace9f2ff13', class: `mrd-image-field__label${this.required ? ' mrd-image-field__label--required' : ''}` }, this.label)), 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 }, 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 ? (h("div", { class: "mrd-image-field__preview-container" }, h("div", { class: "mrd-image-field__preview-thumb" }, h("img", { class: "mrd-image-field__preview", src: this.previewUrl, alt: this.fileName })), h("div", { class: "mrd-image-field__preview-info" }, h("span", { class: "mrd-image-field__preview-name" }, this.fileName)), h("button", { class: "mrd-image-field__clear", type: "button", onClick: this.handleClear, "aria-label": t('clear', this.locale) }, t('remove', this.locale)))) : (h("div", { class: "mrd-image-field__prompt" }, h("svg", { class: "mrd-image-field__upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }), h("circle", { cx: "8.5", cy: "8.5", r: "1.5" }), h("polyline", { points: "21 15 16 10 5 21" })), h("span", null, t('drop_file_here', this.locale), ' ', h("span", { class: "mrd-image-field__browse" }, t('browse', this.locale)))))), hasError && h("span", { key: '85cf998e1ab26cce7fbf87836df25672971a4eb1', class: "mrd-image-field__error" }, this.error))));
96
+ const zoneClass = [
97
+ 'mrd-image-field__zone',
98
+ this.isDragging ? 'mrd-image-field__zone--dragging' : '',
99
+ hasError ? 'mrd-image-field__zone--error' : '',
100
+ this.disabled || this.uploading ? 'mrd-image-field__zone--disabled' : '',
101
+ ].filter(Boolean).join(' ');
102
+ return (h(Host, { key: '76b5a36a7f5a420ded3400c8a1481843363d1cbe' }, h("div", { key: '3544df84aaf427a25518bafe13d60cf89ed28537', class: "mrd-image-field" }, this.label && (h("label", { key: 'dca64c1600cb98526eb4b91a908106087f099ad1', class: `mrd-image-field__label${this.required ? ' mrd-image-field__label--required' : ''}` }, this.label)), h("div", { key: 'ce07f32126f0956e47ff6fc41ff231590e0503d3', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.handleDragOver, onDragLeave: this.handleDragLeave, onDrop: this.handleDrop }, 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 ? (h("div", { class: "mrd-image-field__preview-container" }, h("div", { class: "mrd-image-field__preview-thumb" }, h("img", { class: "mrd-image-field__preview", src: this.previewUrl, alt: this.fileName }), this.uploading && h("div", { class: "mrd-image-field__preview-overlay" }, h("span", { class: "mrd-image-field__spinner" }))), h("div", { class: "mrd-image-field__preview-info" }, h("span", { class: "mrd-image-field__preview-name" }, this.fileName), this.uploading && (h("span", { class: "mrd-image-field__upload-status" }, t('loading', this.locale)))), !this.uploading && (h("button", { class: "mrd-image-field__clear", type: "button", onClick: this.handleClear, "aria-label": t('clear', this.locale) }, t('remove', this.locale))))) : (h("div", { class: "mrd-image-field__prompt" }, h("svg", { class: "mrd-image-field__upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }), h("circle", { cx: "8.5", cy: "8.5", r: "1.5" }), h("polyline", { points: "21 15 16 10 5 21" })), h("span", null, t('drop_file_here', this.locale), ' ', h("span", { class: "mrd-image-field__browse" }, t('browse', this.locale)))))), hasError && h("span", { key: '9b8f9563fea63bd12c38f5c480e9cbd24106c3af', class: "mrd-image-field__error" }, this.error))));
79
103
  }
80
104
  static get is() { return "mrd-image-field"; }
81
105
  static get encapsulation() { return "scoped"; }
@@ -131,6 +155,24 @@ export class MrdImageField {
131
155
  "attribute": "label",
132
156
  "defaultValue": "''"
133
157
  },
158
+ "value": {
159
+ "type": "unknown",
160
+ "mutable": false,
161
+ "complexType": {
162
+ "original": "unknown",
163
+ "resolved": "unknown",
164
+ "references": {}
165
+ },
166
+ "required": false,
167
+ "optional": false,
168
+ "docs": {
169
+ "tags": [],
170
+ "text": ""
171
+ },
172
+ "getter": false,
173
+ "setter": false,
174
+ "defaultValue": "null"
175
+ },
134
176
  "required": {
135
177
  "type": "boolean",
136
178
  "mutable": false,
@@ -238,6 +280,7 @@ export class MrdImageField {
238
280
  "previewUrl": {},
239
281
  "fileName": {},
240
282
  "isDragging": {},
283
+ "uploading": {},
241
284
  "error": {}
242
285
  };
243
286
  }
@@ -282,6 +325,32 @@ export class MrdImageField {
282
325
  }
283
326
  }
284
327
  }
328
+ }, {
329
+ "method": "mrdUpload",
330
+ "name": "mrdUpload",
331
+ "bubbles": true,
332
+ "cancelable": true,
333
+ "composed": true,
334
+ "docs": {
335
+ "tags": [],
336
+ "text": "Emitted when an image is selected and needs to be uploaded.\nHost should upload the file and call form.setFieldValue(name, uri) with the result."
337
+ },
338
+ "complexType": {
339
+ "original": "{ name: string; file: File }",
340
+ "resolved": "{ name: string; file: File; }",
341
+ "references": {
342
+ "File": {
343
+ "location": "global",
344
+ "id": "global::File"
345
+ }
346
+ }
347
+ }
348
+ }];
349
+ }
350
+ static get watchers() {
351
+ return [{
352
+ "propName": "value",
353
+ "methodName": "valueChanged"
285
354
  }];
286
355
  }
287
356
  }
@@ -136,8 +136,32 @@
136
136
  white-space: nowrap;
137
137
  }
138
138
 
139
- .mrd-image-field__overlay {
140
- display: none;
139
+ .mrd-image-field__preview-overlay {
140
+ position: absolute;
141
+ inset: 0;
142
+ background: rgb(255 255 255 / 0.7);
143
+ display: flex;
144
+ align-items: center;
145
+ justify-content: center;
146
+ border-radius: var(--mrd-border-radius);
147
+ }
148
+
149
+ .mrd-image-field__spinner {
150
+ display: inline-block;
151
+ width: 24px;
152
+ height: 24px;
153
+ border: 2px solid var(--mrd-color-neutral-300);
154
+ border-top-color: var(--mrd-color-primary);
155
+ border-radius: 50%;
156
+ animation: mrd-image-spin 0.6s linear infinite;
157
+ }
158
+
159
+ @keyframes mrd-image-spin { to { transform: rotate(360deg); } }
160
+
161
+ .mrd-image-field__upload-status {
162
+ font-family: var(--mrd-font-family);
163
+ font-size: var(--mrd-font-size-xs);
164
+ color: var(--mrd-color-neutral-500);
141
165
  }
142
166
 
143
167
  .mrd-image-field__clear {