@mmlogic/components 0.5.2 → 0.5.3

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 (105) hide show
  1. package/dist/cjs/{cell-renderer-CmaO0CZT.js → cell-renderer-7KX9Qbml.js} +122 -1
  2. package/dist/cjs/{client-layout-RZ3Ix-4a.js → client-layout-CqVuJumR.js} +9 -0
  3. package/dist/cjs/{index-DzRfoAPz.js → index-DVbdkYO3.js} +468 -6
  4. package/dist/cjs/index.cjs.js +4 -1
  5. package/dist/cjs/loader.cjs.js +2 -2
  6. package/dist/cjs/mosterdcomponents.cjs.js +2 -2
  7. package/dist/cjs/{mrd-boolean-field_23.cjs.entry.js → mrd-boolean-field_25.cjs.entry.js} +5618 -5225
  8. package/dist/cjs/mrd-merge-view.cjs.entry.js +5 -5
  9. package/dist/collection/collection-manifest.json +2 -0
  10. package/dist/collection/components/documents/mrd-document-view/mrd-document-view.js +7 -8
  11. package/dist/collection/components/email/mrd-email-view/mrd-email-view.css +126 -0
  12. package/dist/collection/components/email/mrd-email-view/mrd-email-view.js +247 -0
  13. package/dist/collection/components/fields/file-upload-common.js +23 -7
  14. package/dist/collection/components/fields/mrd-boolean-field/mrd-boolean-field.js +1 -1
  15. package/dist/collection/components/fields/mrd-currency-field/mrd-currency-field.js +1 -1
  16. package/dist/collection/components/fields/mrd-date-field/mrd-date-field.js +1 -1
  17. package/dist/collection/components/fields/mrd-datetime-field/mrd-datetime-field.js +1 -1
  18. package/dist/collection/components/fields/mrd-email-field/mrd-email-field.js +1 -1
  19. package/dist/collection/components/fields/mrd-file-field/mrd-file-field.css +20 -1
  20. package/dist/collection/components/fields/mrd-file-field/mrd-file-field.js +108 -47
  21. package/dist/collection/components/fields/mrd-image-field/mrd-image-field.css +44 -0
  22. package/dist/collection/components/fields/mrd-image-field/mrd-image-field.js +126 -58
  23. package/dist/collection/components/fields/mrd-longtext-field/mrd-longtext-field.js +1 -1
  24. package/dist/collection/components/fields/mrd-number-field/mrd-number-field.js +1 -1
  25. package/dist/collection/components/fields/mrd-secret-field/mrd-secret-field.js +2 -2
  26. package/dist/collection/components/fields/mrd-text-field/mrd-text-field.js +1 -1
  27. package/dist/collection/components/fields/mrd-textarea-field/mrd-textarea-field.js +1 -1
  28. package/dist/collection/components/fields/mrd-time-field/mrd-time-field.js +1 -1
  29. package/dist/collection/components/form/mrd-field/mrd-field.js +5 -5
  30. package/dist/collection/components/form/mrd-form/mrd-form.js +55 -6
  31. package/dist/collection/components/invoice/mrd-invoice-view/mrd-invoice-view.css +145 -0
  32. package/dist/collection/components/invoice/mrd-invoice-view/mrd-invoice-view.js +281 -0
  33. package/dist/collection/components/layout/mrd-layout-section/field-value.js +5 -1
  34. package/dist/collection/components/layout/mrd-layout-section/mrd-layout-section.css +10 -0
  35. package/dist/collection/components/layout/mrd-layout-section/mrd-layout-section.js +38 -8
  36. package/dist/collection/components/merge/mrd-merge-view/mrd-merge-view.js +2 -2
  37. package/dist/collection/dev/api.js +20 -5
  38. package/dist/collection/dev/app.js +51 -13
  39. package/dist/collection/dev/example-data.js +126 -2
  40. package/dist/collection/types/client-layout.js +6 -0
  41. package/dist/collection/utils/document-attachments.js +27 -14
  42. package/dist/collection/utils/i18n.js +120 -0
  43. package/dist/components/cell-renderer.js +1 -1
  44. package/dist/components/client-layout.js +1 -1
  45. package/dist/components/document-attachments.js +1 -1
  46. package/dist/components/file-upload-common.js +1 -1
  47. package/dist/components/format.js +1 -1
  48. package/dist/components/i18n.js +1 -1
  49. package/dist/components/index.js +1 -1
  50. package/dist/components/mrd-boolean-field2.js +1 -1
  51. package/dist/components/mrd-currency-field2.js +1 -1
  52. package/dist/components/mrd-date-field2.js +1 -1
  53. package/dist/components/mrd-datetime-field2.js +1 -1
  54. package/dist/components/mrd-document-view2.js +1 -1
  55. package/dist/components/mrd-email-field2.js +1 -1
  56. package/dist/components/mrd-email-view.d.ts +11 -0
  57. package/dist/components/mrd-email-view.js +1 -0
  58. package/dist/components/mrd-email-view2.js +1 -0
  59. package/dist/components/mrd-field2.js +1 -1
  60. package/dist/components/mrd-file-field2.js +1 -1
  61. package/dist/components/mrd-form.js +1 -1
  62. package/dist/components/mrd-image-field2.js +1 -1
  63. package/dist/components/mrd-invoice-view.d.ts +11 -0
  64. package/dist/components/mrd-invoice-view.js +1 -0
  65. package/dist/components/mrd-invoice-view2.js +1 -0
  66. package/dist/components/mrd-layout-section.js +1 -1
  67. package/dist/components/mrd-longtext-field2.js +1 -1
  68. package/dist/components/mrd-merge-view.js +1 -1
  69. package/dist/components/mrd-number-field2.js +1 -1
  70. package/dist/components/mrd-secret-field2.js +1 -1
  71. package/dist/components/mrd-table2.js +1 -1
  72. package/dist/components/mrd-text-field2.js +1 -1
  73. package/dist/components/mrd-textarea-field2.js +1 -2
  74. package/dist/components/mrd-time-field2.js +1 -1
  75. package/dist/components/purify.es.js +2 -0
  76. package/dist/esm/{cell-renderer-D63AUZxa.js → cell-renderer-DIsNX9D7.js} +122 -2
  77. package/dist/esm/{client-layout-DCOAAH92.js → client-layout-Bc42CfJB.js} +7 -1
  78. package/dist/esm/{index-DiSe6vjv.js → index-CDiBvvJU.js} +468 -6
  79. package/dist/esm/index.js +1 -1
  80. package/dist/esm/loader.js +3 -3
  81. package/dist/esm/mosterdcomponents.js +3 -3
  82. package/dist/esm/{mrd-boolean-field_23.entry.js → mrd-boolean-field_25.entry.js} +5617 -5226
  83. package/dist/esm/mrd-merge-view.entry.js +5 -5
  84. package/dist/mosterdcomponents/index.esm.js +1 -1
  85. package/dist/mosterdcomponents/mosterdcomponents.esm.js +1 -1
  86. package/dist/mosterdcomponents/{p-2e16a7d0.entry.js → p-4e061416.entry.js} +1 -1
  87. package/dist/mosterdcomponents/p-910ebfee.entry.js +3 -0
  88. package/dist/mosterdcomponents/{p-DCOAAH92.js → p-Bc42CfJB.js} +1 -1
  89. package/dist/mosterdcomponents/p-CDiBvvJU.js +2 -0
  90. package/dist/mosterdcomponents/p-Ce2QDq0t.js +1 -0
  91. package/dist/types/components/documents/mrd-document-view/mrd-document-view.d.ts +2 -2
  92. package/dist/types/components/email/mrd-email-view/mrd-email-view.d.ts +52 -0
  93. package/dist/types/components/fields/file-upload-common.d.ts +19 -1
  94. package/dist/types/components/fields/mrd-file-field/mrd-file-field.d.ts +24 -10
  95. package/dist/types/components/fields/mrd-image-field/mrd-image-field.d.ts +27 -11
  96. package/dist/types/components/form/mrd-form/mrd-form.d.ts +16 -1
  97. package/dist/types/components/invoice/mrd-invoice-view/mrd-invoice-view.d.ts +60 -0
  98. package/dist/types/components/layout/mrd-layout-section/mrd-layout-section.d.ts +13 -0
  99. package/dist/types/components.d.ts +294 -19
  100. package/dist/types/types/client-layout.d.ts +6 -0
  101. package/dist/types/utils/document-attachments.d.ts +12 -5
  102. package/package.json +1 -1
  103. package/dist/mosterdcomponents/p-CnqDM0Gb.js +0 -1
  104. package/dist/mosterdcomponents/p-DiSe6vjv.js +0 -2
  105. package/dist/mosterdcomponents/p-b5f38707.entry.js +0 -3
@@ -1,7 +1,7 @@
1
1
  import { Host, h } from "@stencil/core";
2
2
  import { t } from "../../../utils/i18n";
3
3
  import { FieldLabel, FieldError } from "../field-helpers";
4
- import { validateUploadFile, uploadZoneClass, makeDragHandlers } from "../file-upload-common";
4
+ import { isPending, entryLabel, validateUploadFile, uploadZoneClass, makeDragHandlers } from "../file-upload-common";
5
5
  export class MrdFileField {
6
6
  constructor() {
7
7
  this.name = '';
@@ -12,69 +12,107 @@ export class MrdFileField {
12
12
  this.locale = navigator.language;
13
13
  this.accept = '';
14
14
  this.maxSize = 0; // bytes, 0 = no limit
15
- this.fileName = '';
15
+ this.multiple = false;
16
+ /** Working copy of the field's files, kept in sync with `value`. Entries still
17
+ * a `File` are pending upload; resolved entries are `{ href, fileName }` (or a
18
+ * bare href string for older hosts). */
19
+ this.entries = [];
16
20
  this.isDragging = false;
17
- this.uploading = false;
18
21
  this.error = '';
19
22
  this.handleInputChange = (e) => {
20
23
  var _a;
21
- const files = e.target.files;
22
- this.handleFile((_a = files === null || files === void 0 ? void 0 : files[0]) !== null && _a !== void 0 ? _a : null);
24
+ const input = e.target;
25
+ this.addFiles(Array.from((_a = input.files) !== null && _a !== void 0 ? _a : []));
26
+ input.value = '';
23
27
  };
24
- this.drag = makeDragHandlers(dragging => (this.isDragging = dragging), file => this.handleFile(file));
28
+ this.drag = makeDragHandlers(dragging => (this.isDragging = dragging), files => this.addFiles(files));
25
29
  this.handleZoneClick = () => {
26
30
  var _a;
27
- if (!this.disabled && !this.uploading) {
31
+ if (!this.disabled && !this.zoneBusy) {
28
32
  (_a = this.fileInputRef) === null || _a === void 0 ? void 0 : _a.click();
29
33
  }
30
34
  };
31
- this.handleClear = (e) => {
35
+ this.handleRemove = (index) => (e) => {
32
36
  e.stopPropagation();
33
- this.fileName = '';
37
+ const next = this.entries.filter((_, i) => i !== index);
38
+ this.entries = next;
34
39
  this.error = '';
35
- this.uploading = false;
36
40
  if (this.fileInputRef)
37
41
  this.fileInputRef.value = '';
38
- this.mrdChange.emit({ name: this.name, value: null });
42
+ this.emitValue(next);
39
43
  };
40
44
  }
41
- /** When the host provides a URI back via setFieldValue, the upload is done. */
42
- valueChanged(newVal) {
43
- if (typeof newVal === 'string' && newVal) {
44
- this.uploading = false;
45
+ componentWillLoad() {
46
+ this.syncEntriesFromValue();
47
+ }
48
+ /** The host (via mrd-form.setFieldValue) is the source of truth once a value round-trips back. */
49
+ valueChanged() {
50
+ this.syncEntriesFromValue();
51
+ }
52
+ syncEntriesFromValue() {
53
+ const v = this.value;
54
+ if (this.multiple) {
55
+ this.entries = Array.isArray(v) ? [...v] : v ? [v] : [];
45
56
  }
46
- else if (!newVal) {
47
- this.uploading = false;
48
- this.fileName = '';
57
+ else {
58
+ this.entries = v ? [v] : [];
49
59
  }
50
60
  }
51
- handleFile(file) {
52
- if (!file) {
53
- this.fileName = '';
54
- this.uploading = false;
55
- this.mrdChange.emit({ name: this.name, value: null });
61
+ emitValue(entries) {
62
+ var _a;
63
+ const value = this.multiple ? entries : (_a = entries[0]) !== null && _a !== void 0 ? _a : null;
64
+ this.mrdChange.emit({ name: this.name, value: value });
65
+ }
66
+ addFiles(files) {
67
+ if (this.disabled || this.zoneBusy)
68
+ return;
69
+ const candidates = this.multiple ? files : files.slice(0, 1);
70
+ if (!candidates.length)
56
71
  return;
72
+ const accepted = [];
73
+ let uploadError = '';
74
+ for (const file of candidates) {
75
+ const err = validateUploadFile(file, this.maxSize, this.locale);
76
+ if (err) {
77
+ uploadError = err;
78
+ continue;
79
+ }
80
+ accepted.push(file);
57
81
  }
58
- const uploadError = validateUploadFile(file, this.maxSize, this.locale);
59
- if (uploadError) {
60
- this.error = uploadError;
82
+ this.error = uploadError;
83
+ if (!accepted.length)
61
84
  return;
85
+ const next = this.multiple ? [...this.entries, ...accepted] : [accepted[0]];
86
+ this.entries = next;
87
+ this.emitValue(next);
88
+ for (const file of accepted) {
89
+ this.mrdUpload.emit({ name: this.name, file });
62
90
  }
63
- this.error = '';
64
- this.fileName = file.name;
65
- this.uploading = true;
66
- this.mrdChange.emit({ name: this.name, value: file });
67
- this.mrdUpload.emit({ name: this.name, file });
91
+ }
92
+ /** In single mode, block re-selection while the one file is still uploading;
93
+ * in multiple mode, more files can always be added alongside pending uploads. */
94
+ get zoneBusy() {
95
+ return !this.multiple && this.entries.some(isPending);
96
+ }
97
+ /** Icon/spinner + filename + remove button — the caller supplies the wrapping element
98
+ * (a plain row for single mode, an `<li>` for the multi-mode list). */
99
+ renderEntry(entry, index) {
100
+ const uploading = isPending(entry);
101
+ return [
102
+ 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" }))),
103
+ h("span", { class: "mrd-file-field__filename" }, entryLabel(entry)),
104
+ !uploading && (h("button", { class: "mrd-file-field__clear", type: "button", onClick: this.handleRemove(index), "aria-label": t('remove', this.locale) }, "\u2715")),
105
+ ];
68
106
  }
69
107
  render() {
70
- const hasFile = this.uploading || (typeof this.value === 'string' && this.value) || this.fileName;
71
108
  const hasError = !!this.error;
109
+ const hasEntries = this.entries.length > 0;
72
110
  const zoneClass = uploadZoneClass('mrd-file-field', {
73
111
  dragging: this.isDragging,
74
112
  error: hasError,
75
- disabled: this.disabled || this.uploading,
113
+ disabled: this.disabled || this.zoneBusy,
76
114
  });
77
- return (h(Host, { key: '6410e945bb873a05d0a1b3be45bc879b5e153a05' }, h("div", { key: '4d1d69d768b383f0d9190f88a50a87de8679d3d2', class: "mrd-file-field" }, h(FieldLabel, { key: '7e0009908fb4c087de16cf08251ab398199dae60', base: "mrd-file-field", label: this.label, required: this.required }), h("div", { key: '88dfc0d1c34670f7de8f3cf2dea4c95b0ae66f4c', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.drag.onDragOver, onDragLeave: this.drag.onDragLeave, onDrop: this.drag.onDrop }, h("input", { key: 'b6d678b5582a58721c928cef47dd8d6645b26a86', 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)))))), h(FieldError, { key: '80f1698819c60b15476b953f5f3216f195430b84', base: "mrd-file-field", error: this.error }))));
115
+ return (h(Host, { key: '2e740a0857b069740a6a13616d0a0dfee2b945be' }, h("div", { key: '069b25ced3b2f1ce547819086dadbd53ade2378c', class: "mrd-file-field" }, h(FieldLabel, { key: 'd13f3cb0af766d6328772dab865b2079c85ec075', base: "mrd-file-field", label: this.label, required: this.required }), h("div", { key: '9ffdbb508e3934854034c46e6f719a88d4175920', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.drag.onDragOver, onDragLeave: this.drag.onDragLeave, onDrop: this.drag.onDrop }, h("input", { key: 'c5d6954b8fa050889b5b65e15fde229dd64d7cc7', ref: el => (this.fileInputRef = el), class: "mrd-file-field__input", type: "file", name: this.name, accept: this.accept, multiple: this.multiple, disabled: this.disabled || this.zoneBusy, required: this.required && !hasEntries, onChange: this.handleInputChange }), hasEntries && !this.multiple ? (h("div", { class: "mrd-file-field__selected" }, this.renderEntry(this.entries[0], 0))) : (h("div", { class: "mrd-file-field__prompt" }, h("svg", { class: "mrd-file-field__upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("polyline", { points: "16 16 12 12 8 16" }), h("line", { x1: "12", y1: "12", x2: "12", y2: "21" }), h("path", { d: "M20.39 18.39A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.3" })), h("span", null, t('drop_file_here', this.locale), ' ', h("span", { class: "mrd-file-field__browse" }, t('browse', this.locale)))))), this.multiple && hasEntries && (h("ul", { key: '910a3e89f74d93ab16fb9f677a4276d5ad88897d', class: "mrd-file-field__list" }, this.entries.map((entry, index) => (h("li", { class: "mrd-file-field__item", key: `${index}-${entryLabel(entry)}` }, this.renderEntry(entry, index)))))), h(FieldError, { key: '4f0f071b0a1460ea1d6067a8fa4f588ebc620f2a', base: "mrd-file-field", error: this.error }))));
78
116
  }
79
117
  static get is() { return "mrd-file-field"; }
80
118
  static get encapsulation() { return "scoped"; }
@@ -247,14 +285,33 @@ export class MrdFileField {
247
285
  "reflect": false,
248
286
  "attribute": "max-size",
249
287
  "defaultValue": "0"
288
+ },
289
+ "multiple": {
290
+ "type": "boolean",
291
+ "mutable": false,
292
+ "complexType": {
293
+ "original": "boolean",
294
+ "resolved": "boolean",
295
+ "references": {}
296
+ },
297
+ "required": false,
298
+ "optional": false,
299
+ "docs": {
300
+ "tags": [],
301
+ "text": ""
302
+ },
303
+ "getter": false,
304
+ "setter": false,
305
+ "reflect": false,
306
+ "attribute": "multiple",
307
+ "defaultValue": "false"
250
308
  }
251
309
  };
252
310
  }
253
311
  static get states() {
254
312
  return {
255
- "fileName": {},
313
+ "entries": {},
256
314
  "isDragging": {},
257
- "uploading": {},
258
315
  "error": {}
259
316
  };
260
317
  }
@@ -270,12 +327,14 @@ export class MrdFileField {
270
327
  "text": ""
271
328
  },
272
329
  "complexType": {
273
- "original": "{ name: string; value: File | null }",
274
- "resolved": "{ name: string; value: File | null; }",
330
+ "original": "{ name: string; value: FileEntry | FileEntry[] | null }",
331
+ "resolved": "{ name: string; value: FileEntry | FileEntry[] | null; }",
275
332
  "references": {
276
- "File": {
277
- "location": "global",
278
- "id": "global::File"
333
+ "FileEntry": {
334
+ "location": "import",
335
+ "path": "../file-upload-common",
336
+ "id": "src/components/fields/file-upload-common.ts::FileEntry",
337
+ "referenceLocation": "FileEntry"
279
338
  }
280
339
  }
281
340
  }
@@ -290,12 +349,14 @@ export class MrdFileField {
290
349
  "text": ""
291
350
  },
292
351
  "complexType": {
293
- "original": "{ name: string; value: File | null }",
294
- "resolved": "{ name: string; value: File | null; }",
352
+ "original": "{ name: string; value: FileEntry | FileEntry[] | null }",
353
+ "resolved": "{ name: string; value: FileEntry | FileEntry[] | null; }",
295
354
  "references": {
296
- "File": {
297
- "location": "global",
298
- "id": "global::File"
355
+ "FileEntry": {
356
+ "location": "import",
357
+ "path": "../file-upload-common",
358
+ "id": "src/components/fields/file-upload-common.ts::FileEntry",
359
+ "referenceLocation": "FileEntry"
299
360
  }
300
361
  }
301
362
  }
@@ -307,7 +368,7 @@ export class MrdFileField {
307
368
  "composed": true,
308
369
  "docs": {
309
370
  "tags": [],
310
- "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."
371
+ "text": "Emitted once per selected/dropped file that needs to be uploaded.\nHost should upload the file and call form.setFieldValue(name, { href, fileName: file.name }, file)\nwith the result \u2014 passing `file` back lets mrd-form resolve the right entry in a `multiple` field."
311
372
  },
312
373
  "complexType": {
313
374
  "original": "{ name: string; file: File }",
@@ -89,6 +89,7 @@
89
89
  width: 100%;
90
90
  }
91
91
  .mrd-image-field__preview-thumb {
92
+ position: relative;
92
93
  flex-shrink: 0;
93
94
  width: 80px;
94
95
  height: 80px;
@@ -159,6 +160,49 @@
159
160
  background-color: var(--mrd-color-danger);
160
161
  color: var(--mrd-color-white);
161
162
  }
163
+ .mrd-image-field__grid {
164
+ list-style: none;
165
+ display: flex;
166
+ flex-wrap: wrap;
167
+ gap: var(--mrd-space-3);
168
+ margin: var(--mrd-space-2) 0 0;
169
+ padding: 0;
170
+ }
171
+ .mrd-image-field__grid-item {
172
+ position: relative;
173
+ display: flex;
174
+ flex-direction: column;
175
+ align-items: center;
176
+ gap: var(--mrd-space-1);
177
+ width: 88px;
178
+ }
179
+ .mrd-image-field__grid-name {
180
+ font-family: var(--mrd-font-family);
181
+ font-size: var(--mrd-font-size-xs);
182
+ color: var(--mrd-color-neutral-600);
183
+ max-width: 100%;
184
+ overflow: hidden;
185
+ text-overflow: ellipsis;
186
+ white-space: nowrap;
187
+ }
188
+ .mrd-image-field__grid-remove {
189
+ position: absolute;
190
+ top: -6px;
191
+ right: -6px;
192
+ width: 20px;
193
+ height: 20px;
194
+ line-height: 1;
195
+ background-color: var(--mrd-color-white);
196
+ color: var(--mrd-color-neutral-500);
197
+ border: var(--mrd-border-width) solid var(--mrd-border-color);
198
+ border-radius: 50%;
199
+ cursor: pointer;
200
+ font-size: var(--mrd-font-size-xs);
201
+ }
202
+ .mrd-image-field__grid-remove:hover {
203
+ color: var(--mrd-color-danger);
204
+ border-color: var(--mrd-color-danger);
205
+ }
162
206
 
163
207
  @keyframes mrd-spin {
164
208
  to {
@@ -1,7 +1,7 @@
1
1
  import { Host, h } from "@stencil/core";
2
2
  import { t } from "../../../utils/i18n";
3
3
  import { FieldLabel, FieldError } from "../field-helpers";
4
- import { validateUploadFile, uploadZoneClass, makeDragHandlers } from "../file-upload-common";
4
+ import { isPending, entryLabel, validateUploadFile, uploadZoneClass, makeDragHandlers } from "../file-upload-common";
5
5
  export class MrdImageField {
6
6
  constructor() {
7
7
  this.name = '';
@@ -12,79 +12,125 @@ export class MrdImageField {
12
12
  this.locale = navigator.language;
13
13
  this.accept = 'image/*';
14
14
  this.maxSize = 0;
15
- this.previewUrl = '';
16
- this.fileName = '';
15
+ this.multiple = false;
16
+ /** Working copy of the field's files, kept in sync with `value`. Entries still
17
+ * a `File` are pending upload; resolved entries are `{ href, fileName }` (or a
18
+ * bare href string for older hosts). */
19
+ this.entries = [];
17
20
  this.isDragging = false;
18
- this.uploading = false;
19
21
  this.error = '';
22
+ /** Local data-URL previews for pending File entries, keyed by File reference. */
23
+ this.previewCache = new Map();
20
24
  this.handleInputChange = (e) => {
21
25
  var _a;
22
- const files = e.target.files;
23
- this.handleFile((_a = files === null || files === void 0 ? void 0 : files[0]) !== null && _a !== void 0 ? _a : null);
26
+ const input = e.target;
27
+ this.addFiles(Array.from((_a = input.files) !== null && _a !== void 0 ? _a : []));
28
+ input.value = '';
24
29
  };
25
- this.drag = makeDragHandlers(dragging => (this.isDragging = dragging), file => this.handleFile(file));
30
+ this.drag = makeDragHandlers(dragging => (this.isDragging = dragging), files => this.addFiles(files));
26
31
  this.handleZoneClick = () => {
27
32
  var _a;
28
- if (!this.disabled && !this.uploading) {
33
+ if (!this.disabled && !this.zoneBusy) {
29
34
  (_a = this.fileInputRef) === null || _a === void 0 ? void 0 : _a.click();
30
35
  }
31
36
  };
32
- this.handleClear = (e) => {
37
+ this.handleRemove = (index) => (e) => {
33
38
  e.stopPropagation();
34
- this.previewUrl = '';
35
- this.fileName = '';
39
+ const removed = this.entries[index];
40
+ if (removed instanceof File)
41
+ this.previewCache.delete(removed);
42
+ const next = this.entries.filter((_, i) => i !== index);
43
+ this.entries = next;
36
44
  this.error = '';
37
- this.uploading = false;
38
45
  if (this.fileInputRef)
39
46
  this.fileInputRef.value = '';
40
- this.mrdChange.emit({ name: this.name, value: null });
47
+ this.emitValue(next);
41
48
  };
42
49
  }
43
- /** When the host provides a URI back via setFieldValue, the upload is done. */
44
- valueChanged(newVal) {
45
- if (typeof newVal === 'string' && newVal) {
46
- this.uploading = false;
47
- }
48
- else if (!newVal) {
49
- this.uploading = false;
50
- this.previewUrl = '';
51
- this.fileName = '';
52
- }
50
+ componentWillLoad() {
51
+ this.syncEntriesFromValue();
53
52
  }
54
- handleFile(file) {
55
- if (!file) {
56
- this.previewUrl = '';
57
- this.fileName = '';
58
- this.uploading = false;
59
- this.mrdChange.emit({ name: this.name, value: null });
60
- return;
53
+ /** The host (via mrd-form.setFieldValue) is the source of truth once a value round-trips back. */
54
+ valueChanged() {
55
+ this.syncEntriesFromValue();
56
+ }
57
+ syncEntriesFromValue() {
58
+ const v = this.value;
59
+ if (this.multiple) {
60
+ this.entries = Array.isArray(v) ? [...v] : v ? [v] : [];
61
61
  }
62
- const uploadError = validateUploadFile(file, this.maxSize, this.locale, true);
63
- if (uploadError) {
64
- this.error = uploadError;
65
- return;
62
+ else {
63
+ this.entries = v ? [v] : [];
66
64
  }
67
- this.error = '';
68
- this.fileName = file.name;
69
- this.uploading = true;
70
- // Show local preview immediately while upload is in progress
65
+ }
66
+ emitValue(entries) {
67
+ var _a;
68
+ const value = this.multiple ? entries : (_a = entries[0]) !== null && _a !== void 0 ? _a : null;
69
+ this.mrdChange.emit({ name: this.name, value: value });
70
+ }
71
+ readPreview(file) {
71
72
  const reader = new FileReader();
72
- reader.onload = (ev) => {
73
+ reader.onload = ev => {
73
74
  var _a;
74
- this.previewUrl = (_a = ev.target) === null || _a === void 0 ? void 0 : _a.result;
75
+ this.previewCache.set(file, (_a = ev.target) === null || _a === void 0 ? void 0 : _a.result);
76
+ this.entries = [...this.entries]; // trigger re-render now that the preview is ready
75
77
  };
76
78
  reader.readAsDataURL(file);
77
- this.mrdChange.emit({ name: this.name, value: file });
78
- this.mrdUpload.emit({ name: this.name, file });
79
+ }
80
+ addFiles(files) {
81
+ if (this.disabled || this.zoneBusy)
82
+ return;
83
+ const candidates = this.multiple ? files : files.slice(0, 1);
84
+ if (!candidates.length)
85
+ return;
86
+ const accepted = [];
87
+ let uploadError = '';
88
+ for (const file of candidates) {
89
+ const err = validateUploadFile(file, this.maxSize, this.locale, true);
90
+ if (err) {
91
+ uploadError = err;
92
+ continue;
93
+ }
94
+ accepted.push(file);
95
+ }
96
+ this.error = uploadError;
97
+ if (!accepted.length)
98
+ return;
99
+ const next = this.multiple ? [...this.entries, ...accepted] : [accepted[0]];
100
+ this.entries = next;
101
+ this.emitValue(next);
102
+ for (const file of accepted) {
103
+ this.readPreview(file);
104
+ this.mrdUpload.emit({ name: this.name, file });
105
+ }
106
+ }
107
+ /** In single mode, block re-selection while the one image is still uploading;
108
+ * in multiple mode, more images can always be added alongside pending uploads. */
109
+ get zoneBusy() {
110
+ return !this.multiple && this.entries.some(isPending);
111
+ }
112
+ renderThumb(entry) {
113
+ const uploading = isPending(entry);
114
+ const previewUrl = uploading ? this.previewCache.get(entry) : null;
115
+ return (h("div", { class: "mrd-image-field__preview-thumb" }, previewUrl && h("img", { class: "mrd-image-field__preview", src: previewUrl, alt: entryLabel(entry) }), uploading && (h("div", { class: "mrd-image-field__preview-overlay" }, h("span", { class: "mrd-image-field__spinner", "aria-label": t('loading', this.locale) })))));
116
+ }
117
+ renderSingle(entry) {
118
+ const uploading = isPending(entry);
119
+ return (h("div", { class: "mrd-image-field__preview-container" }, this.renderThumb(entry), h("div", { class: "mrd-image-field__preview-info" }, h("span", { class: "mrd-image-field__preview-name" }, entryLabel(entry)), uploading && h("span", { class: "mrd-image-field__upload-status" }, t('loading', this.locale))), !uploading && (h("button", { class: "mrd-image-field__clear", type: "button", onClick: this.handleRemove(0), "aria-label": t('remove', this.locale) }, t('remove', this.locale)))));
120
+ }
121
+ renderGridItem(entry, index) {
122
+ const uploading = isPending(entry);
123
+ return (h("li", { class: "mrd-image-field__grid-item", key: `${index}-${entryLabel(entry)}` }, this.renderThumb(entry), h("span", { class: "mrd-image-field__grid-name" }, entryLabel(entry)), !uploading && (h("button", { class: "mrd-image-field__grid-remove", type: "button", onClick: this.handleRemove(index), "aria-label": t('remove', this.locale) }, "\u2715"))));
79
124
  }
80
125
  render() {
81
126
  const hasError = !!this.error;
127
+ const hasEntries = this.entries.length > 0;
82
128
  const zoneClass = uploadZoneClass('mrd-image-field', {
83
129
  dragging: this.isDragging,
84
130
  error: hasError,
85
- disabled: this.disabled || this.uploading,
131
+ disabled: this.disabled || this.zoneBusy,
86
132
  });
87
- return (h(Host, { key: '700310af716dcc167f98bc7ae7024bb44e1285b6' }, h("div", { key: '95d29a82751249e560404488fb279138eee0c1be', class: "mrd-image-field" }, h(FieldLabel, { key: 'f53f040257a4b65d8435c836846adab137b91a5e', base: "mrd-image-field", label: this.label, required: this.required }), h("div", { key: 'a9cc7a0861b1457d8e4abb11b380b6eeb519a863', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.drag.onDragOver, onDragLeave: this.drag.onDragLeave, onDrop: this.drag.onDrop }, h("input", { key: '7112030bc2b80b4c3b31a4421656da4c926a2fe1', 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)))))), h(FieldError, { key: '0cf5346ecb1a5d110822b087081b4b5f05255381', base: "mrd-image-field", error: this.error }))));
133
+ return (h(Host, { key: '51d39ea80195565a5dc780ff6a7923a976cfb0a7' }, h("div", { key: 'd76edb7ac9f1efea8c7c3d5b04e906ad4ab4c761', class: "mrd-image-field" }, h(FieldLabel, { key: 'b46a67a76188047677c40ce3f406daed7d8de141', base: "mrd-image-field", label: this.label, required: this.required }), h("div", { key: '0156a9722ea48d84e3ea1a829e4266425a594a6a', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.drag.onDragOver, onDragLeave: this.drag.onDragLeave, onDrop: this.drag.onDrop }, h("input", { key: '1b8e41da71bb57254bfd2e5527b05e1aeb32eb2f', ref: el => (this.fileInputRef = el), class: "mrd-image-field__input", type: "file", name: this.name, accept: this.accept, multiple: this.multiple, disabled: this.disabled || this.zoneBusy, required: this.required && !hasEntries, onChange: this.handleInputChange }), hasEntries && !this.multiple ? (this.renderSingle(this.entries[0])) : (h("div", { class: "mrd-image-field__prompt" }, h("svg", { class: "mrd-image-field__upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }), h("circle", { cx: "8.5", cy: "8.5", r: "1.5" }), h("polyline", { points: "21 15 16 10 5 21" })), h("span", null, t('drop_file_here', this.locale), ' ', h("span", { class: "mrd-image-field__browse" }, t('browse', this.locale)))))), this.multiple && hasEntries && (h("ul", { key: '9211b5212eae0629f7c9b2b49d80e2b658a9ddd3', class: "mrd-image-field__grid" }, this.entries.map((entry, index) => this.renderGridItem(entry, index)))), h(FieldError, { key: '5f49c03156ed18e7c8307adff679b149658ca4a6', base: "mrd-image-field", error: this.error }))));
88
134
  }
89
135
  static get is() { return "mrd-image-field"; }
90
136
  static get encapsulation() { return "scoped"; }
@@ -257,15 +303,33 @@ export class MrdImageField {
257
303
  "reflect": false,
258
304
  "attribute": "max-size",
259
305
  "defaultValue": "0"
306
+ },
307
+ "multiple": {
308
+ "type": "boolean",
309
+ "mutable": false,
310
+ "complexType": {
311
+ "original": "boolean",
312
+ "resolved": "boolean",
313
+ "references": {}
314
+ },
315
+ "required": false,
316
+ "optional": false,
317
+ "docs": {
318
+ "tags": [],
319
+ "text": ""
320
+ },
321
+ "getter": false,
322
+ "setter": false,
323
+ "reflect": false,
324
+ "attribute": "multiple",
325
+ "defaultValue": "false"
260
326
  }
261
327
  };
262
328
  }
263
329
  static get states() {
264
330
  return {
265
- "previewUrl": {},
266
- "fileName": {},
331
+ "entries": {},
267
332
  "isDragging": {},
268
- "uploading": {},
269
333
  "error": {}
270
334
  };
271
335
  }
@@ -281,12 +345,14 @@ export class MrdImageField {
281
345
  "text": ""
282
346
  },
283
347
  "complexType": {
284
- "original": "{ name: string; value: File | null }",
285
- "resolved": "{ name: string; value: File | null; }",
348
+ "original": "{ name: string; value: FileEntry | FileEntry[] | null }",
349
+ "resolved": "{ name: string; value: FileEntry | FileEntry[] | null; }",
286
350
  "references": {
287
- "File": {
288
- "location": "global",
289
- "id": "global::File"
351
+ "FileEntry": {
352
+ "location": "import",
353
+ "path": "../file-upload-common",
354
+ "id": "src/components/fields/file-upload-common.ts::FileEntry",
355
+ "referenceLocation": "FileEntry"
290
356
  }
291
357
  }
292
358
  }
@@ -301,12 +367,14 @@ export class MrdImageField {
301
367
  "text": ""
302
368
  },
303
369
  "complexType": {
304
- "original": "{ name: string; value: File | null }",
305
- "resolved": "{ name: string; value: File | null; }",
370
+ "original": "{ name: string; value: FileEntry | FileEntry[] | null }",
371
+ "resolved": "{ name: string; value: FileEntry | FileEntry[] | null; }",
306
372
  "references": {
307
- "File": {
308
- "location": "global",
309
- "id": "global::File"
373
+ "FileEntry": {
374
+ "location": "import",
375
+ "path": "../file-upload-common",
376
+ "id": "src/components/fields/file-upload-common.ts::FileEntry",
377
+ "referenceLocation": "FileEntry"
310
378
  }
311
379
  }
312
380
  }
@@ -318,7 +386,7 @@ export class MrdImageField {
318
386
  "composed": true,
319
387
  "docs": {
320
388
  "tags": [],
321
- "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."
389
+ "text": "Emitted once per selected/dropped image that needs to be uploaded.\nHost should upload the file and call form.setFieldValue(name, { href, fileName: file.name }, file)\nwith the result \u2014 passing `file` back lets mrd-form resolve the right entry in a `multiple` field."
322
390
  },
323
391
  "complexType": {
324
392
  "original": "{ name: string; file: File }",
@@ -21,7 +21,7 @@ export class MrdLongtextField {
21
21
  };
22
22
  }
23
23
  render() {
24
- return (h(Host, { key: 'b27d14772f5184d41c178606629a9945120296ef' }, h("div", { key: '206b1b9ee1d37e05680e31bf8b324455867fd93b', class: "mrd-longtext-field" }, h(FieldLabel, { key: '0b6f4959f32a097907965753ed8708d7580aee53', base: "mrd-longtext-field", label: this.label, required: this.required }), this.disabled ? (h("pre", { class: "mrd-longtext-field__content" }, this.value)) : (h("textarea", { class: controlClass('mrd-longtext-field', !!this.error), name: this.name, placeholder: this.placeholder, required: this.required, rows: 10, onInput: this.handleInput, onBlur: this.handleBlur }, this.value)), h(FieldError, { key: '0803cf0c1b6409e6c8a65121efef97d28d870119', base: "mrd-longtext-field", error: this.error }))));
24
+ return (h(Host, { key: 'e53fec4d4eafbd68d9cffb1f064d8e0c4c37839c' }, h("div", { key: '8843a23e42b0545c269fc6c924e7ae295770064e', class: "mrd-longtext-field" }, h(FieldLabel, { key: '8767676dd35f25f9bf5ebdb26887edc0882582e0', base: "mrd-longtext-field", label: this.label, required: this.required }), this.disabled ? (h("pre", { class: "mrd-longtext-field__content" }, this.value)) : (h("textarea", { class: controlClass('mrd-longtext-field', !!this.error), name: this.name, placeholder: this.placeholder, required: this.required, rows: 10, onInput: this.handleInput, onBlur: this.handleBlur }, this.value)), h(FieldError, { key: '54dc790173575e8a02764e5b14040b900c2eb609', base: "mrd-longtext-field", error: this.error }))));
25
25
  }
26
26
  static get is() { return "mrd-longtext-field"; }
27
27
  static get encapsulation() { return "scoped"; }
@@ -70,7 +70,7 @@ export class MrdNumberField {
70
70
  const hasError = !!this.error;
71
71
  const suffix = this.dataType === ClientLayoutItemFieldDataType.PERCENTAGE ? '%' :
72
72
  this.dataType === ClientLayoutItemFieldDataType.DECIMAL ? '' : '';
73
- return (h(Host, { key: '90cae99b332f9554bc80d4044fce892ae37a48cf' }, h("div", { key: '26a9cfcc662eaeb571d17785f10f74269cf78537', class: "mrd-number-field" }, h(FieldLabel, { key: '0d9e70c1591f309ad2875d9e9fe6dbb8aa910323', base: "mrd-number-field", label: this.label, required: this.required }), h("div", { key: '95e9b53fa73c452491f65355915bf04912900ded', class: "mrd-number-field__input-wrapper" }, h("input", { key: '1d341c270a21b1a10c51757e90257e48e741abd7', class: controlClass('mrd-number-field', hasError), type: "text", inputMode: "decimal", name: this.name, value: this.displayValue, placeholder: this.placeholder || (suffix ? `0${suffix}` : '0'), required: this.required, disabled: this.disabled, onInput: this.handleInput, onBlur: this.handleBlur, onFocus: this.handleFocus })), h(FieldError, { key: '0dba75e0f7355b71bfa71dab16cd1a6fcc36922f', base: "mrd-number-field", error: this.error }))));
73
+ return (h(Host, { key: '5df5c2e16c85cd54944d95b7a8c340ae1a4ddb34' }, h("div", { key: 'e332bd0190d537c002b14090fa96ec6502e34746', class: "mrd-number-field" }, h(FieldLabel, { key: 'e26ae85ef6c6d7935b2d34041a7ee2294da392a4', base: "mrd-number-field", label: this.label, required: this.required }), h("div", { key: 'fb1a44a363a36b69124a0092e80b67d41b538c03', class: "mrd-number-field__input-wrapper" }, h("input", { key: '175c448177bbd46015fc7f47b98b76e16ee3b743', class: controlClass('mrd-number-field', hasError), type: "text", inputMode: "decimal", name: this.name, value: this.displayValue, placeholder: this.placeholder || (suffix ? `0${suffix}` : '0'), required: this.required, disabled: this.disabled, onInput: this.handleInput, onBlur: this.handleBlur, onFocus: this.handleFocus })), h(FieldError, { key: 'ecb16ddf655e563f0569e774ab2f2e419f60b0f1', base: "mrd-number-field", error: this.error }))));
74
74
  }
75
75
  static get is() { return "mrd-number-field"; }
76
76
  static get encapsulation() { return "scoped"; }
@@ -21,9 +21,9 @@ export class MrdSecretField {
21
21
  };
22
22
  }
23
23
  render() {
24
- return (h(Host, { key: '9883a87b7fcc840aa4bbe0a3cde163cc58bda65d' }, h("div", { key: '3c7ec45d59a1a17863daa39b7c115db5c58815ee', class: "mrd-secret-field" }, h(FieldLabel, { key: '2dda66c7e6d4946661bff5a5a46589a7e17f569a', base: "mrd-secret-field", label: this.label, required: this.required }), this.disabled
24
+ return (h(Host, { key: 'e06d04fdae34b42441976e21605fe94ad935382e' }, h("div", { key: '2889e1eb1b6d0887ae531523a0b9b43c49ef6f99', class: "mrd-secret-field" }, h(FieldLabel, { key: 'c40907905292cdef8bb0b8b9b0c03e05650bef37', base: "mrd-secret-field", label: this.label, required: this.required }), this.disabled
25
25
  ? (h("span", { class: "mrd-secret-field__masked", "aria-label": this.label }, this.value ? '••••••••' : ''))
26
- : (h("input", { class: controlClass('mrd-secret-field', !!this.error), type: "password", name: this.name, value: this.value, placeholder: this.placeholder, required: this.required, autocomplete: "new-password", onInput: this.handleInput, onBlur: this.handleBlur })), h(FieldError, { key: 'ad8f54a7c76c59591fee77e11a12bbd62c392d91', base: "mrd-secret-field", error: this.error }))));
26
+ : (h("input", { class: controlClass('mrd-secret-field', !!this.error), type: "password", name: this.name, value: this.value, placeholder: this.placeholder, required: this.required, autocomplete: "new-password", onInput: this.handleInput, onBlur: this.handleBlur })), h(FieldError, { key: '6353e4b40566852dbc1994c7c9c409d0d0aa1b37', base: "mrd-secret-field", error: this.error }))));
27
27
  }
28
28
  static get is() { return "mrd-secret-field"; }
29
29
  static get encapsulation() { return "scoped"; }
@@ -21,7 +21,7 @@ export class MrdTextField {
21
21
  };
22
22
  }
23
23
  render() {
24
- return (h(Host, { key: 'd2a6fb5735a3a01887cc467274a0ff9d71312124' }, h("div", { key: '7864bf852d43f93ebd0120a3ec1b72e54837d1ba', class: "mrd-text-field" }, h(FieldLabel, { key: 'bdad112197b44a643a58dd79c4648e284311199d', base: "mrd-text-field", label: this.label, required: this.required }), h("input", { key: '1d3e1cf3374ea2e5a83794b5110205964fff86e1', class: controlClass('mrd-text-field', !!this.error), type: "text", name: this.name, value: this.value, placeholder: this.placeholder, required: this.required, disabled: this.disabled, onInput: this.handleInput, onBlur: this.handleBlur }), h(FieldError, { key: 'bb4ec51de7b6d360fdb3d46dd53e85a5d497bcce', base: "mrd-text-field", error: this.error }))));
24
+ return (h(Host, { key: '3153f0c6f8ab4d9dae93306f7507399aeda75eaf' }, h("div", { key: '5d9c28023fdfb5472fc115c66bc3df509506e10f', class: "mrd-text-field" }, h(FieldLabel, { key: '1e21139aae0cc1ae95aa3297271b618a40043e77', base: "mrd-text-field", label: this.label, required: this.required }), h("input", { key: '46f98d5e39bb834075449fac7096b077a1ae7bb3', class: controlClass('mrd-text-field', !!this.error), type: "text", name: this.name, value: this.value, placeholder: this.placeholder, required: this.required, disabled: this.disabled, onInput: this.handleInput, onBlur: this.handleBlur }), h(FieldError, { key: '10b6ddae9cd9f36dc9d7176167d79df8e4102c03', base: "mrd-text-field", error: this.error }))));
25
25
  }
26
26
  static get is() { return "mrd-text-field"; }
27
27
  static get encapsulation() { return "scoped"; }
@@ -64,7 +64,7 @@ export class MrdTextareaField {
64
64
  return DOMPurify.sanitize(html);
65
65
  }
66
66
  render() {
67
- return (h(Host, { key: '708c1f8f14d2de4b5a274155d190fc19a304d7f0' }, h("div", { key: 'cf5c7a571e74cad08e0e320e91db4e22a3b2e080', class: "mrd-textarea-field" }, h(FieldLabel, { key: '4ced05f3914440f89dc5605901fc311e8ad54360', base: "mrd-textarea-field", label: this.label, required: this.required }), h("div", { key: '81147829bc575d05f3521bf3704edfdfe0d9b2cf', class: controlClass('mrd-textarea-field', !!this.error, 'container') }, h("div", { key: 'a9f42d86cab460d5e0cf6de87e0c0a0a1ca7d77a', class: "mrd-textarea-field__editor" })), h(FieldError, { key: '9f4b5271d0901e474ef6c0f1170b3ef718a844a9', base: "mrd-textarea-field", error: this.error }))));
67
+ return (h(Host, { key: 'e132531881f68f373e700617aac8033c8ebccb47' }, h("div", { key: 'fec0cf56cd7868d3fcd5a4e8a382b2dcdb6e5c50', class: "mrd-textarea-field" }, h(FieldLabel, { key: '333aa2ff57cce9e3178f0c4be4a1df1077884248', base: "mrd-textarea-field", label: this.label, required: this.required }), h("div", { key: '40025207580eb5768981b85aaa0a8ff95fce7234', class: controlClass('mrd-textarea-field', !!this.error, 'container') }, h("div", { key: '621987b3b2b1d8b4836bff065075ba527a82db81', class: "mrd-textarea-field__editor" })), h(FieldError, { key: 'ac2d8de22f008cd1c91842137ccd0cd36eb9ce19', base: "mrd-textarea-field", error: this.error }))));
68
68
  }
69
69
  static get is() { return "mrd-textarea-field"; }
70
70
  static get encapsulation() { return "scoped"; }