@mmlogic/components 0.5.1 → 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 (113) hide show
  1. package/dist/cjs/cell-renderer-7KX9Qbml.js +983 -0
  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} +3017 -951
  8. package/dist/cjs/mrd-merge-view.cjs.entry.js +273 -0
  9. package/dist/collection/collection-manifest.json +3 -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 +9 -5
  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/merge-diff.js +99 -0
  37. package/dist/collection/components/merge/mrd-merge-view/merge-parts.js +44 -0
  38. package/dist/collection/components/merge/mrd-merge-view/mrd-merge-view.css +244 -0
  39. package/dist/collection/components/merge/mrd-merge-view/mrd-merge-view.js +397 -0
  40. package/dist/collection/dev/api.js +41 -2
  41. package/dist/collection/dev/app.js +135 -17
  42. package/dist/collection/dev/example-data.js +126 -2
  43. package/dist/collection/types/client-layout.js +6 -0
  44. package/dist/collection/utils/cell-renderer.js +6 -1
  45. package/dist/collection/utils/document-attachments.js +27 -14
  46. package/dist/collection/utils/i18n.js +224 -0
  47. package/dist/components/cell-renderer.js +1 -0
  48. package/dist/components/client-layout.js +1 -1
  49. package/dist/components/document-attachments.js +1 -1
  50. package/dist/components/file-upload-common.js +1 -1
  51. package/dist/components/format.js +1 -1
  52. package/dist/components/i18n.js +1 -1
  53. package/dist/components/index.js +1 -1
  54. package/dist/components/mrd-boolean-field2.js +1 -1
  55. package/dist/components/mrd-currency-field2.js +1 -1
  56. package/dist/components/mrd-date-field2.js +1 -1
  57. package/dist/components/mrd-datetime-field2.js +1 -1
  58. package/dist/components/mrd-document-view2.js +1 -1
  59. package/dist/components/mrd-email-field2.js +1 -1
  60. package/dist/components/mrd-email-view.d.ts +11 -0
  61. package/dist/components/mrd-email-view.js +1 -0
  62. package/dist/components/mrd-email-view2.js +1 -0
  63. package/dist/components/mrd-field2.js +1 -1
  64. package/dist/components/mrd-file-field2.js +1 -1
  65. package/dist/components/mrd-form.js +1 -1
  66. package/dist/components/mrd-image-field2.js +1 -1
  67. package/dist/components/mrd-invoice-view.d.ts +11 -0
  68. package/dist/components/mrd-invoice-view.js +1 -0
  69. package/dist/components/mrd-invoice-view2.js +1 -0
  70. package/dist/components/mrd-layout-section.js +1 -1
  71. package/dist/components/mrd-longtext-field2.js +1 -1
  72. package/dist/components/mrd-merge-view.d.ts +11 -0
  73. package/dist/components/mrd-merge-view.js +1 -0
  74. package/dist/components/mrd-number-field2.js +1 -1
  75. package/dist/components/mrd-secret-field2.js +1 -1
  76. package/dist/components/mrd-table2.js +1 -1
  77. package/dist/components/mrd-text-field2.js +1 -1
  78. package/dist/components/mrd-textarea-field2.js +1 -1
  79. package/dist/components/mrd-time-field2.js +1 -1
  80. package/dist/components/purify.es.js +2 -0
  81. package/dist/esm/cell-renderer-DIsNX9D7.js +974 -0
  82. package/dist/esm/{client-layout-DCOAAH92.js → client-layout-Bc42CfJB.js} +7 -1
  83. package/dist/esm/{index-DiSe6vjv.js → index-CDiBvvJU.js} +468 -6
  84. package/dist/esm/index.js +1 -1
  85. package/dist/esm/loader.js +3 -3
  86. package/dist/esm/mosterdcomponents.js +3 -3
  87. package/dist/esm/{mrd-boolean-field_23.entry.js → mrd-boolean-field_25.entry.js} +2949 -885
  88. package/dist/esm/mrd-merge-view.entry.js +271 -0
  89. package/dist/mosterdcomponents/index.esm.js +1 -1
  90. package/dist/mosterdcomponents/mosterdcomponents.esm.js +1 -1
  91. package/dist/mosterdcomponents/p-4e061416.entry.js +1 -0
  92. package/dist/mosterdcomponents/p-910ebfee.entry.js +3 -0
  93. package/dist/mosterdcomponents/{p-DCOAAH92.js → p-Bc42CfJB.js} +1 -1
  94. package/dist/mosterdcomponents/p-CDiBvvJU.js +2 -0
  95. package/dist/mosterdcomponents/p-Ce2QDq0t.js +1 -0
  96. package/dist/types/components/documents/mrd-document-view/mrd-document-view.d.ts +2 -2
  97. package/dist/types/components/email/mrd-email-view/mrd-email-view.d.ts +52 -0
  98. package/dist/types/components/fields/file-upload-common.d.ts +19 -1
  99. package/dist/types/components/fields/mrd-file-field/mrd-file-field.d.ts +24 -10
  100. package/dist/types/components/fields/mrd-image-field/mrd-image-field.d.ts +27 -11
  101. package/dist/types/components/fields/mrd-textarea-field/mrd-textarea-field.d.ts +1 -0
  102. package/dist/types/components/form/mrd-form/mrd-form.d.ts +16 -1
  103. package/dist/types/components/invoice/mrd-invoice-view/mrd-invoice-view.d.ts +60 -0
  104. package/dist/types/components/layout/mrd-layout-section/mrd-layout-section.d.ts +13 -0
  105. package/dist/types/components/merge/mrd-merge-view/merge-diff.d.ts +43 -0
  106. package/dist/types/components/merge/mrd-merge-view/merge-parts.d.ts +37 -0
  107. package/dist/types/components/merge/mrd-merge-view/mrd-merge-view.d.ts +68 -0
  108. package/dist/types/components.d.ts +445 -19
  109. package/dist/types/types/client-layout.d.ts +6 -0
  110. package/dist/types/utils/document-attachments.d.ts +12 -5
  111. package/package.json +2 -1
  112. package/dist/mosterdcomponents/p-DiSe6vjv.js +0 -2
  113. package/dist/mosterdcomponents/p-cdecc698.entry.js +0 -1
@@ -0,0 +1,273 @@
1
+ 'use strict';
2
+
3
+ var index = require('./index-DVbdkYO3.js');
4
+ var clientLayout = require('./client-layout-CqVuJumR.js');
5
+ var cellRenderer = require('./cell-renderer-7KX9Qbml.js');
6
+
7
+ /**
8
+ * Whether a layout item can appear in the merge diff at all. m-n relations
9
+ * (`multiple: true`) are unioned automatically server-side (DataService.merge)
10
+ * and must never be surfaced as a user choice — only FIELD and single-value
11
+ * (n-1) RELATION items are diffable.
12
+ */
13
+ function isDiffable(item) {
14
+ if (item.type === clientLayout.ClientLayoutItemType.FIELD)
15
+ return true;
16
+ if (item.type === clientLayout.ClientLayoutItemType.RELATION)
17
+ return !item.multiple;
18
+ return false;
19
+ }
20
+ /**
21
+ * Raw value for a field/relation off a record in the API's row shape (flat
22
+ * fields + `_links`). History-enabled fields come back as `{ current,
23
+ * history: [...] }` — this returns that whole object as-is, since a winning
24
+ * B value must carry its entire history into the patch (FINDING-0114: "the
25
+ * entire history list follows whichever value wins ... never interleaved").
26
+ */
27
+ function getRawValue(item, record) {
28
+ var _a, _b, _c, _d, _e;
29
+ const name = (_a = item.name) !== null && _a !== void 0 ? _a : '';
30
+ if (item.type === clientLayout.ClientLayoutItemType.RELATION) {
31
+ return (_d = (_c = (_b = record === null || record === void 0 ? void 0 : record._links) === null || _b === void 0 ? void 0 : _b[name]) === null || _c === void 0 ? void 0 : _c.href) !== null && _d !== void 0 ? _d : null;
32
+ }
33
+ return (_e = record === null || record === void 0 ? void 0 : record[name]) !== null && _e !== void 0 ? _e : null;
34
+ }
35
+ /** Unwraps a history-enabled field's `{ current, history }` shape to its current value, for comparison only. */
36
+ function comparableValue(item, value) {
37
+ if (item.historyEnabled && value != null && typeof value === 'object' && !Array.isArray(value) && 'current' in value) {
38
+ return value.current;
39
+ }
40
+ return value;
41
+ }
42
+ function normalize(value) {
43
+ return value === undefined || value === '' ? null : value;
44
+ }
45
+ function valuesEqual(a, b) {
46
+ const na = normalize(a);
47
+ const nb = normalize(b);
48
+ if (na === nb)
49
+ return true;
50
+ if (na === null || nb === null)
51
+ return false;
52
+ return JSON.stringify(na) === JSON.stringify(nb);
53
+ }
54
+ function isEmpty(value) {
55
+ return normalize(value) === null;
56
+ }
57
+ /**
58
+ * Splits diffable fields into `conflicts` (both records have a — different —
59
+ * value, user must pick) and `autoFilled` (A has no value, B does; silently
60
+ * taken from B without a UI choice).
61
+ */
62
+ function diffFields(fields, recordA, recordB) {
63
+ const conflicts = [];
64
+ const autoFilled = [];
65
+ for (const item of fields.filter(isDiffable)) {
66
+ const aValue = getRawValue(item, recordA);
67
+ const bValue = getRawValue(item, recordB);
68
+ const aComparable = comparableValue(item, aValue);
69
+ const bComparable = comparableValue(item, bValue);
70
+ if (valuesEqual(aComparable, bComparable))
71
+ continue;
72
+ if (isEmpty(aComparable) && !isEmpty(bComparable)) {
73
+ autoFilled.push({ item, aValue, bValue });
74
+ }
75
+ else {
76
+ conflicts.push({ item, aValue, bValue });
77
+ }
78
+ }
79
+ return { conflicts, autoFilled };
80
+ }
81
+ /**
82
+ * Builds the patch payload per the merge endpoint contract: every `autoFilled`
83
+ * entry is always included (A had nothing to lose); a `conflicts` entry is
84
+ * only included when the user explicitly resolved it to B — anything left
85
+ * unresolved keeps A's value by omission.
86
+ */
87
+ function buildPatch(diff, resolutions) {
88
+ var _a, _b, _c;
89
+ const patch = {};
90
+ for (const { item, bValue } of diff.autoFilled) {
91
+ patch[(_a = item.name) !== null && _a !== void 0 ? _a : ''] = bValue;
92
+ }
93
+ for (const { item, bValue } of diff.conflicts) {
94
+ if (resolutions[(_b = item.name) !== null && _b !== void 0 ? _b : ''] === 'B') {
95
+ patch[(_c = item.name) !== null && _c !== void 0 ? _c : ''] = bValue;
96
+ }
97
+ }
98
+ return patch;
99
+ }
100
+ /** Display label for a candidate record in the search results list. */
101
+ function candidateLabel(record) {
102
+ var _a, _b, _c, _d, _e;
103
+ return (_e = (_b = (_a = record === null || record === void 0 ? void 0 : record.name) !== null && _a !== void 0 ? _a : record === null || record === void 0 ? void 0 : record.label) !== null && _b !== void 0 ? _b : (_d = (_c = record === null || record === void 0 ? void 0 : record._links) === null || _c === void 0 ? void 0 : _c.self) === null || _d === void 0 ? void 0 : _d.href) !== null && _e !== void 0 ? _e : '';
104
+ }
105
+
106
+ /** History-enabled fields carry `{ current, history: [...] }` — this is the legal record itself (e.g. past company names), not an audit log. */
107
+ function getHistory(item, record) {
108
+ var _a, _b;
109
+ if (!item.historyEnabled || !item.name)
110
+ return [];
111
+ return (_b = (_a = record === null || record === void 0 ? void 0 : record[item.name]) === null || _a === void 0 ? void 0 : _a.history) !== null && _b !== void 0 ? _b : [];
112
+ }
113
+ /** Small clock badge + popover listing past values for a history-enabled field — same UX as mrd-layout-section's field view. */
114
+ const HistoryBadge = ({ locale, history, isOpen, onToggle }) => {
115
+ if (history.length === 0)
116
+ return null;
117
+ const sorted = [...history].sort((a, b) => b.until.localeCompare(a.until));
118
+ return (index.h("span", { class: "mrd-merge-view__history-wrap" }, index.h("button", { type: "button", class: "mrd-merge-view__history-btn", title: cellRenderer.t('history_badge_tooltip', locale), "aria-label": cellRenderer.t('history_badge_tooltip', locale), onClick: (e) => { e.stopPropagation(); onToggle(); } }, index.h("svg", { class: "mrd-merge-view__history-icon", viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true" }, index.h("path", { "fill-rule": "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zm.75-13a.75.75 0 00-1.5 0v5c0 .207.085.394.22.53l2.5 2.5a.75.75 0 101.06-1.06L10.75 9.69V5z", "clip-rule": "evenodd" }))), isOpen && (index.h("div", { class: "mrd-merge-view__history-popover", role: "listbox" }, sorted.map((entry, i) => (index.h("div", { key: String(i), class: "mrd-merge-view__history-entry" }, entry.value, " (", cellRenderer.t('history_until', locale), " ", cellRenderer.formatDate(entry.until, locale), ")")))))));
119
+ };
120
+ const MergeSearchStep = ({ locale, searchQuery, searchResults, isLoading, onSearchInput, onSelect }) => (index.h("div", { class: "mrd-merge-view__search-step" }, index.h("p", { class: "mrd-merge-view__hint" }, cellRenderer.t('merge_search_hint', locale)), index.h("div", { class: "mrd-merge-view__search-wrapper" }, index.h("input", { class: "mrd-merge-view__search", type: "text", value: searchQuery, placeholder: cellRenderer.t('search_placeholder', locale), onInput: (e) => onSearchInput(e.target.value) }), isLoading && index.h("span", { class: "mrd-merge-view__spinner", "aria-label": cellRenderer.t('loading', locale) })), searchQuery.trim().length >= 2 && !isLoading && (index.h("div", { class: "mrd-merge-view__results" }, searchResults.length === 0 ? (index.h("div", { class: "mrd-merge-view__no-results" }, cellRenderer.t('no_results', locale))) : (searchResults.map(record => {
121
+ var _a, _b, _c;
122
+ return (index.h("div", { key: (_c = (_b = (_a = record === null || record === void 0 ? void 0 : record._links) === null || _a === void 0 ? void 0 : _a.self) === null || _b === void 0 ? void 0 : _b.href) !== null && _c !== void 0 ? _c : candidateLabel(record), class: "mrd-merge-view__result-item" }, index.h("span", { class: "mrd-merge-view__result-label" }, candidateLabel(record)), index.h("button", { type: "button", class: "mrd-merge-view__btn mrd-merge-view__btn--secondary", onClick: () => onSelect(record) }, cellRenderer.t('merge_select', locale))));
123
+ }))))));
124
+ const MergeCompareStep = ({ locale, currentLabel, candidateLabel: bLabel, conflicts, autoFilled, recordA, recordB, resolutions, openHistoryKey, onResolve, onToggleHistory, onChangeCandidate, onContinue }) => (index.h("div", { class: "mrd-merge-view__compare-step" }, index.h("h3", { class: "mrd-merge-view__heading" }, cellRenderer.t('merge_compare_heading', locale)), conflicts.length === 0 ? (index.h("p", { class: "mrd-merge-view__no-conflicts" }, cellRenderer.t('merge_no_conflicts', locale))) : (index.h("table", { class: "mrd-merge-view__table" }, index.h("thead", null, index.h("tr", null, index.h("th", { class: "mrd-merge-view__header" }), index.h("th", { class: "mrd-merge-view__header" }, cellRenderer.t('merge_column_a', locale), index.h("span", { class: "mrd-merge-view__header-name" }, currentLabel)), index.h("th", { class: "mrd-merge-view__header" }, cellRenderer.t('merge_column_b', locale), index.h("span", { class: "mrd-merge-view__header-name" }, bLabel)))), index.h("tbody", null, conflicts.map(({ item }) => {
125
+ var _a, _b, _c;
126
+ const name = (_a = item.name) !== null && _a !== void 0 ? _a : '';
127
+ const resolution = (_b = resolutions[name]) !== null && _b !== void 0 ? _b : 'A';
128
+ const historyA = getHistory(item, recordA);
129
+ const historyB = getHistory(item, recordB);
130
+ const keyA = `${name}:A`;
131
+ const keyB = `${name}:B`;
132
+ return (index.h("tr", { key: name, class: "mrd-merge-view__row" }, index.h("td", { class: "mrd-merge-view__cell mrd-merge-view__cell--label" }, (_c = item.label) !== null && _c !== void 0 ? _c : name), index.h("td", { class: "mrd-merge-view__cell" }, index.h("label", { class: "mrd-merge-view__option" }, index.h("input", { type: "radio", name: `merge-${name}`, checked: resolution === 'A', onChange: () => onResolve(name, 'A') }), index.h("span", null, cellRenderer.CellRenderer.render(item, recordA, locale) || '—')), index.h(HistoryBadge, { locale: locale, history: historyA, isOpen: openHistoryKey === keyA, onToggle: () => onToggleHistory(openHistoryKey === keyA ? null : keyA) })), index.h("td", { class: "mrd-merge-view__cell" }, index.h("label", { class: "mrd-merge-view__option" }, index.h("input", { type: "radio", name: `merge-${name}`, checked: resolution === 'B', onChange: () => onResolve(name, 'B') }), index.h("span", null, cellRenderer.CellRenderer.render(item, recordB, locale) || '—')), index.h(HistoryBadge, { locale: locale, history: historyB, isOpen: openHistoryKey === keyB, onToggle: () => onToggleHistory(openHistoryKey === keyB ? null : keyB) }))));
133
+ })))), autoFilled.length > 0 && (index.h("div", { class: "mrd-merge-view__auto-note" }, index.h("p", null, cellRenderer.t('merge_auto_heading', locale)), index.h("ul", null, autoFilled.map(({ item }) => { var _a; return index.h("li", { key: item.name }, (_a = item.label) !== null && _a !== void 0 ? _a : item.name); })))), index.h("div", { class: "mrd-merge-view__actions" }, index.h("button", { type: "button", class: "mrd-merge-view__btn mrd-merge-view__btn--secondary", onClick: onChangeCandidate }, cellRenderer.t('merge_back', locale)), index.h("button", { type: "button", class: "mrd-merge-view__btn mrd-merge-view__btn--primary", onClick: onContinue }, cellRenderer.t('merge_continue', locale)))));
134
+ const MergeConfirmStep = ({ locale, candidateLabel: bLabel, conflicts, autoFilled, resolutions, recordB, openHistoryKey, onToggleHistory, onBack, onConfirm }) => {
135
+ const changed = [
136
+ ...autoFilled,
137
+ ...conflicts.filter(({ item }) => { var _a; return resolutions[(_a = item.name) !== null && _a !== void 0 ? _a : ''] === 'B'; }),
138
+ ];
139
+ return (index.h("div", { class: "mrd-merge-view__confirm-step" }, index.h("h3", { class: "mrd-merge-view__heading" }, cellRenderer.t('merge_confirm_heading', locale)), changed.length === 0 ? (index.h("p", { class: "mrd-merge-view__no-conflicts" }, cellRenderer.t('merge_no_conflicts', locale))) : (index.h("ul", { class: "mrd-merge-view__summary-list" }, changed.map(({ item }) => {
140
+ var _a;
141
+ const key = `${item.name}:confirm`;
142
+ return (index.h("li", { key: item.name }, (_a = item.label) !== null && _a !== void 0 ? _a : item.name, ": ", cellRenderer.CellRenderer.render(item, recordB, locale) || '—', index.h(HistoryBadge, { locale: locale, history: getHistory(item, recordB), isOpen: openHistoryKey === key, onToggle: () => onToggleHistory(openHistoryKey === key ? null : key) })));
143
+ }))), index.h("p", { class: "mrd-merge-view__warning" }, cellRenderer.t('merge_confirm_warning', locale), " (", bLabel, ")"), index.h("div", { class: "mrd-merge-view__actions" }, index.h("button", { type: "button", class: "mrd-merge-view__btn mrd-merge-view__btn--secondary", onClick: onBack }, cellRenderer.t('merge_back', locale)), index.h("button", { type: "button", class: "mrd-merge-view__btn mrd-merge-view__btn--danger", onClick: onConfirm }, cellRenderer.t('merge_confirm_button', locale)))));
144
+ };
145
+
146
+ const mrdMergeViewCss = () => `.sc-mrd-merge-view-h{display:block;width:100%}.mrd-merge-view.sc-mrd-merge-view{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-900)}.mrd-merge-view__hint.sc-mrd-merge-view{margin:0 0 var(--mrd-space-4);color:var(--mrd-color-neutral-600)}.mrd-merge-view__heading.sc-mrd-merge-view{margin:0 0 var(--mrd-space-4);font-size:var(--mrd-font-size-lg);font-weight:var(--mrd-font-weight-semibold)}.mrd-merge-view__search-wrapper.sc-mrd-merge-view{position:relative;display:flex;align-items:center}.mrd-merge-view__search.sc-mrd-merge-view{width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);background:var(--mrd-input-bg);color:var(--mrd-input-color);font-size:var(--mrd-font-size-sm)}.mrd-merge-view__search.sc-mrd-merge-view:focus{outline:none;border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-merge-view__spinner.sc-mrd-merge-view{position:absolute;right:var(--mrd-space-3);width:1rem;height:1rem;border:2px solid var(--mrd-color-neutral-300);border-top-color:var(--mrd-color-primary);border-radius:var(--mrd-border-radius-full);animation:mrd-merge-view-spin var(--mrd-transition-slow) linear infinite}.mrd-merge-view__results.sc-mrd-merge-view{margin-top:var(--mrd-space-2);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);overflow:hidden}.mrd-merge-view__no-results.sc-mrd-merge-view{padding:var(--mrd-space-3) var(--mrd-space-4);color:var(--mrd-color-neutral-500)}.mrd-merge-view__result-item.sc-mrd-merge-view{display:flex;align-items:center;justify-content:space-between;gap:var(--mrd-space-3);padding:var(--mrd-space-2) var(--mrd-space-4)}.mrd-merge-view__result-item.sc-mrd-merge-view:not(:last-child){border-bottom:var(--mrd-border-width) solid var(--mrd-border-color)}.mrd-merge-view__result-label.sc-mrd-merge-view{font-weight:var(--mrd-font-weight-medium)}.mrd-merge-view__no-conflicts.sc-mrd-merge-view{color:var(--mrd-color-neutral-600)}.mrd-merge-view__table.sc-mrd-merge-view{width:100%;border-collapse:collapse;margin-bottom:var(--mrd-space-4)}.mrd-merge-view__header.sc-mrd-merge-view{text-align:left;padding:var(--mrd-space-2) var(--mrd-space-3);border-bottom:2px solid var(--mrd-border-color);font-size:var(--mrd-font-size-xs);text-transform:uppercase;letter-spacing:0.04em;color:var(--mrd-color-neutral-600)}.mrd-merge-view__header-name.sc-mrd-merge-view{display:block;text-transform:none;letter-spacing:normal;font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-neutral-900);margin-top:var(--mrd-space-1)}.mrd-merge-view__row.sc-mrd-merge-view:nth-child(even){background:var(--mrd-color-neutral-50)}.mrd-merge-view__cell.sc-mrd-merge-view{padding:var(--mrd-space-2) var(--mrd-space-3);border-bottom:var(--mrd-border-width) solid var(--mrd-border-color);vertical-align:top}.mrd-merge-view__cell--label.sc-mrd-merge-view{font-weight:var(--mrd-font-weight-medium);white-space:nowrap}.mrd-merge-view__option.sc-mrd-merge-view{display:flex;align-items:flex-start;gap:var(--mrd-space-2);cursor:pointer}.mrd-merge-view__option.sc-mrd-merge-view input[type=radio].sc-mrd-merge-view{margin-top:0.2em}.mrd-merge-view__history-wrap.sc-mrd-merge-view{position:relative;display:inline-flex;align-items:center;margin-left:var(--mrd-space-1)}.mrd-merge-view__history-btn.sc-mrd-merge-view{display:inline-flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;padding:0;background:transparent;border:none;border-radius:var(--mrd-border-radius-sm);color:var(--mrd-color-neutral-400);cursor:pointer;flex-shrink:0;transition:color var(--mrd-transition-fast), background-color var(--mrd-transition-fast)}.mrd-merge-view__history-btn.sc-mrd-merge-view:hover{color:var(--mrd-color-neutral-700);background-color:var(--mrd-color-neutral-100)}.mrd-merge-view__history-btn.sc-mrd-merge-view:focus{outline:none;box-shadow:var(--mrd-shadow-focus)}.mrd-merge-view__history-icon.sc-mrd-merge-view{width:0.875rem;height:0.875rem}.mrd-merge-view__history-popover.sc-mrd-merge-view{position:absolute;top:calc(100% + 0.25rem);left:0;min-width:18rem;max-width:18rem;background-color:var(--mrd-color-white);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius-md);box-shadow:var(--mrd-shadow-md);padding:var(--mrd-space-1) 0;z-index:var(--mrd-z-dropdown)}.mrd-merge-view__history-entry.sc-mrd-merge-view{font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-700);padding:var(--mrd-space-2) var(--mrd-space-3);line-height:var(--mrd-line-height-normal)}.mrd-merge-view__history-entry.sc-mrd-merge-view:not(:last-child){border-bottom:var(--mrd-border-width) solid var(--mrd-color-neutral-100)}.mrd-merge-view__auto-note.sc-mrd-merge-view{margin-bottom:var(--mrd-space-4);padding:var(--mrd-space-3) var(--mrd-space-4);background:var(--mrd-color-neutral-50);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);color:var(--mrd-color-neutral-700)}.mrd-merge-view__auto-note.sc-mrd-merge-view p.sc-mrd-merge-view{margin:0 0 var(--mrd-space-1);font-weight:var(--mrd-font-weight-medium)}.mrd-merge-view__auto-note.sc-mrd-merge-view ul.sc-mrd-merge-view{margin:0;padding-left:var(--mrd-space-5)}.mrd-merge-view__summary-list.sc-mrd-merge-view{margin:0 0 var(--mrd-space-4);padding-left:var(--mrd-space-5)}.mrd-merge-view__warning.sc-mrd-merge-view{padding:var(--mrd-space-3) var(--mrd-space-4);background:var(--mrd-color-danger-light);border:var(--mrd-border-width) solid var(--mrd-color-danger);border-radius:var(--mrd-border-radius);color:var(--mrd-color-danger-dark);margin-bottom:var(--mrd-space-4)}.mrd-merge-view__actions.sc-mrd-merge-view{display:flex;gap:var(--mrd-space-3)}.mrd-merge-view__btn.sc-mrd-merge-view{height:var(--mrd-input-height-sm);padding:0 var(--mrd-space-4);border-radius:var(--mrd-border-radius);border:var(--mrd-border-width) solid transparent;font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-medium);cursor:pointer;transition:background-color var(--mrd-transition-fast), border-color var(--mrd-transition-fast)}.mrd-merge-view__btn--primary.sc-mrd-merge-view{background:var(--mrd-color-primary);color:var(--mrd-color-white)}.mrd-merge-view__btn--primary.sc-mrd-merge-view:hover{background:var(--mrd-color-primary-hover)}.mrd-merge-view__btn--secondary.sc-mrd-merge-view{background:var(--mrd-color-white);border-color:var(--mrd-border-color);color:var(--mrd-color-neutral-700)}.mrd-merge-view__btn--secondary.sc-mrd-merge-view:hover{background:var(--mrd-color-neutral-50)}.mrd-merge-view__btn--danger.sc-mrd-merge-view{background:var(--mrd-color-danger);color:var(--mrd-color-white)}.mrd-merge-view__btn--danger.sc-mrd-merge-view:hover{background:var(--mrd-color-danger-dark)}@keyframes mrd-merge-view-spin{to{transform:rotate(360deg)}}`;
147
+
148
+ const MrdMergeView = class {
149
+ constructor(hostRef) {
150
+ index.registerInstance(this, hostRef);
151
+ this.mrdSearch = index.createEvent(this, "mrdSearch");
152
+ this.mrdMerge = index.createEvent(this, "mrdMerge");
153
+ this.locale = navigator.language;
154
+ /** Dot-notation class, passed through on mrdSearch (host may use it to pick the right search endpoint). */
155
+ this.basicType = '';
156
+ /** URL segment for the search endpoint; falls back to basicType when absent. */
157
+ this.mostSignificantClass = '';
158
+ /** Flat FIELD/RELATION items describing the basic type's schema (host flattens SECTION/GROUP, same as mrd-table's `columns`). */
159
+ this.fields = [];
160
+ /** Href of A (winner) — the object the merge screen was opened from. */
161
+ this.currentHref = '';
162
+ /** A's full raw record: flat fields + `_links`, the same row shape CellRenderer.render expects. */
163
+ this.currentRecord = {};
164
+ /** Display name for A, shown in the compare step's column header. */
165
+ this.currentLabel = '';
166
+ this.step = 'search';
167
+ this.searchQuery = '';
168
+ this.searchResults = [];
169
+ this.isLoading = false;
170
+ this.candidate = null;
171
+ this.resolutions = {};
172
+ /** Which history badge popover is open, keyed e.g. `legalName:A` / `legalName:confirm`. */
173
+ this.openHistoryKey = null;
174
+ this.historyClickOutside = null;
175
+ this.searchDebounce = null;
176
+ this.handleSearchInput = (query) => {
177
+ this.searchQuery = query;
178
+ if (this.searchDebounce)
179
+ clearTimeout(this.searchDebounce);
180
+ if (query.trim().length >= 2) {
181
+ this.isLoading = true;
182
+ this.searchDebounce = setTimeout(() => {
183
+ this.mrdSearch.emit({
184
+ query,
185
+ basicType: this.basicType,
186
+ mostSignificantClass: this.mostSignificantClass || undefined,
187
+ });
188
+ }, 300);
189
+ }
190
+ else {
191
+ this.searchResults = [];
192
+ this.isLoading = false;
193
+ }
194
+ };
195
+ this.handleSelect = (record) => {
196
+ this.candidate = record;
197
+ const { conflicts } = diffFields(this.fields, this.currentRecord, record);
198
+ const resolutions = {};
199
+ conflicts.forEach(({ item }) => { var _a; resolutions[(_a = item.name) !== null && _a !== void 0 ? _a : ''] = 'A'; });
200
+ this.resolutions = resolutions;
201
+ this.openHistoryKey = null;
202
+ this.step = 'compare';
203
+ };
204
+ this.handleChangeCandidate = () => {
205
+ this.candidate = null;
206
+ this.resolutions = {};
207
+ this.openHistoryKey = null;
208
+ this.step = 'search';
209
+ };
210
+ this.handleResolve = (name, side) => {
211
+ this.resolutions = Object.assign(Object.assign({}, this.resolutions), { [name]: side });
212
+ };
213
+ this.handleToggleHistory = (key) => {
214
+ this.openHistoryKey = key;
215
+ };
216
+ this.handleContinue = () => {
217
+ this.step = 'confirm';
218
+ };
219
+ this.handleBack = () => {
220
+ this.step = 'compare';
221
+ };
222
+ this.handleConfirm = () => {
223
+ var _a, _b, _c, _d;
224
+ if (!this.candidate)
225
+ return;
226
+ const diff = diffFields(this.fields, this.currentRecord, this.candidate);
227
+ const patch = buildPatch(diff, this.resolutions);
228
+ const loserHref = (_d = (_c = (_b = (_a = this.candidate) === null || _a === void 0 ? void 0 : _a._links) === null || _b === void 0 ? void 0 : _b.self) === null || _c === void 0 ? void 0 : _c.href) !== null && _d !== void 0 ? _d : '';
229
+ this.mrdMerge.emit({ winnerHref: this.currentHref, loserHref, patch });
230
+ };
231
+ }
232
+ connectedCallback() {
233
+ this.historyClickOutside = (e) => {
234
+ if (!this.el.contains(e.target))
235
+ this.openHistoryKey = null;
236
+ };
237
+ document.addEventListener('mousedown', this.historyClickOutside);
238
+ }
239
+ disconnectedCallback() {
240
+ if (this.historyClickOutside) {
241
+ document.removeEventListener('mousedown', this.historyClickOutside);
242
+ this.historyClickOutside = null;
243
+ }
244
+ }
245
+ /**
246
+ * Stores search results, filtering out A itself regardless of what the
247
+ * host's search returns — A must never appear as a mergeable candidate.
248
+ */
249
+ async setSearchResults(records) {
250
+ this.searchResults = (records !== null && records !== void 0 ? records : []).filter(r => { var _a, _b, _c; return ((_c = (_b = (_a = r === null || r === void 0 ? void 0 : r._links) === null || _a === void 0 ? void 0 : _a.self) === null || _b === void 0 ? void 0 : _b.href) !== null && _c !== void 0 ? _c : null) !== this.currentHref; });
251
+ this.isLoading = false;
252
+ }
253
+ async setLoading(loading) {
254
+ this.isLoading = loading;
255
+ }
256
+ render() {
257
+ var _a, _b;
258
+ let stepContent;
259
+ if (this.step === 'search') {
260
+ stepContent = (index.h(MergeSearchStep, { key: '3adb36fb46aa7260641a46a2cf27cc0ef320876f', locale: this.locale, searchQuery: this.searchQuery, searchResults: this.searchResults, isLoading: this.isLoading, onSearchInput: this.handleSearchInput, onSelect: this.handleSelect }));
261
+ }
262
+ else {
263
+ const diff = diffFields(this.fields, this.currentRecord, this.candidate);
264
+ const bLabel = candidateLabel(this.candidate);
265
+ stepContent = this.step === 'compare' ? (index.h(MergeCompareStep, { locale: this.locale, currentLabel: this.currentLabel, candidateLabel: bLabel, conflicts: diff.conflicts, autoFilled: diff.autoFilled, recordA: this.currentRecord, recordB: (_a = this.candidate) !== null && _a !== void 0 ? _a : {}, resolutions: this.resolutions, openHistoryKey: this.openHistoryKey, onResolve: this.handleResolve, onToggleHistory: this.handleToggleHistory, onChangeCandidate: this.handleChangeCandidate, onContinue: this.handleContinue })) : (index.h(MergeConfirmStep, { locale: this.locale, candidateLabel: bLabel, conflicts: diff.conflicts, autoFilled: diff.autoFilled, resolutions: this.resolutions, recordB: (_b = this.candidate) !== null && _b !== void 0 ? _b : {}, openHistoryKey: this.openHistoryKey, onToggleHistory: this.handleToggleHistory, onBack: this.handleBack, onConfirm: this.handleConfirm }));
266
+ }
267
+ return (index.h(index.Host, { key: 'e33a6d66a220b28cc9533da78dc274e2d7ec5c4a' }, index.h("div", { key: 'b5fb1390d86192f9f6f15e3ccb89e2d21d9c7c8b', class: "mrd-merge-view" }, stepContent)));
268
+ }
269
+ get el() { return index.getElement(this); }
270
+ };
271
+ MrdMergeView.style = mrdMergeViewCss();
272
+
273
+ exports.mrd_merge_view = MrdMergeView;
@@ -3,6 +3,7 @@
3
3
  "components/documents/mrd-document-container/mrd-document-container.js",
4
4
  "components/documents/mrd-document-list/mrd-document-list.js",
5
5
  "components/documents/mrd-document-view/mrd-document-view.js",
6
+ "components/email/mrd-email-view/mrd-email-view.js",
6
7
  "components/fields/mrd-boolean-field/mrd-boolean-field.js",
7
8
  "components/fields/mrd-currency-field/mrd-currency-field.js",
8
9
  "components/fields/mrd-date-field/mrd-date-field.js",
@@ -21,7 +22,9 @@
21
22
  "components/fields/mrd-time-field/mrd-time-field.js",
22
23
  "components/form/mrd-field/mrd-field.js",
23
24
  "components/form/mrd-form/mrd-form.js",
25
+ "components/invoice/mrd-invoice-view/mrd-invoice-view.js",
24
26
  "components/layout/mrd-layout-section/mrd-layout-section.js",
27
+ "components/merge/mrd-merge-view/mrd-merge-view.js",
25
28
  "components/table/mrd-table/mrd-table.js"
26
29
  ],
27
30
  "mixins": [],
@@ -1,7 +1,7 @@
1
1
  import { Host, h } from "@stencil/core";
2
2
  import { t } from "../../../utils/i18n";
3
3
  import { formatDate } from "../../../utils/format";
4
- import { attachmentsFromRecord } from "../../../utils/document-attachments";
4
+ import { attachmentsFromRecord, attachmentsKey } from "../../../utils/document-attachments";
5
5
  /**
6
6
  * Archetype-driven single-document view. Given a `commons.document` binding and a
7
7
  * data record, renders the document recognisably — title, date, a navigation
@@ -24,9 +24,9 @@ export class MrdDocumentView {
24
24
  /** The data record from the /data endpoint. Fields keyed by name; relations under `_links`. */
25
25
  this.data = {};
26
26
  this.locale = navigator.language;
27
- /** Tracks the href attachments were last emitted for, so componentDidLoad and
27
+ /** Tracks the key attachments were last emitted for, so componentDidLoad and
28
28
  * the data watcher don't emit duplicate events for the same file. */
29
- this.lastAttachmentHref = null;
29
+ this.lastAttachmentKey = null;
30
30
  }
31
31
  componentDidLoad() {
32
32
  this.emitAttachmentsIfNeeded();
@@ -35,12 +35,11 @@ export class MrdDocumentView {
35
35
  this.emitAttachmentsIfNeeded();
36
36
  }
37
37
  emitAttachmentsIfNeeded() {
38
- var _a, _b;
39
38
  const attachments = attachmentsFromRecord(this.archetype, this.data);
40
- const href = (_b = (_a = attachments[0]) === null || _a === void 0 ? void 0 : _a.href) !== null && _b !== void 0 ? _b : null;
41
- if (href === this.lastAttachmentHref)
39
+ const key = attachmentsKey(attachments);
40
+ if (key === this.lastAttachmentKey)
42
41
  return;
43
- this.lastAttachmentHref = href;
42
+ this.lastAttachmentKey = key;
44
43
  this.mrdAttachments.emit({ attachments });
45
44
  }
46
45
  /** Value of a value-slot: reads data[field] via the slot→field map. */
@@ -88,7 +87,7 @@ export class MrdDocumentView {
88
87
  const fileRaw = this.slotValue('file');
89
88
  const fileHref = (_a = fileRaw === null || fileRaw === void 0 ? void 0 : fileRaw.href) !== null && _a !== void 0 ? _a : '';
90
89
  const fileName = (_b = fileRaw === null || fileRaw === void 0 ? void 0 : fileRaw.fileName) !== null && _b !== void 0 ? _b : (fileRaw ? String(fileRaw) : '');
91
- return (h(Host, { key: 'd4e8d4a6c5c66677df3d4e80943fc4538d9a2be7' }, h("div", { key: 'c67bb1742590dc3ab3cec959f20dfa9030268411', class: "mrd-document-view" }, h("div", { key: '5da6e15d1f67990a9ee06bc07b717e5fa17a2ee7', class: "mrd-document-view__body" }, h("div", { key: '0fc38933add3fff48096c48d2fb6cd06fb5d1eac', class: "mrd-document-view__meta" }, title && h("h1", { key: 'e9ac8d99f9afae6b64dd7e6bd461c54b92a6ea39', class: "mrd-document-view__title" }, title), date && h("p", { key: '8591d77b300ed3c021cfa64b8e9564dee98199cd', class: "mrd-document-view__date" }, date), this.renderContainer(), fileRaw && this.renderFileMeta(fileName, fileHref), summary && (h("div", { key: '8a6d630afcf187fa86c9bab77d06d93695fd5c9f', class: "mrd-document-view__summary" }, h("div", { key: 'bd98e2cf740d08837accd8d260973d4e51cd24f7', class: "mrd-document-view__summary-body", innerHTML: summary }))))))));
90
+ return (h(Host, { key: '405890ef9135d4e9f15532dbc669c4d8d1e8b201' }, h("div", { key: 'be60f0867664a0ded6a85b17999ab207f042d8e2', class: "mrd-document-view" }, h("div", { key: 'f0202da7e83a05f782ba70c3cff91049d56c3e04', class: "mrd-document-view__body" }, h("div", { key: '85d5075c6751200ae3840b1d9e4544792ea52b5e', class: "mrd-document-view__meta" }, title && h("h1", { key: '63a4676ef488f2b0cf2347e0aa4e3c728b2d9351', class: "mrd-document-view__title" }, title), date && h("p", { key: '4ff630a9967509f661050ba04eece5ca26773ce2', class: "mrd-document-view__date" }, date), this.renderContainer(), fileRaw && this.renderFileMeta(fileName, fileHref), summary && (h("div", { key: '412e4934755e801e8a6cd10f5d00da82f9b6aa6a', class: "mrd-document-view__summary" }, h("div", { key: 'fc5c1b88cdba2f2398d09b42ede0b4dc556cd0f3', class: "mrd-document-view__summary-body", innerHTML: summary }))))))));
92
91
  }
93
92
  static get is() { return "mrd-document-view"; }
94
93
  static get encapsulation() { return "scoped"; }
@@ -0,0 +1,126 @@
1
+ :host {
2
+ display: block;
3
+ }
4
+
5
+ .mrd-email-view {
6
+ max-width: 720px;
7
+ display: flex;
8
+ flex-direction: column;
9
+ gap: var(--mrd-space-4);
10
+ }
11
+ .mrd-email-view__subject {
12
+ font-size: var(--mrd-font-size-2xl);
13
+ font-weight: var(--mrd-font-weight-bold);
14
+ color: var(--mrd-color-neutral-900);
15
+ letter-spacing: -0.02em;
16
+ margin: 0;
17
+ }
18
+ .mrd-email-view__header {
19
+ display: flex;
20
+ flex-direction: column;
21
+ gap: var(--mrd-space-1);
22
+ }
23
+ .mrd-email-view__header-row {
24
+ display: flex;
25
+ gap: var(--mrd-space-3);
26
+ font-size: var(--mrd-font-size-sm);
27
+ }
28
+ .mrd-email-view__header-label {
29
+ flex-shrink: 0;
30
+ width: 3rem;
31
+ font-weight: var(--mrd-font-weight-medium);
32
+ color: var(--mrd-color-neutral-400);
33
+ }
34
+ .mrd-email-view__header-value {
35
+ color: var(--mrd-color-neutral-700);
36
+ }
37
+ .mrd-email-view__link {
38
+ background: none;
39
+ border: none;
40
+ padding: 0;
41
+ font-family: var(--mrd-font-family);
42
+ font-size: inherit;
43
+ font-weight: var(--mrd-font-weight-medium);
44
+ color: var(--mrd-color-primary);
45
+ cursor: pointer;
46
+ }
47
+ .mrd-email-view__link:hover {
48
+ text-decoration: underline;
49
+ }
50
+ .mrd-email-view__container-link {
51
+ align-self: flex-start;
52
+ background: none;
53
+ border: none;
54
+ padding: 0;
55
+ font-family: var(--mrd-font-family);
56
+ font-size: var(--mrd-font-size-sm);
57
+ font-weight: var(--mrd-font-weight-semibold);
58
+ color: var(--mrd-color-primary);
59
+ cursor: pointer;
60
+ }
61
+ .mrd-email-view__container-link:hover {
62
+ text-decoration: underline;
63
+ }
64
+ .mrd-email-view__divider {
65
+ height: var(--mrd-border-width);
66
+ background: var(--mrd-color-neutral-200);
67
+ }
68
+ .mrd-email-view__body-html {
69
+ font-size: var(--mrd-font-size-base);
70
+ color: var(--mrd-color-neutral-700);
71
+ line-height: var(--mrd-line-height-relaxed);
72
+ word-break: break-word;
73
+ }
74
+ .mrd-email-view__body-text {
75
+ font-size: var(--mrd-font-size-base);
76
+ color: var(--mrd-color-neutral-700);
77
+ line-height: var(--mrd-line-height-relaxed);
78
+ white-space: pre-wrap;
79
+ word-break: break-word;
80
+ }
81
+ .mrd-email-view__attachments {
82
+ display: flex;
83
+ flex-direction: column;
84
+ gap: var(--mrd-space-2);
85
+ }
86
+ .mrd-email-view__attachment {
87
+ display: inline-flex;
88
+ align-items: center;
89
+ gap: var(--mrd-space-2);
90
+ align-self: flex-start;
91
+ height: 2rem;
92
+ padding: 0 var(--mrd-space-3);
93
+ background: var(--mrd-color-white);
94
+ border: 1px solid var(--mrd-color-neutral-300);
95
+ border-radius: var(--mrd-border-radius);
96
+ font-family: var(--mrd-font-family);
97
+ font-size: var(--mrd-font-size-sm);
98
+ font-weight: var(--mrd-font-weight-medium);
99
+ color: var(--mrd-color-neutral-700);
100
+ cursor: pointer;
101
+ }
102
+ .mrd-email-view__attachment:hover {
103
+ background: var(--mrd-color-neutral-100);
104
+ color: var(--mrd-color-neutral-900);
105
+ }
106
+ .mrd-email-view__attachment-icon {
107
+ width: 0.9375rem;
108
+ height: 0.9375rem;
109
+ flex-shrink: 0;
110
+ }
111
+ .mrd-email-view__headers {
112
+ font-size: var(--mrd-font-size-xs);
113
+ color: var(--mrd-color-neutral-400);
114
+ }
115
+ .mrd-email-view__headers summary {
116
+ cursor: pointer;
117
+ font-weight: var(--mrd-font-weight-medium);
118
+ }
119
+ .mrd-email-view__headers-body {
120
+ margin: var(--mrd-space-2) 0 0 0;
121
+ padding: var(--mrd-space-3);
122
+ background: var(--mrd-color-neutral-50);
123
+ border-radius: var(--mrd-border-radius);
124
+ white-space: pre-wrap;
125
+ word-break: break-word;
126
+ }