@sdcorejs/angular 20.1.2 → 20.1.4

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 (177) hide show
  1. package/README.md +127 -807
  2. package/components/audit-diff/index.d.ts +74 -0
  3. package/components/badge/index.d.ts +1 -1
  4. package/components/breadcrumb/index.d.ts +53 -0
  5. package/components/data-state/index.d.ts +44 -0
  6. package/components/document-builder/index.d.ts +5 -5
  7. package/components/form-generic/index.d.ts +89 -103
  8. package/components/import-excel/index.d.ts +4 -14
  9. package/components/index.d.ts +4 -0
  10. package/components/job-progress/index.d.ts +38 -0
  11. package/components/mini-editor/index.d.ts +9 -9
  12. package/components/modal/index.d.ts +7 -1
  13. package/components/preview/index.d.ts +181 -28
  14. package/components/side-drawer/index.d.ts +7 -1
  15. package/components/tab/index.d.ts +9 -2
  16. package/components/table/index.d.ts +8 -7
  17. package/components/tree/index.d.ts +24 -2
  18. package/components/upload-file/index.d.ts +5 -4
  19. package/directives/index.d.ts +10 -8
  20. package/fesm2022/sdcorejs-angular-components-anchor.mjs +14 -14
  21. package/fesm2022/sdcorejs-angular-components-anchor.mjs.map +1 -1
  22. package/fesm2022/sdcorejs-angular-components-audit-diff.mjs +332 -0
  23. package/fesm2022/sdcorejs-angular-components-audit-diff.mjs.map +1 -0
  24. package/fesm2022/sdcorejs-angular-components-badge.mjs +1 -0
  25. package/fesm2022/sdcorejs-angular-components-badge.mjs.map +1 -1
  26. package/fesm2022/sdcorejs-angular-components-breadcrumb.mjs +121 -0
  27. package/fesm2022/sdcorejs-angular-components-breadcrumb.mjs.map +1 -0
  28. package/fesm2022/sdcorejs-angular-components-data-state.mjs +68 -0
  29. package/fesm2022/sdcorejs-angular-components-data-state.mjs.map +1 -0
  30. package/fesm2022/sdcorejs-angular-components-document-builder.mjs +18 -23
  31. package/fesm2022/sdcorejs-angular-components-document-builder.mjs.map +1 -1
  32. package/fesm2022/sdcorejs-angular-components-editor.mjs +6 -4
  33. package/fesm2022/sdcorejs-angular-components-editor.mjs.map +1 -1
  34. package/fesm2022/sdcorejs-angular-components-form-generic.mjs +633 -886
  35. package/fesm2022/sdcorejs-angular-components-form-generic.mjs.map +1 -1
  36. package/fesm2022/sdcorejs-angular-components-import-excel.mjs +26 -41
  37. package/fesm2022/sdcorejs-angular-components-import-excel.mjs.map +1 -1
  38. package/fesm2022/sdcorejs-angular-components-job-progress.mjs +97 -0
  39. package/fesm2022/sdcorejs-angular-components-job-progress.mjs.map +1 -0
  40. package/fesm2022/sdcorejs-angular-components-mini-editor.mjs +10 -20
  41. package/fesm2022/sdcorejs-angular-components-mini-editor.mjs.map +1 -1
  42. package/fesm2022/sdcorejs-angular-components-modal.mjs +61 -4
  43. package/fesm2022/sdcorejs-angular-components-modal.mjs.map +1 -1
  44. package/fesm2022/sdcorejs-angular-components-preview.mjs +1438 -218
  45. package/fesm2022/sdcorejs-angular-components-preview.mjs.map +1 -1
  46. package/fesm2022/sdcorejs-angular-components-query-bar.mjs +9 -17
  47. package/fesm2022/sdcorejs-angular-components-query-bar.mjs.map +1 -1
  48. package/fesm2022/sdcorejs-angular-components-query-builder.mjs +1 -1
  49. package/fesm2022/sdcorejs-angular-components-query-builder.mjs.map +1 -1
  50. package/fesm2022/sdcorejs-angular-components-side-drawer.mjs +39 -2
  51. package/fesm2022/sdcorejs-angular-components-side-drawer.mjs.map +1 -1
  52. package/fesm2022/sdcorejs-angular-components-tab-router.mjs +76 -52
  53. package/fesm2022/sdcorejs-angular-components-tab-router.mjs.map +1 -1
  54. package/fesm2022/sdcorejs-angular-components-tab.mjs +48 -4
  55. package/fesm2022/sdcorejs-angular-components-tab.mjs.map +1 -1
  56. package/fesm2022/sdcorejs-angular-components-table.mjs +123 -89
  57. package/fesm2022/sdcorejs-angular-components-table.mjs.map +1 -1
  58. package/fesm2022/sdcorejs-angular-components-tree.mjs +188 -18
  59. package/fesm2022/sdcorejs-angular-components-tree.mjs.map +1 -1
  60. package/fesm2022/sdcorejs-angular-components-upload-file.mjs +17 -23
  61. package/fesm2022/sdcorejs-angular-components-upload-file.mjs.map +1 -1
  62. package/fesm2022/sdcorejs-angular-components.mjs +4 -0
  63. package/fesm2022/sdcorejs-angular-components.mjs.map +1 -1
  64. package/fesm2022/sdcorejs-angular-directives.mjs +29 -41
  65. package/fesm2022/sdcorejs-angular-directives.mjs.map +1 -1
  66. package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs +9 -8
  67. package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs.map +1 -1
  68. package/fesm2022/sdcorejs-angular-forms-checkbox.mjs +20 -83
  69. package/fesm2022/sdcorejs-angular-forms-checkbox.mjs.map +1 -1
  70. package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs +8 -4
  71. package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs.map +1 -1
  72. package/fesm2022/sdcorejs-angular-forms-chip.mjs +8 -4
  73. package/fesm2022/sdcorejs-angular-forms-chip.mjs.map +1 -1
  74. package/fesm2022/sdcorejs-angular-forms-date-range.mjs +18 -14
  75. package/fesm2022/sdcorejs-angular-forms-date-range.mjs.map +1 -1
  76. package/fesm2022/sdcorejs-angular-forms-date.mjs +48 -70
  77. package/fesm2022/sdcorejs-angular-forms-date.mjs.map +1 -1
  78. package/fesm2022/sdcorejs-angular-forms-datetime.mjs +62 -528
  79. package/fesm2022/sdcorejs-angular-forms-datetime.mjs.map +1 -1
  80. package/fesm2022/sdcorejs-angular-forms-entity-picker.mjs +384 -0
  81. package/fesm2022/sdcorejs-angular-forms-entity-picker.mjs.map +1 -0
  82. package/fesm2022/sdcorejs-angular-forms-input-color.mjs +5 -3
  83. package/fesm2022/sdcorejs-angular-forms-input-color.mjs.map +1 -1
  84. package/fesm2022/sdcorejs-angular-forms-input-number.mjs +16 -11
  85. package/fesm2022/sdcorejs-angular-forms-input-number.mjs.map +1 -1
  86. package/fesm2022/sdcorejs-angular-forms-input.mjs +297 -59
  87. package/fesm2022/sdcorejs-angular-forms-input.mjs.map +1 -1
  88. package/fesm2022/sdcorejs-angular-forms-models.mjs +155 -2
  89. package/fesm2022/sdcorejs-angular-forms-models.mjs.map +1 -1
  90. package/fesm2022/sdcorejs-angular-forms-radio.mjs +44 -78
  91. package/fesm2022/sdcorejs-angular-forms-radio.mjs.map +1 -1
  92. package/fesm2022/sdcorejs-angular-forms-select.mjs +8 -21
  93. package/fesm2022/sdcorejs-angular-forms-select.mjs.map +1 -1
  94. package/fesm2022/sdcorejs-angular-forms-switch.mjs +19 -76
  95. package/fesm2022/sdcorejs-angular-forms-switch.mjs.map +1 -1
  96. package/fesm2022/sdcorejs-angular-forms-textarea.mjs +8 -6
  97. package/fesm2022/sdcorejs-angular-forms-textarea.mjs.map +1 -1
  98. package/fesm2022/sdcorejs-angular-forms-time-range.mjs +280 -0
  99. package/fesm2022/sdcorejs-angular-forms-time-range.mjs.map +1 -0
  100. package/fesm2022/sdcorejs-angular-forms-time.mjs +310 -0
  101. package/fesm2022/sdcorejs-angular-forms-time.mjs.map +1 -0
  102. package/fesm2022/sdcorejs-angular-forms-tree-select.mjs +210 -0
  103. package/fesm2022/sdcorejs-angular-forms-tree-select.mjs.map +1 -0
  104. package/fesm2022/sdcorejs-angular-forms.mjs +73 -4
  105. package/fesm2022/sdcorejs-angular-forms.mjs.map +1 -1
  106. package/fesm2022/sdcorejs-angular-i18n.mjs +355 -10
  107. package/fesm2022/sdcorejs-angular-i18n.mjs.map +1 -1
  108. package/fesm2022/sdcorejs-angular-interceptors.mjs +12 -17
  109. package/fesm2022/sdcorejs-angular-interceptors.mjs.map +1 -1
  110. package/fesm2022/sdcorejs-angular-modules-icon.mjs.map +1 -1
  111. package/fesm2022/sdcorejs-angular-modules-layout.mjs +861 -80
  112. package/fesm2022/sdcorejs-angular-modules-layout.mjs.map +1 -1
  113. package/fesm2022/sdcorejs-angular-modules.mjs +0 -1
  114. package/fesm2022/sdcorejs-angular-modules.mjs.map +1 -1
  115. package/fesm2022/sdcorejs-angular-pipes.mjs +5 -7
  116. package/fesm2022/sdcorejs-angular-pipes.mjs.map +1 -1
  117. package/fesm2022/sdcorejs-angular-services-api.mjs +407 -137
  118. package/fesm2022/sdcorejs-angular-services-api.mjs.map +1 -1
  119. package/fesm2022/sdcorejs-angular-services-cache.mjs +515 -105
  120. package/fesm2022/sdcorejs-angular-services-cache.mjs.map +1 -1
  121. package/fesm2022/sdcorejs-angular-services-confirm.mjs +5 -7
  122. package/fesm2022/sdcorejs-angular-services-confirm.mjs.map +1 -1
  123. package/fesm2022/sdcorejs-angular-services-docx.mjs +7 -10
  124. package/fesm2022/sdcorejs-angular-services-docx.mjs.map +1 -1
  125. package/fesm2022/sdcorejs-angular-services-loading.mjs +340 -66
  126. package/fesm2022/sdcorejs-angular-services-loading.mjs.map +1 -1
  127. package/fesm2022/sdcorejs-angular-services-notify.mjs +7 -10
  128. package/fesm2022/sdcorejs-angular-services-notify.mjs.map +1 -1
  129. package/fesm2022/sdcorejs-angular-services-persistence.mjs +899 -0
  130. package/fesm2022/sdcorejs-angular-services-persistence.mjs.map +1 -0
  131. package/fesm2022/sdcorejs-angular-services-storage.mjs +324 -122
  132. package/fesm2022/sdcorejs-angular-services-storage.mjs.map +1 -1
  133. package/fesm2022/sdcorejs-angular-services-task.mjs +389 -0
  134. package/fesm2022/sdcorejs-angular-services-task.mjs.map +1 -0
  135. package/fesm2022/sdcorejs-angular-services-unsaved-changes.mjs +255 -0
  136. package/fesm2022/sdcorejs-angular-services-unsaved-changes.mjs.map +1 -0
  137. package/fesm2022/sdcorejs-angular-services-viewport.mjs +76 -0
  138. package/fesm2022/sdcorejs-angular-services-viewport.mjs.map +1 -0
  139. package/fesm2022/sdcorejs-angular-services.mjs +4 -0
  140. package/fesm2022/sdcorejs-angular-services.mjs.map +1 -1
  141. package/forms/autocomplete/index.d.ts +3 -4
  142. package/forms/checkbox/index.d.ts +4 -8
  143. package/forms/date/index.d.ts +3 -3
  144. package/forms/date-range/index.d.ts +6 -7
  145. package/forms/datetime/index.d.ts +3 -3
  146. package/forms/entity-picker/index.d.ts +128 -0
  147. package/forms/index.d.ts +15 -5
  148. package/forms/input/index.d.ts +76 -11
  149. package/forms/input-color/index.d.ts +3 -1
  150. package/forms/input-number/index.d.ts +4 -2
  151. package/forms/models/index.d.ts +86 -3
  152. package/forms/radio/index.d.ts +12 -8
  153. package/forms/switch/index.d.ts +4 -7
  154. package/forms/time/index.d.ts +117 -0
  155. package/forms/time-range/index.d.ts +98 -0
  156. package/forms/tree-select/index.d.ts +76 -0
  157. package/i18n/index.d.ts +68 -2
  158. package/interceptors/index.d.ts +5 -6
  159. package/modules/icon/index.d.ts +2 -3
  160. package/modules/index.d.ts +0 -1
  161. package/modules/layout/index.d.ts +288 -15
  162. package/package.json +50 -5
  163. package/pipes/index.d.ts +2 -2
  164. package/services/api/index.d.ts +68 -24
  165. package/services/cache/index.d.ts +52 -16
  166. package/services/confirm/index.d.ts +3 -2
  167. package/services/docx/index.d.ts +2 -3
  168. package/services/index.d.ts +4 -0
  169. package/services/loading/index.d.ts +16 -8
  170. package/services/persistence/index.d.ts +159 -0
  171. package/services/storage/index.d.ts +26 -8
  172. package/services/task/index.d.ts +104 -0
  173. package/services/unsaved-changes/index.d.ts +83 -0
  174. package/services/viewport/index.d.ts +42 -0
  175. package/fesm2022/sdcorejs-angular-modules-authom.mjs +0 -360
  176. package/fesm2022/sdcorejs-angular-modules-authom.mjs.map +0 -1
  177. package/modules/authom/index.d.ts +0 -70
@@ -0,0 +1,332 @@
1
+ import { NgTemplateOutlet } from '@angular/common';
2
+ import * as i0 from '@angular/core';
3
+ import { inject, TemplateRef, Directive, input, computed, contentChild, ChangeDetectionStrategy, Component } from '@angular/core';
4
+ import { I18nService } from '@sdcorejs/angular/i18n';
5
+
6
+ const DEFAULT_REDACTED_VALUE = '••••••';
7
+ function sdBuildAuditDiff(before, after, options = {}) {
8
+ const context = {
9
+ options,
10
+ fields: options.fields ?? [],
11
+ rows: [],
12
+ activeBefore: new WeakSet(),
13
+ activeAfter: new WeakSet(),
14
+ };
15
+ walkValue(context, before, after, true, true, '$', '$');
16
+ return context.rows.sort((left, right) => compareRows(left, right, context.fields));
17
+ }
18
+ function walkValue(context, before, after, beforePresent, afterPresent, path, configPath) {
19
+ if (isConfigured(context.fields, configPath, 'hidden'))
20
+ return;
21
+ if (isConfigured(context.fields, configPath, 'redacted')) {
22
+ addAtomicRow(context, before, after, beforePresent, afterPresent, path, configPath, true);
23
+ return;
24
+ }
25
+ const field = findExactField(context.fields, configPath);
26
+ if (field?.format || field?.enumMap) {
27
+ addAtomicRow(context, before, after, beforePresent, afterPresent, path, configPath, false);
28
+ return;
29
+ }
30
+ const beforeArray = Array.isArray(before);
31
+ const afterArray = Array.isArray(after);
32
+ if (beforeArray || afterArray) {
33
+ if ((!beforePresent && afterArray) || (beforeArray && !afterPresent) || (beforeArray && afterArray)) {
34
+ const arrayKey = field?.arrayKey;
35
+ if (arrayKey && walkStableArray(context, beforeArray ? before : [], afterArray ? after : [], path, configPath, arrayKey))
36
+ return;
37
+ }
38
+ addAtomicRow(context, before, after, beforePresent, afterPresent, path, configPath, false);
39
+ return;
40
+ }
41
+ const beforeObject = isPlainObject(before);
42
+ const afterObject = isPlainObject(after);
43
+ const canRecurse = (beforeObject && afterObject) || (beforeObject && !afterPresent) || (afterObject && !beforePresent);
44
+ if (canRecurse) {
45
+ if ((beforeObject && context.activeBefore.has(before)) || (afterObject && context.activeAfter.has(after)))
46
+ return;
47
+ if (beforeObject)
48
+ context.activeBefore.add(before);
49
+ if (afterObject)
50
+ context.activeAfter.add(after);
51
+ const beforeRecord = beforeObject ? before : {};
52
+ const afterRecord = afterObject ? after : {};
53
+ const keys = [...new Set([...Object.keys(beforeRecord), ...Object.keys(afterRecord)])].sort(compareText);
54
+ if (keys.length === 0) {
55
+ addAtomicRow(context, before, after, beforePresent, afterPresent, path, configPath, false);
56
+ if (beforeObject)
57
+ context.activeBefore.delete(before);
58
+ if (afterObject)
59
+ context.activeAfter.delete(after);
60
+ return;
61
+ }
62
+ for (const key of keys) {
63
+ const childBeforePresent = beforeObject && hasOwn(beforeRecord, key);
64
+ const childAfterPresent = afterObject && hasOwn(afterRecord, key);
65
+ walkValue(context, childBeforePresent ? beforeRecord[key] : undefined, childAfterPresent ? afterRecord[key] : undefined, childBeforePresent, childAfterPresent, path === '$' ? key : `${path}.${key}`, configPath === '$' ? key : `${configPath}.${key}`);
66
+ }
67
+ if (beforeObject)
68
+ context.activeBefore.delete(before);
69
+ if (afterObject)
70
+ context.activeAfter.delete(after);
71
+ return;
72
+ }
73
+ addAtomicRow(context, before, after, beforePresent, afterPresent, path, configPath, false);
74
+ }
75
+ function walkStableArray(context, before, after, path, configPath, keySelector) {
76
+ const beforeItems = indexStableArray(before, keySelector);
77
+ const afterItems = indexStableArray(after, keySelector);
78
+ if (!beforeItems || !afterItems)
79
+ return false;
80
+ const keys = [...new Set([...beforeItems.keys(), ...afterItems.keys()])].sort(compareText);
81
+ const keyName = typeof keySelector === 'string' ? keySelector : 'key';
82
+ for (const key of keys) {
83
+ const beforeItem = beforeItems.get(key);
84
+ const afterItem = afterItems.get(key);
85
+ const itemPath = `${path}[${keyName}=${encodeURIComponent(key)}]`;
86
+ const itemConfigPath = `${configPath}[]`;
87
+ if (!beforeItem || !afterItem) {
88
+ walkValue(context, beforeItem?.value, afterItem?.value, Boolean(beforeItem), Boolean(afterItem), itemPath, itemConfigPath);
89
+ continue;
90
+ }
91
+ walkValue(context, beforeItem.value, afterItem.value, true, true, itemPath, itemConfigPath);
92
+ }
93
+ return true;
94
+ }
95
+ function indexStableArray(items, keySelector) {
96
+ const result = new Map();
97
+ for (const item of items) {
98
+ let key;
99
+ try {
100
+ key = typeof keySelector === 'function' ? keySelector(item) : isObject(item) ? item[keySelector] : undefined;
101
+ }
102
+ catch {
103
+ return null;
104
+ }
105
+ const serialized = serializeStableKey(key);
106
+ if (serialized === null || result.has(serialized))
107
+ return null;
108
+ result.set(serialized, { key, value: item });
109
+ }
110
+ return result;
111
+ }
112
+ function serializeStableKey(key) {
113
+ if (key === null)
114
+ return 'null:null';
115
+ switch (typeof key) {
116
+ case 'string':
117
+ case 'number':
118
+ case 'bigint':
119
+ case 'boolean':
120
+ return `${typeof key}:${String(key)}`;
121
+ default:
122
+ return null;
123
+ }
124
+ }
125
+ function addAtomicRow(context, before, after, beforePresent, afterPresent, path, configPath, redacted) {
126
+ const kind = classifyChange(before, after, beforePresent, afterPresent);
127
+ if (kind === 'unchanged' && !context.options.includeUnchanged)
128
+ return;
129
+ const field = findExactField(context.fields, configPath);
130
+ const redactedValue = context.options.redactedValue ?? DEFAULT_REDACTED_VALUE;
131
+ const normalizedBefore = redacted
132
+ ? beforePresent
133
+ ? redactedValue
134
+ : undefined
135
+ : normalizeValue(before, beforePresent, 'before', kind, path, configPath, field, after);
136
+ const normalizedAfter = redacted
137
+ ? afterPresent
138
+ ? redactedValue
139
+ : undefined
140
+ : normalizeValue(after, afterPresent, 'after', kind, path, configPath, field, before);
141
+ context.rows.push({
142
+ id: path,
143
+ path,
144
+ configPath,
145
+ label: field?.label ?? (path === '$' ? (context.options.rootLabel ?? 'Value') : path),
146
+ kind,
147
+ before: normalizedBefore,
148
+ after: normalizedAfter,
149
+ beforePresent,
150
+ afterPresent,
151
+ redacted,
152
+ });
153
+ }
154
+ function normalizeValue(value, present, side, kind, path, configPath, field, otherValue) {
155
+ if (!present)
156
+ return undefined;
157
+ const mapped = field?.enumMap && hasOwn(field.enumMap, String(value)) ? field.enumMap[String(value)] : value;
158
+ if (!field?.format)
159
+ return mapped;
160
+ try {
161
+ return field.format(mapped, {
162
+ path,
163
+ configPath,
164
+ side,
165
+ kind,
166
+ before: side === 'before' ? value : otherValue,
167
+ after: side === 'after' ? value : otherValue,
168
+ });
169
+ }
170
+ catch {
171
+ return mapped;
172
+ }
173
+ }
174
+ function classifyChange(before, after, beforePresent, afterPresent) {
175
+ if (!beforePresent && afterPresent)
176
+ return 'added';
177
+ if (beforePresent && !afterPresent)
178
+ return 'removed';
179
+ return deepEqual(before, after) ? 'unchanged' : 'changed';
180
+ }
181
+ function deepEqual(left, right, seen = new WeakMap()) {
182
+ if (Object.is(left, right))
183
+ return true;
184
+ if (left instanceof Date && right instanceof Date)
185
+ return left.getTime() === right.getTime();
186
+ if (!isObject(left) || !isObject(right))
187
+ return false;
188
+ let rightSet = seen.get(left);
189
+ if (rightSet?.has(right))
190
+ return true;
191
+ if (!rightSet) {
192
+ rightSet = new WeakSet();
193
+ seen.set(left, rightSet);
194
+ }
195
+ rightSet.add(right);
196
+ if (Array.isArray(left) && Array.isArray(right)) {
197
+ if (left.length !== right.length)
198
+ return false;
199
+ return left.every((value, index) => deepEqual(value, right[index], seen));
200
+ }
201
+ if (!isPlainObject(left) || !isPlainObject(right))
202
+ return false;
203
+ const leftKeys = Object.keys(left).sort(compareText);
204
+ const rightKeys = Object.keys(right).sort(compareText);
205
+ if (leftKeys.length !== rightKeys.length || leftKeys.some((key, index) => key !== rightKeys[index]))
206
+ return false;
207
+ return leftKeys.every(key => deepEqual(left[key], right[key], seen));
208
+ }
209
+ function compareRows(left, right, fields) {
210
+ const leftOrder = explicitOrder(left.configPath, fields);
211
+ const rightOrder = explicitOrder(right.configPath, fields);
212
+ if (leftOrder !== rightOrder)
213
+ return leftOrder - rightOrder;
214
+ return compareText(left.path, right.path);
215
+ }
216
+ function explicitOrder(path, fields) {
217
+ const field = fields
218
+ .filter(candidate => Number.isFinite(candidate.order) && isPathOrDescendant(path, candidate.path))
219
+ .sort((left, right) => right.path.length - left.path.length)[0];
220
+ return field?.order ?? Number.POSITIVE_INFINITY;
221
+ }
222
+ function findExactField(fields, path) {
223
+ return fields.find(field => field.path === path);
224
+ }
225
+ function isConfigured(fields, path, property) {
226
+ return fields.some(field => Boolean(field[property]) && isPathOrDescendant(path, field.path));
227
+ }
228
+ function isPathOrDescendant(path, ancestor) {
229
+ return path === ancestor || path.startsWith(`${ancestor}.`) || path.startsWith(`${ancestor}[]`);
230
+ }
231
+ function isObject(value) {
232
+ return typeof value === 'object' && value !== null;
233
+ }
234
+ function isPlainObject(value) {
235
+ if (!isObject(value))
236
+ return false;
237
+ const prototype = Object.getPrototypeOf(value);
238
+ return prototype === Object.prototype || prototype === null;
239
+ }
240
+ function hasOwn(object, key) {
241
+ return Object.prototype.hasOwnProperty.call(object, key);
242
+ }
243
+ function compareText(left, right) {
244
+ return left < right ? -1 : left > right ? 1 : 0;
245
+ }
246
+
247
+ class SdAuditDiffValueTemplateDirective {
248
+ template = inject(TemplateRef);
249
+ static ngTemplateContextGuard(_directive, _context) {
250
+ return true;
251
+ }
252
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdAuditDiffValueTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
253
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.25", type: SdAuditDiffValueTemplateDirective, isStandalone: true, selector: "ng-template[sdAuditDiffValue]", ngImport: i0 });
254
+ }
255
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdAuditDiffValueTemplateDirective, decorators: [{
256
+ type: Directive,
257
+ args: [{
258
+ selector: 'ng-template[sdAuditDiffValue]',
259
+ standalone: true,
260
+ }]
261
+ }] });
262
+ class SdAuditDiff {
263
+ before = input(undefined, ...(ngDevMode ? [{ debugName: "before" }] : []));
264
+ after = input(undefined, ...(ngDevMode ? [{ debugName: "after" }] : []));
265
+ options = input({}, ...(ngDevMode ? [{ debugName: "options" }] : []));
266
+ mode = input('table', ...(ngDevMode ? [{ debugName: "mode" }] : []));
267
+ ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
268
+ #i18n = inject(I18nService);
269
+ rows = computed(() => {
270
+ const options = this.options();
271
+ return sdBuildAuditDiff(this.before(), this.after(), {
272
+ ...options,
273
+ rootLabel: options.rootLabel ?? this.text('value.label'),
274
+ });
275
+ }, ...(ngDevMode ? [{ debugName: "rows" }] : []));
276
+ valueTemplate = contentChild(SdAuditDiffValueTemplateDirective, ...(ngDevMode ? [{ debugName: "valueTemplate" }] : []));
277
+ text(key) {
278
+ return this.#i18n.t(`core.component.audit-diff.${key}`);
279
+ }
280
+ valueContext(row, side) {
281
+ return { $implicit: row[side], row, side };
282
+ }
283
+ displayValue(row, side) {
284
+ const present = side === 'before' ? row.beforePresent : row.afterPresent;
285
+ if (!present)
286
+ return this.text('value.not-set');
287
+ const value = row[side];
288
+ if (value === undefined)
289
+ return this.text('value.undefined');
290
+ if (value === null)
291
+ return this.text('value.null');
292
+ if (value instanceof Date)
293
+ return value.toISOString();
294
+ if (typeof value === 'boolean')
295
+ return this.text(`value.${value ? 'true' : 'false'}`);
296
+ if (typeof value === 'string')
297
+ return value;
298
+ if (typeof value === 'number' || typeof value === 'bigint')
299
+ return String(value);
300
+ return safeStringify(value);
301
+ }
302
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdAuditDiff, deps: [], target: i0.ɵɵFactoryTarget.Component });
303
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: SdAuditDiff, isStandalone: true, selector: "sd-audit-diff", inputs: { before: { classPropertyName: "before", publicName: "before", isSignal: true, isRequired: false, transformFunction: null }, after: { classPropertyName: "after", publicName: "after", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "valueTemplate", first: true, predicate: SdAuditDiffValueTemplateDirective, descendants: true, isSignal: true }], ngImport: i0, template: "@let currentRows = rows();\n@let customValue = valueTemplate();\n\n@if (currentRows.length === 0) {\n <p class=\"sd-audit-diff__empty\" data-audit-empty role=\"status\">{{ text('empty') }}</p>\n} @else if (mode() === 'table') {\n <div class=\"sd-audit-diff__table-scroll\">\n <table class=\"sd-audit-diff__table\" [attr.aria-label]=\"ariaLabel() || text('label')\">\n <thead>\n <tr>\n <th scope=\"col\">{{ text('field') }}</th>\n <th scope=\"col\">{{ text('before') }}</th>\n <th scope=\"col\">{{ text('after') }}</th>\n </tr>\n </thead>\n <tbody>\n @for (row of currentRows; track row.id) {\n <tr data-audit-row [attr.data-change-kind]=\"row.kind\">\n <th scope=\"row\">\n <span class=\"sd-audit-diff__field\">{{ row.label }}</span>\n <span class=\"sd-audit-diff__kind\">{{ text('kind.' + row.kind) }}</span>\n </th>\n <td data-audit-before>\n @if (customValue) {\n <ng-container\n [ngTemplateOutlet]=\"customValue.template\"\n [ngTemplateOutletContext]=\"valueContext(row, 'before')\"></ng-container>\n } @else {\n {{ displayValue(row, 'before') }}\n }\n </td>\n <td data-audit-after>\n @if (customValue) {\n <ng-container\n [ngTemplateOutlet]=\"customValue.template\"\n [ngTemplateOutletContext]=\"valueContext(row, 'after')\"></ng-container>\n } @else {\n {{ displayValue(row, 'after') }}\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n} @else {\n <dl class=\"sd-audit-diff__details\" [attr.aria-label]=\"ariaLabel() || text('label')\">\n @for (row of currentRows; track row.id) {\n <div class=\"sd-audit-diff__detail\" data-audit-row [attr.data-change-kind]=\"row.kind\">\n <dt>\n <span class=\"sd-audit-diff__field\">{{ row.label }}</span>\n <span class=\"sd-audit-diff__kind\">{{ text('kind.' + row.kind) }}</span>\n </dt>\n <dd data-audit-before>\n <span class=\"sd-audit-diff__side-label\">{{ text('before') }}</span>\n @if (customValue) {\n <ng-container [ngTemplateOutlet]=\"customValue.template\" [ngTemplateOutletContext]=\"valueContext(row, 'before')\"></ng-container>\n } @else {\n <span>{{ displayValue(row, 'before') }}</span>\n }\n </dd>\n <dd data-audit-after>\n <span class=\"sd-audit-diff__side-label\">{{ text('after') }}</span>\n @if (customValue) {\n <ng-container [ngTemplateOutlet]=\"customValue.template\" [ngTemplateOutletContext]=\"valueContext(row, 'after')\"></ng-container>\n } @else {\n <span>{{ displayValue(row, 'after') }}</span>\n }\n </dd>\n </div>\n }\n </dl>\n}\n", styles: [":host{display:block}.sd-audit-diff__table-scroll{overflow-x:auto;border:1px solid var(--sd-border-color, #dfe3e8);border-radius:8px}.sd-audit-diff__table{width:100%;border-collapse:collapse;background:var(--sd-surface, #fff)}.sd-audit-diff__table th,.sd-audit-diff__table td{min-width:160px;padding:10px 12px;border-bottom:1px solid var(--sd-border-color, #dfe3e8);text-align:left;vertical-align:top;overflow-wrap:anywhere}.sd-audit-diff__table th:first-child{min-width:180px}.sd-audit-diff__table tbody tr:last-child>*{border-bottom:0}.sd-audit-diff__field,.sd-audit-diff__kind,.sd-audit-diff__side-label{display:block}.sd-audit-diff__kind,.sd-audit-diff__side-label{margin-top:2px;color:var(--sd-text-muted, #5f6772);font-size:.75rem;font-weight:400}.sd-audit-diff__details{display:grid;gap:12px;margin:0}.sd-audit-diff__detail{display:grid;grid-template-columns:minmax(140px,.8fr) repeat(2,minmax(0,1fr));gap:12px;padding:12px;border:1px solid var(--sd-border-color, #dfe3e8);border-radius:8px;background:var(--sd-surface, #fff)}.sd-audit-diff__detail dt,.sd-audit-diff__detail dd{min-width:0;margin:0;overflow-wrap:anywhere}.sd-audit-diff__empty{margin:0;padding:16px;border:1px dashed var(--sd-border-color, #dfe3e8);border-radius:8px;color:var(--sd-text-muted, #5f6772);text-align:center}@media(max-width:640px){.sd-audit-diff__detail{grid-template-columns:1fr}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
304
+ }
305
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdAuditDiff, decorators: [{
306
+ type: Component,
307
+ args: [{ selector: 'sd-audit-diff', standalone: true, imports: [NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "@let currentRows = rows();\n@let customValue = valueTemplate();\n\n@if (currentRows.length === 0) {\n <p class=\"sd-audit-diff__empty\" data-audit-empty role=\"status\">{{ text('empty') }}</p>\n} @else if (mode() === 'table') {\n <div class=\"sd-audit-diff__table-scroll\">\n <table class=\"sd-audit-diff__table\" [attr.aria-label]=\"ariaLabel() || text('label')\">\n <thead>\n <tr>\n <th scope=\"col\">{{ text('field') }}</th>\n <th scope=\"col\">{{ text('before') }}</th>\n <th scope=\"col\">{{ text('after') }}</th>\n </tr>\n </thead>\n <tbody>\n @for (row of currentRows; track row.id) {\n <tr data-audit-row [attr.data-change-kind]=\"row.kind\">\n <th scope=\"row\">\n <span class=\"sd-audit-diff__field\">{{ row.label }}</span>\n <span class=\"sd-audit-diff__kind\">{{ text('kind.' + row.kind) }}</span>\n </th>\n <td data-audit-before>\n @if (customValue) {\n <ng-container\n [ngTemplateOutlet]=\"customValue.template\"\n [ngTemplateOutletContext]=\"valueContext(row, 'before')\"></ng-container>\n } @else {\n {{ displayValue(row, 'before') }}\n }\n </td>\n <td data-audit-after>\n @if (customValue) {\n <ng-container\n [ngTemplateOutlet]=\"customValue.template\"\n [ngTemplateOutletContext]=\"valueContext(row, 'after')\"></ng-container>\n } @else {\n {{ displayValue(row, 'after') }}\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n} @else {\n <dl class=\"sd-audit-diff__details\" [attr.aria-label]=\"ariaLabel() || text('label')\">\n @for (row of currentRows; track row.id) {\n <div class=\"sd-audit-diff__detail\" data-audit-row [attr.data-change-kind]=\"row.kind\">\n <dt>\n <span class=\"sd-audit-diff__field\">{{ row.label }}</span>\n <span class=\"sd-audit-diff__kind\">{{ text('kind.' + row.kind) }}</span>\n </dt>\n <dd data-audit-before>\n <span class=\"sd-audit-diff__side-label\">{{ text('before') }}</span>\n @if (customValue) {\n <ng-container [ngTemplateOutlet]=\"customValue.template\" [ngTemplateOutletContext]=\"valueContext(row, 'before')\"></ng-container>\n } @else {\n <span>{{ displayValue(row, 'before') }}</span>\n }\n </dd>\n <dd data-audit-after>\n <span class=\"sd-audit-diff__side-label\">{{ text('after') }}</span>\n @if (customValue) {\n <ng-container [ngTemplateOutlet]=\"customValue.template\" [ngTemplateOutletContext]=\"valueContext(row, 'after')\"></ng-container>\n } @else {\n <span>{{ displayValue(row, 'after') }}</span>\n }\n </dd>\n </div>\n }\n </dl>\n}\n", styles: [":host{display:block}.sd-audit-diff__table-scroll{overflow-x:auto;border:1px solid var(--sd-border-color, #dfe3e8);border-radius:8px}.sd-audit-diff__table{width:100%;border-collapse:collapse;background:var(--sd-surface, #fff)}.sd-audit-diff__table th,.sd-audit-diff__table td{min-width:160px;padding:10px 12px;border-bottom:1px solid var(--sd-border-color, #dfe3e8);text-align:left;vertical-align:top;overflow-wrap:anywhere}.sd-audit-diff__table th:first-child{min-width:180px}.sd-audit-diff__table tbody tr:last-child>*{border-bottom:0}.sd-audit-diff__field,.sd-audit-diff__kind,.sd-audit-diff__side-label{display:block}.sd-audit-diff__kind,.sd-audit-diff__side-label{margin-top:2px;color:var(--sd-text-muted, #5f6772);font-size:.75rem;font-weight:400}.sd-audit-diff__details{display:grid;gap:12px;margin:0}.sd-audit-diff__detail{display:grid;grid-template-columns:minmax(140px,.8fr) repeat(2,minmax(0,1fr));gap:12px;padding:12px;border:1px solid var(--sd-border-color, #dfe3e8);border-radius:8px;background:var(--sd-surface, #fff)}.sd-audit-diff__detail dt,.sd-audit-diff__detail dd{min-width:0;margin:0;overflow-wrap:anywhere}.sd-audit-diff__empty{margin:0;padding:16px;border:1px dashed var(--sd-border-color, #dfe3e8);border-radius:8px;color:var(--sd-text-muted, #5f6772);text-align:center}@media(max-width:640px){.sd-audit-diff__detail{grid-template-columns:1fr}}\n"] }]
308
+ }], propDecorators: { before: [{ type: i0.Input, args: [{ isSignal: true, alias: "before", required: false }] }], after: [{ type: i0.Input, args: [{ isSignal: true, alias: "after", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], valueTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SdAuditDiffValueTemplateDirective), { isSignal: true }] }] } });
309
+ function safeStringify(value) {
310
+ const seen = new WeakSet();
311
+ try {
312
+ const result = JSON.stringify(value, (_key, current) => {
313
+ if (typeof current !== 'object' || current === null)
314
+ return current;
315
+ if (seen.has(current))
316
+ return '[Circular]';
317
+ seen.add(current);
318
+ return current;
319
+ });
320
+ return result ?? String(value);
321
+ }
322
+ catch {
323
+ return String(value);
324
+ }
325
+ }
326
+
327
+ /**
328
+ * Generated bundle index. Do not edit.
329
+ */
330
+
331
+ export { SdAuditDiff, SdAuditDiffValueTemplateDirective, sdBuildAuditDiff };
332
+ //# sourceMappingURL=sdcorejs-angular-components-audit-diff.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdcorejs-angular-components-audit-diff.mjs","sources":["../../../projects/sdcorejs-angular/components/audit-diff/src/audit-diff.engine.ts","../../../projects/sdcorejs-angular/components/audit-diff/src/audit-diff.component.ts","../../../projects/sdcorejs-angular/components/audit-diff/src/audit-diff.component.html","../../../projects/sdcorejs-angular/components/audit-diff/sdcorejs-angular-components-audit-diff.ts"],"sourcesContent":["export type SdAuditDiffKind = 'added' | 'removed' | 'changed' | 'unchanged';\nexport type SdAuditDiffSide = 'before' | 'after';\nexport type SdAuditDiffArrayKey = string | ((item: unknown) => unknown);\n\nexport interface SdAuditDiffFormatContext {\n readonly path: string;\n readonly configPath: string;\n readonly side: SdAuditDiffSide;\n readonly kind: SdAuditDiffKind;\n readonly before: unknown;\n readonly after: unknown;\n}\n\nexport interface SdAuditDiffField {\n readonly path: string;\n readonly label?: string;\n readonly order?: number;\n readonly hidden?: boolean;\n readonly redacted?: boolean;\n readonly arrayKey?: SdAuditDiffArrayKey;\n readonly enumMap?: Readonly<Record<string, unknown>>;\n readonly format?: (value: unknown, context: SdAuditDiffFormatContext) => unknown;\n}\n\nexport interface SdAuditDiffOptions {\n readonly fields?: readonly SdAuditDiffField[];\n readonly includeUnchanged?: boolean;\n readonly redactedValue?: unknown;\n readonly rootLabel?: string;\n}\n\nexport interface SdAuditDiffRow {\n readonly id: string;\n readonly path: string;\n readonly configPath: string;\n readonly label: string;\n readonly kind: SdAuditDiffKind;\n readonly before: unknown;\n readonly after: unknown;\n readonly beforePresent: boolean;\n readonly afterPresent: boolean;\n readonly redacted: boolean;\n}\n\ninterface WalkContext {\n readonly options: SdAuditDiffOptions;\n readonly fields: readonly SdAuditDiffField[];\n readonly rows: SdAuditDiffRow[];\n readonly activeBefore: WeakSet<object>;\n readonly activeAfter: WeakSet<object>;\n}\n\ninterface StableArrayItem {\n readonly key: unknown;\n readonly value: unknown;\n}\n\nconst DEFAULT_REDACTED_VALUE = '••••••';\n\nexport function sdBuildAuditDiff(before: unknown, after: unknown, options: SdAuditDiffOptions = {}): SdAuditDiffRow[] {\n const context: WalkContext = {\n options,\n fields: options.fields ?? [],\n rows: [],\n activeBefore: new WeakSet<object>(),\n activeAfter: new WeakSet<object>(),\n };\n walkValue(context, before, after, true, true, '$', '$');\n return context.rows.sort((left, right) => compareRows(left, right, context.fields));\n}\n\nfunction walkValue(\n context: WalkContext,\n before: unknown,\n after: unknown,\n beforePresent: boolean,\n afterPresent: boolean,\n path: string,\n configPath: string\n): void {\n if (isConfigured(context.fields, configPath, 'hidden')) return;\n if (isConfigured(context.fields, configPath, 'redacted')) {\n addAtomicRow(context, before, after, beforePresent, afterPresent, path, configPath, true);\n return;\n }\n\n const field = findExactField(context.fields, configPath);\n if (field?.format || field?.enumMap) {\n addAtomicRow(context, before, after, beforePresent, afterPresent, path, configPath, false);\n return;\n }\n\n const beforeArray = Array.isArray(before);\n const afterArray = Array.isArray(after);\n if (beforeArray || afterArray) {\n if ((!beforePresent && afterArray) || (beforeArray && !afterPresent) || (beforeArray && afterArray)) {\n const arrayKey = field?.arrayKey;\n if (arrayKey && walkStableArray(context, beforeArray ? before : [], afterArray ? after : [], path, configPath, arrayKey)) return;\n }\n addAtomicRow(context, before, after, beforePresent, afterPresent, path, configPath, false);\n return;\n }\n\n const beforeObject = isPlainObject(before);\n const afterObject = isPlainObject(after);\n const canRecurse = (beforeObject && afterObject) || (beforeObject && !afterPresent) || (afterObject && !beforePresent);\n if (canRecurse) {\n if ((beforeObject && context.activeBefore.has(before)) || (afterObject && context.activeAfter.has(after))) return;\n if (beforeObject) context.activeBefore.add(before);\n if (afterObject) context.activeAfter.add(after);\n const beforeRecord = beforeObject ? before : {};\n const afterRecord = afterObject ? after : {};\n const keys = [...new Set([...Object.keys(beforeRecord), ...Object.keys(afterRecord)])].sort(compareText);\n if (keys.length === 0) {\n addAtomicRow(context, before, after, beforePresent, afterPresent, path, configPath, false);\n if (beforeObject) context.activeBefore.delete(before);\n if (afterObject) context.activeAfter.delete(after);\n return;\n }\n for (const key of keys) {\n const childBeforePresent = beforeObject && hasOwn(beforeRecord, key);\n const childAfterPresent = afterObject && hasOwn(afterRecord, key);\n walkValue(\n context,\n childBeforePresent ? beforeRecord[key] : undefined,\n childAfterPresent ? afterRecord[key] : undefined,\n childBeforePresent,\n childAfterPresent,\n path === '$' ? key : `${path}.${key}`,\n configPath === '$' ? key : `${configPath}.${key}`\n );\n }\n if (beforeObject) context.activeBefore.delete(before);\n if (afterObject) context.activeAfter.delete(after);\n return;\n }\n\n addAtomicRow(context, before, after, beforePresent, afterPresent, path, configPath, false);\n}\n\nfunction walkStableArray(\n context: WalkContext,\n before: readonly unknown[],\n after: readonly unknown[],\n path: string,\n configPath: string,\n keySelector: SdAuditDiffArrayKey\n): boolean {\n const beforeItems = indexStableArray(before, keySelector);\n const afterItems = indexStableArray(after, keySelector);\n if (!beforeItems || !afterItems) return false;\n\n const keys = [...new Set([...beforeItems.keys(), ...afterItems.keys()])].sort(compareText);\n const keyName = typeof keySelector === 'string' ? keySelector : 'key';\n for (const key of keys) {\n const beforeItem = beforeItems.get(key);\n const afterItem = afterItems.get(key);\n const itemPath = `${path}[${keyName}=${encodeURIComponent(key)}]`;\n const itemConfigPath = `${configPath}[]`;\n if (!beforeItem || !afterItem) {\n walkValue(context, beforeItem?.value, afterItem?.value, Boolean(beforeItem), Boolean(afterItem), itemPath, itemConfigPath);\n continue;\n }\n walkValue(context, beforeItem.value, afterItem.value, true, true, itemPath, itemConfigPath);\n }\n return true;\n}\n\nfunction indexStableArray(items: readonly unknown[], keySelector: SdAuditDiffArrayKey): Map<string, StableArrayItem> | null {\n const result = new Map<string, StableArrayItem>();\n for (const item of items) {\n let key: unknown;\n try {\n key = typeof keySelector === 'function' ? keySelector(item) : isObject(item) ? item[keySelector] : undefined;\n } catch {\n return null;\n }\n const serialized = serializeStableKey(key);\n if (serialized === null || result.has(serialized)) return null;\n result.set(serialized, { key, value: item });\n }\n return result;\n}\n\nfunction serializeStableKey(key: unknown): string | null {\n if (key === null) return 'null:null';\n switch (typeof key) {\n case 'string':\n case 'number':\n case 'bigint':\n case 'boolean':\n return `${typeof key}:${String(key)}`;\n default:\n return null;\n }\n}\n\nfunction addAtomicRow(\n context: WalkContext,\n before: unknown,\n after: unknown,\n beforePresent: boolean,\n afterPresent: boolean,\n path: string,\n configPath: string,\n redacted: boolean\n): void {\n const kind = classifyChange(before, after, beforePresent, afterPresent);\n if (kind === 'unchanged' && !context.options.includeUnchanged) return;\n\n const field = findExactField(context.fields, configPath);\n const redactedValue = context.options.redactedValue ?? DEFAULT_REDACTED_VALUE;\n const normalizedBefore = redacted\n ? beforePresent\n ? redactedValue\n : undefined\n : normalizeValue(before, beforePresent, 'before', kind, path, configPath, field, after);\n const normalizedAfter = redacted\n ? afterPresent\n ? redactedValue\n : undefined\n : normalizeValue(after, afterPresent, 'after', kind, path, configPath, field, before);\n\n context.rows.push({\n id: path,\n path,\n configPath,\n label: field?.label ?? (path === '$' ? (context.options.rootLabel ?? 'Value') : path),\n kind,\n before: normalizedBefore,\n after: normalizedAfter,\n beforePresent,\n afterPresent,\n redacted,\n });\n}\n\nfunction normalizeValue(\n value: unknown,\n present: boolean,\n side: SdAuditDiffSide,\n kind: SdAuditDiffKind,\n path: string,\n configPath: string,\n field: SdAuditDiffField | undefined,\n otherValue: unknown\n): unknown {\n if (!present) return undefined;\n const mapped = field?.enumMap && hasOwn(field.enumMap, String(value)) ? field.enumMap[String(value)] : value;\n if (!field?.format) return mapped;\n try {\n return field.format(mapped, {\n path,\n configPath,\n side,\n kind,\n before: side === 'before' ? value : otherValue,\n after: side === 'after' ? value : otherValue,\n });\n } catch {\n return mapped;\n }\n}\n\nfunction classifyChange(before: unknown, after: unknown, beforePresent: boolean, afterPresent: boolean): SdAuditDiffKind {\n if (!beforePresent && afterPresent) return 'added';\n if (beforePresent && !afterPresent) return 'removed';\n return deepEqual(before, after) ? 'unchanged' : 'changed';\n}\n\nfunction deepEqual(left: unknown, right: unknown, seen = new WeakMap<object, WeakSet<object>>()): boolean {\n if (Object.is(left, right)) return true;\n if (left instanceof Date && right instanceof Date) return left.getTime() === right.getTime();\n if (!isObject(left) || !isObject(right)) return false;\n let rightSet = seen.get(left);\n if (rightSet?.has(right)) return true;\n if (!rightSet) {\n rightSet = new WeakSet<object>();\n seen.set(left, rightSet);\n }\n rightSet.add(right);\n if (Array.isArray(left) && Array.isArray(right)) {\n if (left.length !== right.length) return false;\n return left.every((value, index) => deepEqual(value, right[index], seen));\n }\n if (!isPlainObject(left) || !isPlainObject(right)) return false;\n const leftKeys = Object.keys(left).sort(compareText);\n const rightKeys = Object.keys(right).sort(compareText);\n if (leftKeys.length !== rightKeys.length || leftKeys.some((key, index) => key !== rightKeys[index])) return false;\n return leftKeys.every(key => deepEqual(left[key], right[key], seen));\n}\n\nfunction compareRows(left: SdAuditDiffRow, right: SdAuditDiffRow, fields: readonly SdAuditDiffField[]): number {\n const leftOrder = explicitOrder(left.configPath, fields);\n const rightOrder = explicitOrder(right.configPath, fields);\n if (leftOrder !== rightOrder) return leftOrder - rightOrder;\n return compareText(left.path, right.path);\n}\n\nfunction explicitOrder(path: string, fields: readonly SdAuditDiffField[]): number {\n const field = fields\n .filter(candidate => Number.isFinite(candidate.order) && isPathOrDescendant(path, candidate.path))\n .sort((left, right) => right.path.length - left.path.length)[0];\n return field?.order ?? Number.POSITIVE_INFINITY;\n}\n\nfunction findExactField(fields: readonly SdAuditDiffField[], path: string): SdAuditDiffField | undefined {\n return fields.find(field => field.path === path);\n}\n\nfunction isConfigured(fields: readonly SdAuditDiffField[], path: string, property: 'hidden' | 'redacted'): boolean {\n return fields.some(field => Boolean(field[property]) && isPathOrDescendant(path, field.path));\n}\n\nfunction isPathOrDescendant(path: string, ancestor: string): boolean {\n return path === ancestor || path.startsWith(`${ancestor}.`) || path.startsWith(`${ancestor}[]`);\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (!isObject(value)) return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nfunction hasOwn(object: object, key: PropertyKey): boolean {\n return Object.prototype.hasOwnProperty.call(object, key);\n}\n\nfunction compareText(left: string, right: string): number {\n return left < right ? -1 : left > right ? 1 : 0;\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, Directive, TemplateRef, computed, contentChild, inject, input } from '@angular/core';\nimport { I18nService } from '@sdcorejs/angular/i18n';\nimport { SdAuditDiffOptions, SdAuditDiffRow, SdAuditDiffSide, sdBuildAuditDiff } from './audit-diff.engine';\n\nexport type SdAuditDiffMode = 'table' | 'detail-list';\n\nexport interface SdAuditDiffValueTemplateContext {\n readonly $implicit: unknown;\n readonly row: SdAuditDiffRow;\n readonly side: SdAuditDiffSide;\n}\n\n@Directive({\n selector: 'ng-template[sdAuditDiffValue]',\n standalone: true,\n})\nexport class SdAuditDiffValueTemplateDirective {\n readonly template = inject<TemplateRef<SdAuditDiffValueTemplateContext>>(TemplateRef);\n\n static ngTemplateContextGuard(\n _directive: SdAuditDiffValueTemplateDirective,\n _context: unknown\n ): _context is SdAuditDiffValueTemplateContext {\n return true;\n }\n}\n\n@Component({\n selector: 'sd-audit-diff',\n standalone: true,\n imports: [NgTemplateOutlet],\n templateUrl: './audit-diff.component.html',\n styleUrl: './audit-diff.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SdAuditDiff {\n readonly before = input<unknown>(undefined);\n readonly after = input<unknown>(undefined);\n readonly options = input<SdAuditDiffOptions>({});\n readonly mode = input<SdAuditDiffMode>('table');\n readonly ariaLabel = input<string | undefined>(undefined);\n\n readonly #i18n = inject(I18nService);\n readonly rows = computed(() => {\n const options = this.options();\n return sdBuildAuditDiff(this.before(), this.after(), {\n ...options,\n rootLabel: options.rootLabel ?? this.text('value.label'),\n });\n });\n protected readonly valueTemplate = contentChild(SdAuditDiffValueTemplateDirective);\n\n protected text(key: string): string {\n return this.#i18n.t(`core.component.audit-diff.${key}`);\n }\n\n protected valueContext(row: SdAuditDiffRow, side: SdAuditDiffSide): SdAuditDiffValueTemplateContext {\n return { $implicit: row[side], row, side };\n }\n\n protected displayValue(row: SdAuditDiffRow, side: SdAuditDiffSide): string {\n const present = side === 'before' ? row.beforePresent : row.afterPresent;\n if (!present) return this.text('value.not-set');\n const value = row[side];\n if (value === undefined) return this.text('value.undefined');\n if (value === null) return this.text('value.null');\n if (value instanceof Date) return value.toISOString();\n if (typeof value === 'boolean') return this.text(`value.${value ? 'true' : 'false'}`);\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'bigint') return String(value);\n return safeStringify(value);\n }\n}\n\nfunction safeStringify(value: unknown): string {\n const seen = new WeakSet<object>();\n try {\n const result = JSON.stringify(value, (_key, current: unknown) => {\n if (typeof current !== 'object' || current === null) return current;\n if (seen.has(current)) return '[Circular]';\n seen.add(current);\n return current;\n });\n return result ?? String(value);\n } catch {\n return String(value);\n }\n}\n","@let currentRows = rows();\n@let customValue = valueTemplate();\n\n@if (currentRows.length === 0) {\n <p class=\"sd-audit-diff__empty\" data-audit-empty role=\"status\">{{ text('empty') }}</p>\n} @else if (mode() === 'table') {\n <div class=\"sd-audit-diff__table-scroll\">\n <table class=\"sd-audit-diff__table\" [attr.aria-label]=\"ariaLabel() || text('label')\">\n <thead>\n <tr>\n <th scope=\"col\">{{ text('field') }}</th>\n <th scope=\"col\">{{ text('before') }}</th>\n <th scope=\"col\">{{ text('after') }}</th>\n </tr>\n </thead>\n <tbody>\n @for (row of currentRows; track row.id) {\n <tr data-audit-row [attr.data-change-kind]=\"row.kind\">\n <th scope=\"row\">\n <span class=\"sd-audit-diff__field\">{{ row.label }}</span>\n <span class=\"sd-audit-diff__kind\">{{ text('kind.' + row.kind) }}</span>\n </th>\n <td data-audit-before>\n @if (customValue) {\n <ng-container\n [ngTemplateOutlet]=\"customValue.template\"\n [ngTemplateOutletContext]=\"valueContext(row, 'before')\"></ng-container>\n } @else {\n {{ displayValue(row, 'before') }}\n }\n </td>\n <td data-audit-after>\n @if (customValue) {\n <ng-container\n [ngTemplateOutlet]=\"customValue.template\"\n [ngTemplateOutletContext]=\"valueContext(row, 'after')\"></ng-container>\n } @else {\n {{ displayValue(row, 'after') }}\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n} @else {\n <dl class=\"sd-audit-diff__details\" [attr.aria-label]=\"ariaLabel() || text('label')\">\n @for (row of currentRows; track row.id) {\n <div class=\"sd-audit-diff__detail\" data-audit-row [attr.data-change-kind]=\"row.kind\">\n <dt>\n <span class=\"sd-audit-diff__field\">{{ row.label }}</span>\n <span class=\"sd-audit-diff__kind\">{{ text('kind.' + row.kind) }}</span>\n </dt>\n <dd data-audit-before>\n <span class=\"sd-audit-diff__side-label\">{{ text('before') }}</span>\n @if (customValue) {\n <ng-container [ngTemplateOutlet]=\"customValue.template\" [ngTemplateOutletContext]=\"valueContext(row, 'before')\"></ng-container>\n } @else {\n <span>{{ displayValue(row, 'before') }}</span>\n }\n </dd>\n <dd data-audit-after>\n <span class=\"sd-audit-diff__side-label\">{{ text('after') }}</span>\n @if (customValue) {\n <ng-container [ngTemplateOutlet]=\"customValue.template\" [ngTemplateOutletContext]=\"valueContext(row, 'after')\"></ng-container>\n } @else {\n <span>{{ displayValue(row, 'after') }}</span>\n }\n </dd>\n </div>\n }\n </dl>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -36,6 +36,7 @@ class SdBadge {
36
36
  // ==========================================
37
37
  // 2. OUTPUT
38
38
  // ==========================================
39
+ // why: the template reads EventEmitter.observed to expose pointer styling only when a click listener exists.
39
40
  click = new EventEmitter();
40
41
  onClick = (event) => {
41
42
  event.stopPropagation();
@@ -1 +1 @@
1
- {"version":3,"file":"sdcorejs-angular-components-badge.mjs","sources":["../../../projects/sdcorejs-angular/components/badge/src/badge.component.ts","../../../projects/sdcorejs-angular/components/badge/src/badge.component.html","../../../projects/sdcorejs-angular/components/badge/sdcorejs-angular-components-badge.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, EventEmitter, Output, booleanAttribute, computed, input } from '@angular/core';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { SdIcon, type SdIconSet } from '@sdcorejs/angular/modules/icon';\nimport { Color, Size } from '@sdcorejs/utils/models';\n\n// Export các Type để dùng chung\nexport type SdBadgeType = 'tag' | 'round' | 'icon';\n\n@Component({\n selector: 'sd-badge',\n templateUrl: './badge.component.html',\n styleUrl: './badge.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [CommonModule, SdIcon, MatTooltipModule],\n})\nexport class SdBadge {\n defaultIcon = 'fiber_manual_record';\n\n // ==========================================\n // 1. SIGNAL INPUTS\n // ==========================================\n type = input<SdBadgeType, SdBadgeType | undefined | null>('icon', {\n transform: value => value || 'icon',\n });\n\n color = input<Color, Color | undefined | null>('secondary', {\n transform: value => value || 'secondary',\n });\n\n primary = input(false, { transform: booleanAttribute });\n secondary = input(false, { transform: booleanAttribute });\n success = input(false, { transform: booleanAttribute });\n info = input(false, { transform: booleanAttribute });\n warning = input(false, { transform: booleanAttribute });\n error = input(false, { transform: booleanAttribute });\n\n fontSet = input<SdIconSet | undefined, SdIconSet | undefined | null>(undefined, {\n transform: value => value ?? undefined,\n });\n\n title = input<string | number | undefined | null>();\n description = input<string | undefined | null>();\n tooltip = input<string | undefined | null>();\n icon = input<string | undefined | null>();\n\n size = input<Size, Size | undefined | null>('sm', {\n transform: value => value || 'sm',\n });\n\n // ==========================================\n // 2. OUTPUT\n // ==========================================\n @Output() click = new EventEmitter<Event>();\n\n onClick = (event: Event) => {\n event.stopPropagation();\n this.click.emit(event);\n };\n\n // ==========================================\n // 3. COMPUTED STATE\n // ==========================================\n\n effectiveColor = computed(() => {\n if (this.primary()) return 'primary';\n if (this.secondary()) return 'secondary';\n if (this.success()) return 'success';\n if (this.info()) return 'info';\n if (this.warning()) return 'warning';\n if (this.error()) return 'error';\n return this.color();\n });\n\n baseColorClasses = computed(() => {\n const c = this.effectiveColor();\n return {\n 'c-primary': c === 'primary',\n 'c-secondary': c === 'secondary',\n 'c-info': c === 'info',\n 'c-success': c === 'success',\n 'c-warning': c === 'warning',\n 'c-error': c === 'error',\n };\n });\n\n iconColorClasses = computed(() => {\n const c = this.effectiveColor();\n return {\n 'c-primary': c === 'primary',\n 'c-secondary': c === 'secondary',\n 'c-info': c === 'info',\n 'c-success': c === 'success',\n 'c-warning': c === 'warning',\n 'c-error': c === 'error',\n };\n });\n\n iconSizeAndFontClasses = computed(() => {\n const s = this.size();\n return {\n 'c-sm': s === 'sm',\n 'c-md': s === 'md',\n 'c-lg': s === 'lg',\n };\n });\n\n iconCssSize = computed(() => {\n const s = this.size();\n if (s === 'md') return '18px';\n if (s === 'lg') return '24px';\n return '16px';\n });\n\n // why: keep container size classes separate from icon element size classes.\n containerSizeClasses = computed(() => {\n const s = this.size();\n return {\n 'c-badge--sm': s === 'sm',\n 'c-badge--md': s === 'md',\n 'c-badge--lg': s === 'lg',\n };\n });\n\n // GỘP CLASS CHO BADGE TYPE = 'TAG' (cũng dùng lại cho 'ROUND' khi có icon)\n tagIconCombinedClasses = computed(() => ({\n ...this.iconSizeAndFontClasses(),\n ...this.baseColorClasses(),\n }));\n\n // GỘP CLASS CHO CONTAINER round/tag (color tint + size modifier)\n containerCombinedClasses = computed(() => ({\n ...this.baseColorClasses(),\n ...this.containerSizeClasses(),\n }));\n\n // GỘP CLASS CHO BADGE TYPE = 'ICON'\n iconCombinedClasses = computed(() => ({\n ...this.iconSizeAndFontClasses(),\n ...this.iconColorClasses(),\n }));\n}\n","@let _type = type();\n@let _tooltip = tooltip();\n@let _title = title();\n@let _description = description();\n@let _fontSet = fontSet();\n@let _iconCssSize = iconCssSize();\n@let iconName = icon() || defaultIcon;\n@let isPointer = click.observed;\n\n@if (_type === 'round') {\n <div\n class=\"c-badge\"\n matTooltipPosition=\"above\"\n [matTooltip]=\"_tooltip || ''\"\n matTooltipClass=\"sd-multiline-tooltip\"\n [ngClass]=\"containerCombinedClasses()\"\n [class.c-badge--has-icon]=\"!!icon()\"\n [class.pointer]=\"isPointer\"\n (click)=\"onClick($event)\"\n aria-hidden=\"true\">\n @if (icon()) {\n <sd-icon\n class=\"c-material-icon\"\n [name]=\"iconName\"\n [fontSet]=\"_fontSet\"\n [size]=\"_iconCssSize\"\n [ngClass]=\"tagIconCombinedClasses()\"></sd-icon>\n }\n <span class=\"c-badge-title\">{{ _title }}</span>\n </div>\n} @else if (_type === 'tag') {\n <div\n class=\"c-badge c-badge--tag\"\n matTooltipPosition=\"above\"\n [matTooltip]=\"_tooltip || ''\"\n matTooltipClass=\"sd-multiline-tooltip\"\n [ngClass]=\"containerCombinedClasses()\"\n [class.pointer]=\"isPointer\"\n (click)=\"onClick($event)\"\n aria-hidden=\"true\">\n <div class=\"c-icon d-flex align-items-center\">\n @if (icon()) {\n <sd-icon\n class=\"c-material-icon mr-4\"\n [name]=\"iconName\"\n [fontSet]=\"_fontSet\"\n [size]=\"_iconCssSize\"\n [ngClass]=\"tagIconCombinedClasses()\"></sd-icon>\n }\n <div class=\"d-flex flex-column align-items-start\">\n <span class=\"T14R c-badge-title\">{{ _title }}</span>\n @if (_description) {\n <span class=\"T12R c-badge-description\">{{ _description }}</span>\n }\n </div>\n </div>\n </div>\n} @else {\n <div\n class=\"d-flex\"\n matTooltipPosition=\"above\"\n [matTooltip]=\"_tooltip || ''\"\n matTooltipClass=\"sd-multiline-tooltip\"\n [class.c-badge-icon]=\"_type === 'icon'\"\n [class.pointer]=\"isPointer\"\n (click)=\"onClick($event)\"\n aria-hidden=\"true\">\n <div class=\"c-icon d-flex align-items-center\">\n <sd-icon\n class=\"c-material-icon mr-4\"\n [name]=\"iconName\"\n [fontSet]=\"_fontSet\"\n [size]=\"_iconCssSize\"\n [ngClass]=\"iconCombinedClasses()\"></sd-icon>\n <div class=\"d-flex flex-column\">\n <span class=\"T14R c-badge-title\">{{ _title }}</span>\n @if (_description) {\n <span class=\"T10R c-badge-description\">{{ _description }}</span>\n }\n </div>\n </div>\n </div>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sdcorejs-angular-components-badge.mjs","sources":["../../../projects/sdcorejs-angular/components/badge/src/badge.component.ts","../../../projects/sdcorejs-angular/components/badge/src/badge.component.html","../../../projects/sdcorejs-angular/components/badge/sdcorejs-angular-components-badge.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, EventEmitter, Output, booleanAttribute, computed, input } from '@angular/core';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { SdIcon, type SdIconSet } from '@sdcorejs/angular/modules/icon';\nimport { Color, Size } from '@sdcorejs/utils/models';\n\n// Export các Type để dùng chung\nexport type SdBadgeType = 'tag' | 'round' | 'icon';\n\n@Component({\n selector: 'sd-badge',\n templateUrl: './badge.component.html',\n styleUrl: './badge.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [CommonModule, SdIcon, MatTooltipModule],\n})\nexport class SdBadge {\n defaultIcon = 'fiber_manual_record';\n\n // ==========================================\n // 1. SIGNAL INPUTS\n // ==========================================\n type = input<SdBadgeType, SdBadgeType | undefined | null>('icon', {\n transform: value => value || 'icon',\n });\n\n color = input<Color, Color | undefined | null>('secondary', {\n transform: value => value || 'secondary',\n });\n\n primary = input(false, { transform: booleanAttribute });\n secondary = input(false, { transform: booleanAttribute });\n success = input(false, { transform: booleanAttribute });\n info = input(false, { transform: booleanAttribute });\n warning = input(false, { transform: booleanAttribute });\n error = input(false, { transform: booleanAttribute });\n\n fontSet = input<SdIconSet | undefined, SdIconSet | undefined | null>(undefined, {\n transform: value => value ?? undefined,\n });\n\n title = input<string | number | undefined | null>();\n description = input<string | undefined | null>();\n tooltip = input<string | undefined | null>();\n icon = input<string | undefined | null>();\n\n size = input<Size, Size | undefined | null>('sm', {\n transform: value => value || 'sm',\n });\n\n // ==========================================\n // 2. OUTPUT\n // ==========================================\n // why: the template reads EventEmitter.observed to expose pointer styling only when a click listener exists.\n @Output() readonly click = new EventEmitter<Event>();\n\n onClick = (event: Event) => {\n event.stopPropagation();\n this.click.emit(event);\n };\n\n // ==========================================\n // 3. COMPUTED STATE\n // ==========================================\n\n effectiveColor = computed(() => {\n if (this.primary()) return 'primary';\n if (this.secondary()) return 'secondary';\n if (this.success()) return 'success';\n if (this.info()) return 'info';\n if (this.warning()) return 'warning';\n if (this.error()) return 'error';\n return this.color();\n });\n\n baseColorClasses = computed(() => {\n const c = this.effectiveColor();\n return {\n 'c-primary': c === 'primary',\n 'c-secondary': c === 'secondary',\n 'c-info': c === 'info',\n 'c-success': c === 'success',\n 'c-warning': c === 'warning',\n 'c-error': c === 'error',\n };\n });\n\n iconColorClasses = computed(() => {\n const c = this.effectiveColor();\n return {\n 'c-primary': c === 'primary',\n 'c-secondary': c === 'secondary',\n 'c-info': c === 'info',\n 'c-success': c === 'success',\n 'c-warning': c === 'warning',\n 'c-error': c === 'error',\n };\n });\n\n iconSizeAndFontClasses = computed(() => {\n const s = this.size();\n return {\n 'c-sm': s === 'sm',\n 'c-md': s === 'md',\n 'c-lg': s === 'lg',\n };\n });\n\n iconCssSize = computed(() => {\n const s = this.size();\n if (s === 'md') return '18px';\n if (s === 'lg') return '24px';\n return '16px';\n });\n\n // why: keep container size classes separate from icon element size classes.\n containerSizeClasses = computed(() => {\n const s = this.size();\n return {\n 'c-badge--sm': s === 'sm',\n 'c-badge--md': s === 'md',\n 'c-badge--lg': s === 'lg',\n };\n });\n\n // GỘP CLASS CHO BADGE TYPE = 'TAG' (cũng dùng lại cho 'ROUND' khi có icon)\n tagIconCombinedClasses = computed(() => ({\n ...this.iconSizeAndFontClasses(),\n ...this.baseColorClasses(),\n }));\n\n // GỘP CLASS CHO CONTAINER round/tag (color tint + size modifier)\n containerCombinedClasses = computed(() => ({\n ...this.baseColorClasses(),\n ...this.containerSizeClasses(),\n }));\n\n // GỘP CLASS CHO BADGE TYPE = 'ICON'\n iconCombinedClasses = computed(() => ({\n ...this.iconSizeAndFontClasses(),\n ...this.iconColorClasses(),\n }));\n}\n","@let _type = type();\n@let _tooltip = tooltip();\n@let _title = title();\n@let _description = description();\n@let _fontSet = fontSet();\n@let _iconCssSize = iconCssSize();\n@let iconName = icon() || defaultIcon;\n@let isPointer = click.observed;\n\n@if (_type === 'round') {\n <div\n class=\"c-badge\"\n matTooltipPosition=\"above\"\n [matTooltip]=\"_tooltip || ''\"\n matTooltipClass=\"sd-multiline-tooltip\"\n [ngClass]=\"containerCombinedClasses()\"\n [class.c-badge--has-icon]=\"!!icon()\"\n [class.pointer]=\"isPointer\"\n (click)=\"onClick($event)\"\n aria-hidden=\"true\">\n @if (icon()) {\n <sd-icon\n class=\"c-material-icon\"\n [name]=\"iconName\"\n [fontSet]=\"_fontSet\"\n [size]=\"_iconCssSize\"\n [ngClass]=\"tagIconCombinedClasses()\"></sd-icon>\n }\n <span class=\"c-badge-title\">{{ _title }}</span>\n </div>\n} @else if (_type === 'tag') {\n <div\n class=\"c-badge c-badge--tag\"\n matTooltipPosition=\"above\"\n [matTooltip]=\"_tooltip || ''\"\n matTooltipClass=\"sd-multiline-tooltip\"\n [ngClass]=\"containerCombinedClasses()\"\n [class.pointer]=\"isPointer\"\n (click)=\"onClick($event)\"\n aria-hidden=\"true\">\n <div class=\"c-icon d-flex align-items-center\">\n @if (icon()) {\n <sd-icon\n class=\"c-material-icon mr-4\"\n [name]=\"iconName\"\n [fontSet]=\"_fontSet\"\n [size]=\"_iconCssSize\"\n [ngClass]=\"tagIconCombinedClasses()\"></sd-icon>\n }\n <div class=\"d-flex flex-column align-items-start\">\n <span class=\"T14R c-badge-title\">{{ _title }}</span>\n @if (_description) {\n <span class=\"T12R c-badge-description\">{{ _description }}</span>\n }\n </div>\n </div>\n </div>\n} @else {\n <div\n class=\"d-flex\"\n matTooltipPosition=\"above\"\n [matTooltip]=\"_tooltip || ''\"\n matTooltipClass=\"sd-multiline-tooltip\"\n [class.c-badge-icon]=\"_type === 'icon'\"\n [class.pointer]=\"isPointer\"\n (click)=\"onClick($event)\"\n aria-hidden=\"true\">\n <div class=\"c-icon d-flex align-items-center\">\n <sd-icon\n class=\"c-material-icon mr-4\"\n [name]=\"iconName\"\n [fontSet]=\"_fontSet\"\n [size]=\"_iconCssSize\"\n [ngClass]=\"iconCombinedClasses()\"></sd-icon>\n <div class=\"d-flex flex-column\">\n <span class=\"T14R c-badge-title\">{{ _title }}</span>\n @if (_description) {\n <span class=\"T10R c-badge-description\">{{ _description }}</span>\n }\n </div>\n </div>\n </div>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}