@leanix/components 0.4.758 → 0.4.760
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.
- package/fesm2022/leanix-components-ui5.mjs.map +1 -1
- package/fesm2022/leanix-components.mjs +478 -477
- package/fesm2022/leanix-components.mjs.map +1 -1
- package/index.d.ts +1 -0
- package/lib/core-ui/core-ui.constants.d.ts +0 -13
- package/lib/core-ui/icon/icon-map.d.ts +13 -0
- package/lib/core-ui/tooltip/tooltip.directive.d.ts +1 -1
- package/lib/forms-ui/components/single-select/single-select.component.d.ts +1 -1
- package/lib/tab-ui/components/tab-group/tab-group.component.d.ts +1 -1
- package/package.json +1 -1
- package/ui5/components/breadcrumbs.component.d.ts +1 -1
- package/ui5/index.d.ts +1 -1
|
@@ -81,272 +81,6 @@ const DATE_FORMATS = new InjectionToken('DATE_FORMATS', {
|
|
|
81
81
|
const DATE_FN_LOCALE = new InjectionToken('DATE_FN_LOCALE');
|
|
82
82
|
const LOCALE_FN = new InjectionToken('LOCALE_FN');
|
|
83
83
|
const GLOBAL_TRANSLATION_OPTIONS = new InjectionToken('GLOBAL_TRANSLATION_OPTIONS');
|
|
84
|
-
/**
|
|
85
|
-
* map Font Awesome -> SAP icons
|
|
86
|
-
* [0]: regular icon
|
|
87
|
-
* [1]: solid icon alternative (if available)
|
|
88
|
-
*/
|
|
89
|
-
const ICON_MAP = {
|
|
90
|
-
'fa-3x3-grid': ['lx-icons/3x3-grid'],
|
|
91
|
-
'fa-align-center': ['text-align-center'],
|
|
92
|
-
'fa-align-justify': ['text-align-justified'],
|
|
93
|
-
'fa-align-left': ['text-align-left'],
|
|
94
|
-
'fa-align-right': ['text-align-right'],
|
|
95
|
-
'fa-align-slash': ['tnt/clear-all-mapping'],
|
|
96
|
-
'fa-angle-double-down': ['expand-group'],
|
|
97
|
-
'fa-angle-double-left': ['close-command-field'],
|
|
98
|
-
'fa-angle-double-right': ['open-command-field'],
|
|
99
|
-
'fa-angle-double-up': ['collapse-group'],
|
|
100
|
-
'fa-angle-down': ['slim-arrow-down'],
|
|
101
|
-
'fa-angle-left': ['slim-arrow-left'],
|
|
102
|
-
'fa-angle-right': ['slim-arrow-right'],
|
|
103
|
-
'fa-angle-up': ['slim-arrow-up'],
|
|
104
|
-
'fa-archive': ['sap-box'],
|
|
105
|
-
'fa-arrow-circle-right': ['initiative'],
|
|
106
|
-
'fa-arrow-circle-up': ['arrow-top'],
|
|
107
|
-
'fa-arrow-down': ['arrow-bottom'],
|
|
108
|
-
'fa-arrow-from-bottom': ['upload'],
|
|
109
|
-
'fa-arrow-left': ['arrow-left'],
|
|
110
|
-
'fa-arrow-right': ['arrow-right'],
|
|
111
|
-
'fa-arrow-to-bottom': ['download'],
|
|
112
|
-
'fa-arrow-to-top': ['back-to-top'],
|
|
113
|
-
'fa-arrow-up': ['arrow-top'],
|
|
114
|
-
'fa-arrows-h': ['resize-horizontal'],
|
|
115
|
-
'fa-at': ['arobase'],
|
|
116
|
-
'fa-atom': ['lx-icons/atom'],
|
|
117
|
-
'fa-badge-check': ['lx-icons/badge-sign'],
|
|
118
|
-
'fa-balance-scale-right': ['compare-2'],
|
|
119
|
-
'fa-ballot-check': ['activities'],
|
|
120
|
-
'fa-ban': ['cancel'],
|
|
121
|
-
'fa-bars': ['menu2'],
|
|
122
|
-
'fa-bell': ['bell'],
|
|
123
|
-
'fa-binoculars': ['sys-find'],
|
|
124
|
-
'fa-bold': ['bold-text'],
|
|
125
|
-
'fa-bolt': ['tnt/raise-fault'],
|
|
126
|
-
'fa-book': ['course-book'],
|
|
127
|
-
'fa-book-open': ['education'],
|
|
128
|
-
'fa-books': ['course-book'],
|
|
129
|
-
'fa-bug': ['lx-icons/bug'],
|
|
130
|
-
'fa-bullhorn': ['marketing-campaign'],
|
|
131
|
-
'fa-bullseye-arrow': ['lx-icons/bullseye-arrow'],
|
|
132
|
-
'fa-calendar': ['calendar'],
|
|
133
|
-
'fa-caret-down': ['megamenu'],
|
|
134
|
-
'fa-caret-left': ['navigation-left-arrow'],
|
|
135
|
-
'fa-caret-up': ['sorting-ranking'],
|
|
136
|
-
'fa-chart-bar': ['vertical-bar-chart'],
|
|
137
|
-
'fa-chart-pie-alt': ['pie-chart'],
|
|
138
|
-
'fa-check': ['accept'],
|
|
139
|
-
'fa-check-circle': ['status-completed'],
|
|
140
|
-
'fa-check-square': ['complete'],
|
|
141
|
-
'fa-chess-queen-alt': ['lx-icons/chess-queen'],
|
|
142
|
-
'fa-chevron-down': ['navigation-down-arrow'],
|
|
143
|
-
'fa-chevron-left': ['navigation-left-arrow'],
|
|
144
|
-
'fa-chevron-right': ['navigation-right-arrow'],
|
|
145
|
-
'fa-chevron-square-down': ['navigation-down-arrow'],
|
|
146
|
-
'fa-chevron-square-right': ['navigation-right-arrow'],
|
|
147
|
-
'fa-chevron-up': ['navigation-up-arrow'],
|
|
148
|
-
'fa-child': ['tnt/actor'],
|
|
149
|
-
'fa-circle': ['circle-task', 'circle-task-2'],
|
|
150
|
-
'fa-clipboard-list-check': ['order-status'],
|
|
151
|
-
'fa-clock': ['in-progress'],
|
|
152
|
-
'fa-clone': ['duplicate'],
|
|
153
|
-
'fa-cloud': ['cloud'],
|
|
154
|
-
'fa-code': ['source-code'],
|
|
155
|
-
'fa-code-branch': ['business-suite/empty-sequence'],
|
|
156
|
-
'fa-cog': ['action-settings'],
|
|
157
|
-
'fa-comment': ['comment'],
|
|
158
|
-
'fa-comment-alt': ['comment'],
|
|
159
|
-
'fa-comment-alt-check': ['lx-icons/comment-alt-check'],
|
|
160
|
-
'fa-comment-lines': ['comment'],
|
|
161
|
-
'fa-comments': ['discussion'],
|
|
162
|
-
'fa-comments-alt': ['discussion'],
|
|
163
|
-
'fa-compass': ['business-objects-explorer'],
|
|
164
|
-
'fa-compress': ['exit-full-screen'],
|
|
165
|
-
'fa-confluence': ['lx-icons/confluence'],
|
|
166
|
-
'fa-copy': ['copy'],
|
|
167
|
-
'fa-database': ['database'],
|
|
168
|
-
'fa-diamond': ['rhombus-milestone', 'rhombus-milestone-2'],
|
|
169
|
-
'fa-do-not-enter': ['sys-minus'],
|
|
170
|
-
'fa-dollar-sign': ['lx-icons/dollar-sign'],
|
|
171
|
-
'fa-download': ['download'],
|
|
172
|
-
'fa-edit': ['edit'],
|
|
173
|
-
'fa-ellipsis-h': ['overflow'],
|
|
174
|
-
'fa-ellipsis-v': ['overflow'],
|
|
175
|
-
'fa-envelope': ['email'],
|
|
176
|
-
'fa-euro-sign': ['lx-icons/euro-sign'],
|
|
177
|
-
'fa-exchange': ['lx-icons/exchange'],
|
|
178
|
-
'fa-exclamation': ['business-suite/priority-1'],
|
|
179
|
-
'fa-exclamation-circle': ['lx-icons/exclamation-circle'],
|
|
180
|
-
'fa-exclamation-square': ['high-priority'],
|
|
181
|
-
'fa-exclamation-triangle': ['warning'],
|
|
182
|
-
'fa-expand': ['full-screen'],
|
|
183
|
-
'fa-expand-alt': ['full-screen'],
|
|
184
|
-
'fa-expand-wide': ['full-screen'],
|
|
185
|
-
'fa-external-link': ['action'],
|
|
186
|
-
'fa-external-link-alt': ['action'],
|
|
187
|
-
'fa-eye': ['show'],
|
|
188
|
-
'fa-eye-dropper': ['business-suite/pipette'],
|
|
189
|
-
'fa-eye-slash': ['hide'],
|
|
190
|
-
'fa-feather': ['lx-icons/feather'],
|
|
191
|
-
'fa-file': ['document'],
|
|
192
|
-
'fa-file-alt': ['document'],
|
|
193
|
-
'fa-file-audio': ['attachment-audio'],
|
|
194
|
-
'fa-file-certificate': ['verified'],
|
|
195
|
-
'fa-file-download': ['download'],
|
|
196
|
-
'fa-file-excel': ['excel-attachment'],
|
|
197
|
-
'fa-file-image': ['attachment-photo'],
|
|
198
|
-
'fa-file-pdf': ['pdf-attachment'],
|
|
199
|
-
'fa-file-plus': ['add-document'],
|
|
200
|
-
'fa-file-video': ['attachment-video'],
|
|
201
|
-
'fa-file-word': ['doc-attachment'],
|
|
202
|
-
'fa-filter': ['filter'],
|
|
203
|
-
'fa-fire': ['business-suite/fire'],
|
|
204
|
-
'fa-fire-alt': ['business-suite/fire'],
|
|
205
|
-
'fa-folder': ['folder-blank'],
|
|
206
|
-
'fa-folder-open': ['open-folder'],
|
|
207
|
-
'fa-folder-tree': ['lx-icons/folder-tree'],
|
|
208
|
-
'fa-gavel': ['lx-icons/gavel'],
|
|
209
|
-
'fa-globe': ['world'],
|
|
210
|
-
'fa-graduation-cap': ['study-leave'],
|
|
211
|
-
'fa-grip-lines': ['media-pause'],
|
|
212
|
-
'fa-hammer': ['lx-icons/hammer'],
|
|
213
|
-
'fa-handshake': ['decision'],
|
|
214
|
-
'fa-hat-wizard': ['lx-icons/hat-wizard'],
|
|
215
|
-
'fa-heading': ['heading1'],
|
|
216
|
-
'fa-headset': ['headset'],
|
|
217
|
-
'fa-history': ['history'],
|
|
218
|
-
'fa-home': ['home'],
|
|
219
|
-
'fa-hourglass-end': ['lx-icons/hourglass-end'],
|
|
220
|
-
'fa-hourglass-half': ['lateness'],
|
|
221
|
-
'fa-house': ['home'],
|
|
222
|
-
'fa-image': ['picture'],
|
|
223
|
-
'fa-info': ['message-information'],
|
|
224
|
-
'fa-info-circle': ['message-information', 'information'],
|
|
225
|
-
'fa-info-square': ['message-information', 'information'],
|
|
226
|
-
'fa-italic': ['italic-text'],
|
|
227
|
-
'fa-key': ['key'],
|
|
228
|
-
'fa-keyboard': ['keyboard-and-mouse'],
|
|
229
|
-
'fa-jira': ['rhombus-milestone'],
|
|
230
|
-
'fa-lemon': ['lx-icons/lemon'],
|
|
231
|
-
'fa-lightbulb': ['lightbulb'],
|
|
232
|
-
'fa-lightbulb-on': ['lx-icons/lightbulb-check'],
|
|
233
|
-
'fa-link': ['chain-link'],
|
|
234
|
-
'fa-list': ['list'],
|
|
235
|
-
'fa-list-ol': ['business-suite/icon-bulleting-with-numbers'],
|
|
236
|
-
'fa-list-ul': ['list'],
|
|
237
|
-
'fa-lock': ['locked'],
|
|
238
|
-
'fa-lock-alt': ['locked'],
|
|
239
|
-
'fa-lock-open': ['unlocked'],
|
|
240
|
-
'fa-long-arrow-left': ['arrow-left'],
|
|
241
|
-
'fa-long-arrow-right': ['arrow-right'],
|
|
242
|
-
'fa-map': ['map-3'],
|
|
243
|
-
'fa-map-pin': ['lx-icons/map-pin'],
|
|
244
|
-
'fa-map-signs': ['lx-icons/map-signs'],
|
|
245
|
-
'fa-minus': ['less'],
|
|
246
|
-
'fa-minus-circle': ['sys-minus'],
|
|
247
|
-
'fa-minus-square': ['negative'],
|
|
248
|
-
'fa-paragraph': ['text'],
|
|
249
|
-
'fa-pause': ['media-pause'],
|
|
250
|
-
'fa-pen': ['edit'],
|
|
251
|
-
'fa-pencil': ['edit'],
|
|
252
|
-
'fa-people-arrows': ['citizen-connect'],
|
|
253
|
-
'fa-phone-alt': ['call'],
|
|
254
|
-
'fa-play': ['media-play'],
|
|
255
|
-
'fa-play-circle': ['play'],
|
|
256
|
-
'fa-plug': ['disconnected'],
|
|
257
|
-
'fa-plus': ['add'],
|
|
258
|
-
'fa-plus-circle': ['sys-add'],
|
|
259
|
-
'fa-pound-sign': ['lx-icons/pound-sign'],
|
|
260
|
-
'fa-power-off': ['log'],
|
|
261
|
-
'fa-presentation': ['projector'],
|
|
262
|
-
'fa-print': ['print'],
|
|
263
|
-
'fa-project-diagram': ['lx-icons/project-diagram'],
|
|
264
|
-
'fa-question': ['incident'],
|
|
265
|
-
'fa-question-circle': ['question-mark'],
|
|
266
|
-
'fa-question-square': ['question-mark'],
|
|
267
|
-
'fa-quote-right': ['lx-icons/quote-right'],
|
|
268
|
-
'fa-radar': ['business-suite/radius'],
|
|
269
|
-
'fa-random': ['tnt/flow'],
|
|
270
|
-
'fa-rectangle-landscape': ['iphone-2'],
|
|
271
|
-
'fa-rectangle-portrait': ['iphone'],
|
|
272
|
-
'fa-rectangle-wide': ['legend'],
|
|
273
|
-
'fa-redo': ['refresh'],
|
|
274
|
-
'fa-repeat': ['synchronize'],
|
|
275
|
-
'fa-road': ['lx-icons/road'],
|
|
276
|
-
'fa-robot': ['lx-icons/robot'],
|
|
277
|
-
'fa-rocket': ['lx-icons/rocket'],
|
|
278
|
-
'fa-save': ['save'],
|
|
279
|
-
'fa-search': ['search'],
|
|
280
|
-
'fa-seedling': ['e-care'],
|
|
281
|
-
'fa-shapes': ['program-triangles'],
|
|
282
|
-
'fa-share-alt': ['share-2'],
|
|
283
|
-
'fa-share-square': ['action'],
|
|
284
|
-
'fa-shield': ['lx-icons/shield'],
|
|
285
|
-
'fa-shield-alt': ['lx-icons/shield'],
|
|
286
|
-
'fa-shield-check': ['checklist-item'],
|
|
287
|
-
'fa-shopping-cart': ['cart'],
|
|
288
|
-
'fa-signal': ['lx-icons/signal'],
|
|
289
|
-
'fa-sitemap': ['tree'],
|
|
290
|
-
'fa-sort': ['sorting-ranking'],
|
|
291
|
-
'fa-sort-alt': ['sort'],
|
|
292
|
-
'fa-sort-down': ['megamenu'],
|
|
293
|
-
'fa-sort-up': ['sorting-ranking'],
|
|
294
|
-
'fa-sparkles': ['ai'],
|
|
295
|
-
'fa-spinner': ['pending'],
|
|
296
|
-
'fa-square': ['border'],
|
|
297
|
-
'fa-star': ['unfavorite', 'favorite'],
|
|
298
|
-
'fa-sticky-note': ['notes'],
|
|
299
|
-
'fa-strikethrough': ['strikethrough'],
|
|
300
|
-
'fa-sync': ['synchronize'],
|
|
301
|
-
'fa-sync-alt': ['synchronize'],
|
|
302
|
-
'fa-table': ['business-suite/2x2-grid-layout'],
|
|
303
|
-
'fa-tachometer': ['performance'],
|
|
304
|
-
'fa-tachometer-alt-average': ['performance'],
|
|
305
|
-
'fa-tags': ['blank-tag-2'],
|
|
306
|
-
'fa-tasks': ['activities'],
|
|
307
|
-
'fa-tasks-alt': ['lx-icons/tasks'],
|
|
308
|
-
'fa-text': ['text'],
|
|
309
|
-
'fa-th': ['business-suite/2x2-grid-layout'],
|
|
310
|
-
'fa-th-large': ['business-suite/2x2-grid-layout'],
|
|
311
|
-
'fa-thumbs-down': ['thumb-down'],
|
|
312
|
-
'fa-thumbs-up': ['thumb-up'],
|
|
313
|
-
'fa-times': ['decline'],
|
|
314
|
-
'fa-times-circle': ['error'],
|
|
315
|
-
'fa-toolbox': ['lx-icons/toolbox'],
|
|
316
|
-
'fa-tools': ['wrench'],
|
|
317
|
-
'fa-trash': ['delete'],
|
|
318
|
-
'fa-trash-restore': ['history'],
|
|
319
|
-
'fa-trophy': ['competitor'],
|
|
320
|
-
'fa-tshirt': ['lx-icons/tshirt'],
|
|
321
|
-
'fa-umbrella-beach': ['umbrella'],
|
|
322
|
-
'fa-underline': ['underline-text'],
|
|
323
|
-
'fa-undo': ['undo'],
|
|
324
|
-
'fa-unicorn': ['lx-icons/unicorn'],
|
|
325
|
-
'fa-unlink': ['broken-link'],
|
|
326
|
-
'fa-upload': ['upload'],
|
|
327
|
-
'fa-user': ['person-placeholder'],
|
|
328
|
-
'fa-user-friends': ['group'],
|
|
329
|
-
'fa-user-hard-hat': ['lx-icons/user-hard-hat'],
|
|
330
|
-
'fa-user-headset': ['headset'],
|
|
331
|
-
'fa-user-robot': ['lx-icons/robot'],
|
|
332
|
-
'fa-users': ['family-care'],
|
|
333
|
-
'fa-window': ['lx-icons/window'], // ['tnt/subject'],
|
|
334
|
-
'fa-wrench': ['wrench'],
|
|
335
|
-
'fa-yen-sign': ['lx-icons/yen-sign']
|
|
336
|
-
};
|
|
337
|
-
/**
|
|
338
|
-
* Retrieves the SAP icon for a given Font Awesome icon name.
|
|
339
|
-
* @param faIcon Font Awesome icon name (e.g., 'fa-check')
|
|
340
|
-
* @param solid If true, returns solid variant when available
|
|
341
|
-
* @returns SAP icon name or undefined if not mapped
|
|
342
|
-
*/
|
|
343
|
-
function getSapIcon(faIcon, solid = false) {
|
|
344
|
-
const icons = ICON_MAP[faIcon];
|
|
345
|
-
if (!icons) {
|
|
346
|
-
return undefined;
|
|
347
|
-
}
|
|
348
|
-
return solid && icons[1] ? icons[1] : icons[0];
|
|
349
|
-
}
|
|
350
84
|
|
|
351
85
|
/**
|
|
352
86
|
* Badge component is used to show a small piece of information in a colored badge.
|
|
@@ -875,221 +609,488 @@ class ResizeObserverService {
|
|
|
875
609
|
target: element
|
|
876
610
|
};
|
|
877
611
|
}
|
|
878
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: ResizeObserverService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
879
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: ResizeObserverService, providedIn: 'root' }); }
|
|
612
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: ResizeObserverService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
613
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: ResizeObserverService, providedIn: 'root' }); }
|
|
614
|
+
}
|
|
615
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: ResizeObserverService, decorators: [{
|
|
616
|
+
type: Injectable,
|
|
617
|
+
args: [{ providedIn: 'root' }]
|
|
618
|
+
}] });
|
|
619
|
+
|
|
620
|
+
const LX_ELLIPSIS_DEBOUNCE_ON_RESIZE = new InjectionToken('LX_ELLIPSIS_DEBOUNCE_ON_RESIZE', {
|
|
621
|
+
providedIn: 'root',
|
|
622
|
+
factory: () => EllipsisComponent.DEFAULT_RESIZE_DEBOUNCE_MS
|
|
623
|
+
});
|
|
624
|
+
/**
|
|
625
|
+
* You can set `max-width` CSS property on your `lx-ellipsis` host element or the parent element if you want its content to never exceed a specific width.
|
|
626
|
+
*/
|
|
627
|
+
class EllipsisComponent {
|
|
628
|
+
/** @internal */
|
|
629
|
+
static { this.DEFAULT_RESIZE_DEBOUNCE_MS = 500; }
|
|
630
|
+
constructor(debounceMsAfterResize, cdRef, hostEl, resizeObserverService, translateService) {
|
|
631
|
+
this.debounceMsAfterResize = debounceMsAfterResize;
|
|
632
|
+
this.cdRef = cdRef;
|
|
633
|
+
this.hostEl = hostEl;
|
|
634
|
+
this.resizeObserverService = resizeObserverService;
|
|
635
|
+
this.translateService = translateService;
|
|
636
|
+
this.content = '';
|
|
637
|
+
/**
|
|
638
|
+
* Only set this to false if the content is not a user provided string
|
|
639
|
+
* or if you sanitize the provided content yourself.
|
|
640
|
+
*/
|
|
641
|
+
this.escapeHtmlInContent = true;
|
|
642
|
+
/** @internal */
|
|
643
|
+
this.isShowingMore$ = new BehaviorSubject(false);
|
|
644
|
+
this.destroyed$ = new Subject();
|
|
645
|
+
this.viewChecked$ = new Subject();
|
|
646
|
+
}
|
|
647
|
+
ngOnInit() {
|
|
648
|
+
this.sanitizedContent$ = this.content$.pipe(map((content) => {
|
|
649
|
+
if (this.escapeHtmlInContent && typeof content === 'string') {
|
|
650
|
+
return escape(content);
|
|
651
|
+
}
|
|
652
|
+
return content;
|
|
653
|
+
}));
|
|
654
|
+
this.showMoreButtonLabel$ = this.isShowingMore$.pipe(switchMap((isShowingMore) => {
|
|
655
|
+
const translationKey = isShowingMore ? 'common.showLess' : 'common.showMore';
|
|
656
|
+
return this.translateService.get(translationKey);
|
|
657
|
+
}));
|
|
658
|
+
const newWidthOnResize$ = new Subject();
|
|
659
|
+
const newHeightOnResize$ = new Subject();
|
|
660
|
+
this.resizeObserverService.observe(this.hostEl.nativeElement, (resizedElement) => {
|
|
661
|
+
newWidthOnResize$.next(resizedElement.contentRect.width);
|
|
662
|
+
newHeightOnResize$.next(resizedElement.contentRect.height);
|
|
663
|
+
});
|
|
664
|
+
const containerWidthChangedSignificantlyAfterResize$ = newWidthOnResize$.pipe(startWith(0), pairwise(), filter(([previousWidth, newWidth]) => Math.abs(newWidth - previousWidth) > 1), map(([, newWidth]) => newWidth));
|
|
665
|
+
const userTriggeredTriggeredShowLess$ = this.isShowingMore$.pipe(filter((isShowingMore) => !isShowingMore));
|
|
666
|
+
const reevaluateIfContentIsOverflowing$ = combineLatest([
|
|
667
|
+
this.contentSpanEl$,
|
|
668
|
+
userTriggeredTriggeredShowLess$,
|
|
669
|
+
containerWidthChangedSignificantlyAfterResize$
|
|
670
|
+
]);
|
|
671
|
+
const isContentOverflowing$ = merge(concat(reevaluateIfContentIsOverflowing$.pipe(take(1)), // debounce all but the first output
|
|
672
|
+
reevaluateIfContentIsOverflowing$.pipe(debounceTime(this.debounceMsAfterResize))), this.content$.pipe(skip(1), switchMap(() => this.viewChecked$))).pipe(withLatestFrom(this.contentSpanEl$), map(([, contentSpanRef]) => this.isContentOverflowing(contentSpanRef)));
|
|
673
|
+
const userTriggeredTriggeredShowMore$ = this.isShowingMore$.pipe(filter((isShowingMore) => isShowingMore));
|
|
674
|
+
const buttonHeight$ = this.showMoreButtonEl$.pipe(filter((showMoreButtonEl) => !!showMoreButtonEl), map((showMoreButtonEl) => showMoreButtonEl.nativeElement.offsetHeight), distinctUntilChanged());
|
|
675
|
+
const userIncreasedBrowserWindowSizeToThePointOfNoTruncationNecessary$ = combineLatest([
|
|
676
|
+
buttonHeight$,
|
|
677
|
+
newHeightOnResize$.pipe(distinctUntilChanged())
|
|
678
|
+
]).pipe(withLatestFrom(this.isShowingMore$), filter(([, isShowingMore]) => isShowingMore), map(([[buttonHeight, newHeight]]) => {
|
|
679
|
+
const heightOfOneLine = buttonHeight;
|
|
680
|
+
const showLessButtonMarginTop = 4;
|
|
681
|
+
const heightOfSpanInShowMoreMode = newHeight - buttonHeight - showLessButtonMarginTop;
|
|
682
|
+
const thresholdToDetectContentInSingleLine = 4;
|
|
683
|
+
const differenceBetweenContentSpanAndButtonHeight = Math.abs(heightOfOneLine - heightOfSpanInShowMoreMode);
|
|
684
|
+
const isSpanContentDisplayedInOneLineAgain = differenceBetweenContentSpanAndButtonHeight < thresholdToDetectContentInSingleLine;
|
|
685
|
+
return isSpanContentDisplayedInOneLineAgain;
|
|
686
|
+
}));
|
|
687
|
+
const contentFitsInOneLineAgainWhileShowMoreIsEnabled$ = userIncreasedBrowserWindowSizeToThePointOfNoTruncationNecessary$.pipe(startWith(false), pairwise(), filter(([previousTextIsNowInOneLineAgain]) => !previousTextIsNowInOneLineAgain), map(([, textIsNowInOneLineAgain]) => !textIsNowInOneLineAgain));
|
|
688
|
+
const contentIsOverflowingAndShowMoreIsNotEnabled$ = isContentOverflowing$.pipe(withLatestFrom(this.isShowingMore$), filter(([, isShowingMore]) => !isShowingMore), map(([isContentLongerThanContainerWidth]) => {
|
|
689
|
+
return isContentLongerThanContainerWidth;
|
|
690
|
+
}));
|
|
691
|
+
this.showButton$ = merge(userTriggeredTriggeredShowMore$, contentFitsInOneLineAgainWhileShowMoreIsEnabled$, contentIsOverflowingAndShowMoreIsNotEnabled$);
|
|
692
|
+
// As long as no parent component is listening on resize events,
|
|
693
|
+
// the ChangeDetectorRef.markForCheck() call done by the async pipe
|
|
694
|
+
// will not result in a change detection cycle in this component when its size changes.
|
|
695
|
+
// This is the least amount of ChangeDetectorRef.detectChanges() calls
|
|
696
|
+
// I was able to come up with. The Angular profiler shows acceptable numbers of change detection.
|
|
697
|
+
this.detectChangesWhenObservableEmits(isContentOverflowing$);
|
|
698
|
+
this.detectChangesWhenObservableEmits(this.showButton$);
|
|
699
|
+
this.detectChangesWhenObservableEmits(this.content$);
|
|
700
|
+
this.detectChangesWhenObservableEmits(contentIsOverflowingAndShowMoreIsNotEnabled$);
|
|
701
|
+
this.detectChangesWhenObservableEmits(isContentOverflowing$);
|
|
702
|
+
}
|
|
703
|
+
ngAfterViewChecked() {
|
|
704
|
+
this.viewChecked$.next();
|
|
705
|
+
}
|
|
706
|
+
/** @internal */
|
|
707
|
+
onShowMoreToggle() {
|
|
708
|
+
this.isShowingMore$.next(!this.isShowingMore$.getValue());
|
|
709
|
+
this.cdRef.detectChanges();
|
|
710
|
+
}
|
|
711
|
+
ngOnDestroy() {
|
|
712
|
+
this.resizeObserverService.unobserve(this.hostEl.nativeElement);
|
|
713
|
+
}
|
|
714
|
+
detectChangesWhenObservableEmits(observable$) {
|
|
715
|
+
observable$.pipe(takeUntil(this.destroyed$)).subscribe(() => this.cdRef.detectChanges());
|
|
716
|
+
}
|
|
717
|
+
isContentOverflowing(contentSpanElRef) {
|
|
718
|
+
const scrollWidth = contentSpanElRef.nativeElement.scrollWidth;
|
|
719
|
+
const offsetWidth = contentSpanElRef.nativeElement.clientWidth;
|
|
720
|
+
return offsetWidth < scrollWidth;
|
|
721
|
+
}
|
|
722
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EllipsisComponent, deps: [{ token: LX_ELLIPSIS_DEBOUNCE_ON_RESIZE }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: ResizeObserverService }, { token: i1.TranslateService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
723
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: EllipsisComponent, isStandalone: true, selector: "lx-ellipsis", inputs: { content: "content", escapeHtmlInContent: "escapeHtmlInContent" }, viewQueries: [{ propertyName: "contentSpanEl", first: true, predicate: ["contentEl"], descendants: true }, { propertyName: "showMoreButtonEl", first: true, predicate: ["showMoreButton"], descendants: true, read: ElementRef }], ngImport: i0, template: "<span\n #contentEl\n [class.showMore]=\"isShowingMore$ | async\"\n class=\"content truncate lx-margin-right\"\n [innerHtml]=\"sanitizedContent$ | async\"\n></span>\n@if (showButton$ | async) {\n <button (click)=\"onShowMoreToggle()\" lx-button #showMoreButton size=\"auto\" mode=\"link\" color=\"primary\">\n {{ showMoreButtonLabel$ | async }}\n </button>\n}\n", styles: [":host{display:block;white-space:pre-line;overflow-wrap:break-word}.content{display:inline-block;word-break:break-word}.truncate:not(.showMore){width:calc(100% - 140px);white-space:nowrap;overflow-wrap:normal;overflow:hidden;text-overflow:ellipsis}.content.showMore+button{margin-top:4px;display:block}button{white-space:nowrap;vertical-align:top}\n"], dependencies: [{ kind: "component", type: ButtonComponent, selector: "button[lx-button]", inputs: ["size", "color", "mode", "pressed", "selected", "square", "circle", "disabled", "icon", "endIcon", "showSpinner"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
724
|
+
}
|
|
725
|
+
__decorate([
|
|
726
|
+
Observe('contentSpanEl')
|
|
727
|
+
], EllipsisComponent.prototype, "contentSpanEl$", void 0);
|
|
728
|
+
__decorate([
|
|
729
|
+
Observe('showMoreButtonEl')
|
|
730
|
+
], EllipsisComponent.prototype, "showMoreButtonEl$", void 0);
|
|
731
|
+
__decorate([
|
|
732
|
+
Observe('content')
|
|
733
|
+
], EllipsisComponent.prototype, "content$", void 0);
|
|
734
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EllipsisComponent, decorators: [{
|
|
735
|
+
type: Component,
|
|
736
|
+
args: [{ selector: 'lx-ellipsis', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ButtonComponent, AsyncPipe], template: "<span\n #contentEl\n [class.showMore]=\"isShowingMore$ | async\"\n class=\"content truncate lx-margin-right\"\n [innerHtml]=\"sanitizedContent$ | async\"\n></span>\n@if (showButton$ | async) {\n <button (click)=\"onShowMoreToggle()\" lx-button #showMoreButton size=\"auto\" mode=\"link\" color=\"primary\">\n {{ showMoreButtonLabel$ | async }}\n </button>\n}\n", styles: [":host{display:block;white-space:pre-line;overflow-wrap:break-word}.content{display:inline-block;word-break:break-word}.truncate:not(.showMore){width:calc(100% - 140px);white-space:nowrap;overflow-wrap:normal;overflow:hidden;text-overflow:ellipsis}.content.showMore+button{margin-top:4px;display:block}button{white-space:nowrap;vertical-align:top}\n"] }]
|
|
737
|
+
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
738
|
+
type: Inject,
|
|
739
|
+
args: [LX_ELLIPSIS_DEBOUNCE_ON_RESIZE]
|
|
740
|
+
}] }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: ResizeObserverService }, { type: i1.TranslateService }], propDecorators: { content: [{
|
|
741
|
+
type: Input
|
|
742
|
+
}], escapeHtmlInContent: [{
|
|
743
|
+
type: Input
|
|
744
|
+
}], contentSpanEl$: [], contentSpanEl: [{
|
|
745
|
+
type: ViewChild,
|
|
746
|
+
args: ['contentEl']
|
|
747
|
+
}], showMoreButtonEl$: [], showMoreButtonEl: [{
|
|
748
|
+
type: ViewChild,
|
|
749
|
+
args: ['showMoreButton', { read: ElementRef }]
|
|
750
|
+
}], content$: [] } });
|
|
751
|
+
|
|
752
|
+
class EmptyStateComponent {
|
|
753
|
+
constructor() {
|
|
754
|
+
/**
|
|
755
|
+
* The title to be displayed
|
|
756
|
+
*/
|
|
757
|
+
this.title = input.required();
|
|
758
|
+
/**
|
|
759
|
+
* The SAP icon to show in the empty state.
|
|
760
|
+
*/
|
|
761
|
+
this.icon = input();
|
|
762
|
+
/**
|
|
763
|
+
* The main call-to-action button label
|
|
764
|
+
*/
|
|
765
|
+
this.buttonLabel = input();
|
|
766
|
+
/**
|
|
767
|
+
* The secondary call-to-action button label
|
|
768
|
+
*/
|
|
769
|
+
this.secondaryButtonLabel = input();
|
|
770
|
+
/**
|
|
771
|
+
* Whether the empty state is in a loading state. If true, main call-to-action button will show a spinner
|
|
772
|
+
*/
|
|
773
|
+
this.loading = input(false);
|
|
774
|
+
/**
|
|
775
|
+
* The more link label
|
|
776
|
+
*/
|
|
777
|
+
this.moreLinkLabel = input();
|
|
778
|
+
/**
|
|
779
|
+
* The URL of the more link
|
|
780
|
+
*/
|
|
781
|
+
this.moreLink = input();
|
|
782
|
+
/**
|
|
783
|
+
* Whether the more link should be opened in a new tab
|
|
784
|
+
*
|
|
785
|
+
* @default true
|
|
786
|
+
*/
|
|
787
|
+
this.openMoreLinkInNewTab = input(true);
|
|
788
|
+
/**
|
|
789
|
+
* The size of the empty state
|
|
790
|
+
*
|
|
791
|
+
* @default medium
|
|
792
|
+
*/
|
|
793
|
+
this.size = input('medium');
|
|
794
|
+
this.useRouterLink = computed(() => Array.isArray(this.moreLink()));
|
|
795
|
+
/**
|
|
796
|
+
* Emitted when the main call-to-action button is clicked
|
|
797
|
+
*/
|
|
798
|
+
this.buttonClicked = new EventEmitter();
|
|
799
|
+
/**
|
|
800
|
+
* Emitted when the secondary call-to-action button is clicked
|
|
801
|
+
*/
|
|
802
|
+
this.secondaryButtonClicked = new EventEmitter();
|
|
803
|
+
/**
|
|
804
|
+
* Emitted when the more link is clicked
|
|
805
|
+
*/
|
|
806
|
+
this.moreLinkClicked = new EventEmitter();
|
|
807
|
+
}
|
|
808
|
+
get _size() {
|
|
809
|
+
return this.size();
|
|
810
|
+
}
|
|
811
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EmptyStateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
812
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: EmptyStateComponent, isStandalone: true, selector: "lx-empty-state", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, buttonLabel: { classPropertyName: "buttonLabel", publicName: "buttonLabel", isSignal: true, isRequired: false, transformFunction: null }, secondaryButtonLabel: { classPropertyName: "secondaryButtonLabel", publicName: "secondaryButtonLabel", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, moreLinkLabel: { classPropertyName: "moreLinkLabel", publicName: "moreLinkLabel", isSignal: true, isRequired: false, transformFunction: null }, moreLink: { classPropertyName: "moreLink", publicName: "moreLink", isSignal: true, isRequired: false, transformFunction: null }, openMoreLinkInNewTab: { classPropertyName: "openMoreLinkInNewTab", publicName: "openMoreLinkInNewTab", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { buttonClicked: "buttonClicked", secondaryButtonClicked: "secondaryButtonClicked", moreLinkClicked: "moreLinkClicked" }, host: { properties: { "attr.size": "this._size" } }, ngImport: i0, template: "<div class=\"tw-max-w-[434px] tw-text-center\">\n @if (icon(); as icon) {\n <ui5-icon [name]=\"icon\" design=\"Information\" />\n }\n\n <h3 class=\"empty-state-title tw-mb-m tw-mt-xl tw-text-black\" [innerHTML]=\"title()\"></h3>\n\n <div class=\"empty-state-content tw-leading-[16px] tw-text-gray-50\">\n <ng-content />\n </div>\n\n <div class=\"tw-flex tw-justify-center tw-gap-m\">\n @if (secondaryButtonLabel()) {\n <div class=\"secondaryButton tw-my-xl\">\n <button lx-button size=\"large\" [showSpinner]=\"loading()\" (click)=\"secondaryButtonClicked.emit($event)\">\n {{ secondaryButtonLabel() }}\n </button>\n </div>\n }\n\n @if (buttonLabel()) {\n <div class=\"actionButton tw-my-xl\">\n <button lx-button size=\"large\" color=\"primary\" [showSpinner]=\"loading()\" (click)=\"buttonClicked.emit($event)\">\n {{ buttonLabel() }}\n </button>\n </div>\n }\n </div>\n\n @if (moreLinkLabel() && moreLink()) {\n <div>\n @if (useRouterLink()) {\n <a\n rel=\"noopener noreferrer\"\n class=\"tw-text-size-md tw-text-primary\"\n [routerLink]=\"moreLink()\"\n (click)=\"moreLinkClicked.emit($event)\"\n [target]=\"openMoreLinkInNewTab() ? '_blank' : '_self'\"\n >{{ moreLinkLabel() }}</a\n >\n } @else {\n <a\n rel=\"noopener noreferrer\"\n class=\"tw-text-size-md tw-text-primary\"\n [href]=\"moreLink()\"\n (click)=\"moreLinkClicked.emit($event)\"\n [target]=\"openMoreLinkInNewTab() ? '_blank' : '_self'\"\n >{{ moreLinkLabel() }}</a\n >\n }\n </div>\n }\n</div>\n", styles: [":host{display:flex;justify-content:center}:host[size=small] .empty-state-title{font-size:var(--lxFontSize, 14px)}:host[size=small] .empty-state-content{font-size:var(--lxFontSmallSize, 12px)}:host[size=medium] .empty-state-title{font-size:var(--lxFontHeader2Size, 24px)}:host[size=medium] .empty-state-content{font-size:var(--lxFontSize, 14px)}ui5-icon{position:relative;width:2rem;height:2rem}ui5-icon:after{content:\"\";position:absolute;bottom:-8px;left:50%;transform:translate(-50%);height:6px;width:44px;background-color:#f0f2f5;border-radius:100%}\n"], dependencies: [{ kind: "component", type: ButtonComponent, selector: "button[lx-button]", inputs: ["size", "color", "mode", "pressed", "selected", "square", "circle", "disabled", "icon", "endIcon", "showSpinner"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: IconComponent$1, selector: "ui5-icon", inputs: ["design", "name", "accessibleName", "showTooltip", "mode"], outputs: ["ui5Click"], exportAs: ["ui5Icon"] }] }); }
|
|
880
813
|
}
|
|
881
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type:
|
|
882
|
-
type:
|
|
883
|
-
args: [{
|
|
884
|
-
}]
|
|
814
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EmptyStateComponent, decorators: [{
|
|
815
|
+
type: Component,
|
|
816
|
+
args: [{ selector: 'lx-empty-state', imports: [ButtonComponent, RouterLink, IconComponent$1], template: "<div class=\"tw-max-w-[434px] tw-text-center\">\n @if (icon(); as icon) {\n <ui5-icon [name]=\"icon\" design=\"Information\" />\n }\n\n <h3 class=\"empty-state-title tw-mb-m tw-mt-xl tw-text-black\" [innerHTML]=\"title()\"></h3>\n\n <div class=\"empty-state-content tw-leading-[16px] tw-text-gray-50\">\n <ng-content />\n </div>\n\n <div class=\"tw-flex tw-justify-center tw-gap-m\">\n @if (secondaryButtonLabel()) {\n <div class=\"secondaryButton tw-my-xl\">\n <button lx-button size=\"large\" [showSpinner]=\"loading()\" (click)=\"secondaryButtonClicked.emit($event)\">\n {{ secondaryButtonLabel() }}\n </button>\n </div>\n }\n\n @if (buttonLabel()) {\n <div class=\"actionButton tw-my-xl\">\n <button lx-button size=\"large\" color=\"primary\" [showSpinner]=\"loading()\" (click)=\"buttonClicked.emit($event)\">\n {{ buttonLabel() }}\n </button>\n </div>\n }\n </div>\n\n @if (moreLinkLabel() && moreLink()) {\n <div>\n @if (useRouterLink()) {\n <a\n rel=\"noopener noreferrer\"\n class=\"tw-text-size-md tw-text-primary\"\n [routerLink]=\"moreLink()\"\n (click)=\"moreLinkClicked.emit($event)\"\n [target]=\"openMoreLinkInNewTab() ? '_blank' : '_self'\"\n >{{ moreLinkLabel() }}</a\n >\n } @else {\n <a\n rel=\"noopener noreferrer\"\n class=\"tw-text-size-md tw-text-primary\"\n [href]=\"moreLink()\"\n (click)=\"moreLinkClicked.emit($event)\"\n [target]=\"openMoreLinkInNewTab() ? '_blank' : '_self'\"\n >{{ moreLinkLabel() }}</a\n >\n }\n </div>\n }\n</div>\n", styles: [":host{display:flex;justify-content:center}:host[size=small] .empty-state-title{font-size:var(--lxFontSize, 14px)}:host[size=small] .empty-state-content{font-size:var(--lxFontSmallSize, 12px)}:host[size=medium] .empty-state-title{font-size:var(--lxFontHeader2Size, 24px)}:host[size=medium] .empty-state-content{font-size:var(--lxFontSize, 14px)}ui5-icon{position:relative;width:2rem;height:2rem}ui5-icon:after{content:\"\";position:absolute;bottom:-8px;left:50%;transform:translate(-50%);height:6px;width:44px;background-color:#f0f2f5;border-radius:100%}\n"] }]
|
|
817
|
+
}], propDecorators: { _size: [{
|
|
818
|
+
type: HostBinding,
|
|
819
|
+
args: ['attr.size']
|
|
820
|
+
}], buttonClicked: [{
|
|
821
|
+
type: Output
|
|
822
|
+
}], secondaryButtonClicked: [{
|
|
823
|
+
type: Output
|
|
824
|
+
}], moreLinkClicked: [{
|
|
825
|
+
type: Output
|
|
826
|
+
}] } });
|
|
885
827
|
|
|
886
|
-
const LX_ELLIPSIS_DEBOUNCE_ON_RESIZE = new InjectionToken('LX_ELLIPSIS_DEBOUNCE_ON_RESIZE', {
|
|
887
|
-
providedIn: 'root',
|
|
888
|
-
factory: () => EllipsisComponent.DEFAULT_RESIZE_DEBOUNCE_MS
|
|
889
|
-
});
|
|
890
828
|
/**
|
|
891
|
-
*
|
|
829
|
+
* map Font Awesome -> SAP icons
|
|
830
|
+
* [0]: regular icon
|
|
831
|
+
* [1]: solid icon alternative (if available)
|
|
832
|
+
*/
|
|
833
|
+
const ICON_MAP = {
|
|
834
|
+
'fa-3x3-grid': ['lx-icons/3x3-grid'],
|
|
835
|
+
'fa-align-center': ['text-align-center'],
|
|
836
|
+
'fa-align-justify': ['text-align-justified'],
|
|
837
|
+
'fa-align-left': ['text-align-left'],
|
|
838
|
+
'fa-align-right': ['text-align-right'],
|
|
839
|
+
'fa-align-slash': ['tnt/clear-all-mapping'],
|
|
840
|
+
'fa-angle-double-down': ['expand-group'],
|
|
841
|
+
'fa-angle-double-left': ['close-command-field'],
|
|
842
|
+
'fa-angle-double-right': ['open-command-field'],
|
|
843
|
+
'fa-angle-double-up': ['collapse-group'],
|
|
844
|
+
'fa-angle-down': ['slim-arrow-down'],
|
|
845
|
+
'fa-angle-left': ['slim-arrow-left'],
|
|
846
|
+
'fa-angle-right': ['slim-arrow-right'],
|
|
847
|
+
'fa-angle-up': ['slim-arrow-up'],
|
|
848
|
+
'fa-archive': ['sap-box'],
|
|
849
|
+
'fa-arrow-circle-right': ['initiative'],
|
|
850
|
+
'fa-arrow-circle-up': ['arrow-top'],
|
|
851
|
+
'fa-arrow-down': ['arrow-bottom'],
|
|
852
|
+
'fa-arrow-from-bottom': ['upload'],
|
|
853
|
+
'fa-arrow-left': ['arrow-left'],
|
|
854
|
+
'fa-arrow-right': ['arrow-right'],
|
|
855
|
+
'fa-arrow-to-bottom': ['download'],
|
|
856
|
+
'fa-arrow-to-top': ['back-to-top'],
|
|
857
|
+
'fa-arrow-up': ['arrow-top'],
|
|
858
|
+
'fa-arrows-h': ['resize-horizontal'],
|
|
859
|
+
'fa-at': ['arobase'],
|
|
860
|
+
'fa-atom': ['lx-icons/atom'],
|
|
861
|
+
'fa-badge-check': ['lx-icons/badge-sign'],
|
|
862
|
+
'fa-balance-scale-right': ['compare-2'],
|
|
863
|
+
'fa-ballot-check': ['activities'],
|
|
864
|
+
'fa-ban': ['cancel'],
|
|
865
|
+
'fa-bars': ['menu2'],
|
|
866
|
+
'fa-bell': ['bell'],
|
|
867
|
+
'fa-binoculars': ['sys-find'],
|
|
868
|
+
'fa-bold': ['bold-text'],
|
|
869
|
+
'fa-bolt': ['tnt/raise-fault'],
|
|
870
|
+
'fa-book': ['course-book'],
|
|
871
|
+
'fa-book-open': ['education'],
|
|
872
|
+
'fa-books': ['course-book'],
|
|
873
|
+
'fa-bug': ['lx-icons/bug'],
|
|
874
|
+
'fa-bullhorn': ['marketing-campaign'],
|
|
875
|
+
'fa-bullseye-arrow': ['lx-icons/bullseye-arrow'],
|
|
876
|
+
'fa-calendar': ['calendar'],
|
|
877
|
+
'fa-caret-down': ['megamenu'],
|
|
878
|
+
'fa-caret-left': ['navigation-left-arrow'],
|
|
879
|
+
'fa-caret-up': ['sorting-ranking'],
|
|
880
|
+
'fa-chart-bar': ['vertical-bar-chart'],
|
|
881
|
+
'fa-chart-pie-alt': ['pie-chart'],
|
|
882
|
+
'fa-check': ['accept'],
|
|
883
|
+
'fa-check-circle': ['status-completed'],
|
|
884
|
+
'fa-check-square': ['complete'],
|
|
885
|
+
'fa-chess-queen-alt': ['lx-icons/chess-queen'],
|
|
886
|
+
'fa-chevron-down': ['navigation-down-arrow'],
|
|
887
|
+
'fa-chevron-left': ['navigation-left-arrow'],
|
|
888
|
+
'fa-chevron-right': ['navigation-right-arrow'],
|
|
889
|
+
'fa-chevron-square-down': ['navigation-down-arrow'],
|
|
890
|
+
'fa-chevron-square-right': ['navigation-right-arrow'],
|
|
891
|
+
'fa-chevron-up': ['navigation-up-arrow'],
|
|
892
|
+
'fa-child': ['tnt/actor'],
|
|
893
|
+
'fa-circle': ['circle-task', 'circle-task-2'],
|
|
894
|
+
'fa-clipboard-list-check': ['order-status'],
|
|
895
|
+
'fa-clock': ['in-progress'],
|
|
896
|
+
'fa-clone': ['duplicate'],
|
|
897
|
+
'fa-cloud': ['cloud'],
|
|
898
|
+
'fa-code': ['source-code'],
|
|
899
|
+
'fa-code-branch': ['business-suite/empty-sequence'],
|
|
900
|
+
'fa-cog': ['action-settings'],
|
|
901
|
+
'fa-comment': ['comment'],
|
|
902
|
+
'fa-comment-alt': ['comment'],
|
|
903
|
+
'fa-comment-alt-check': ['lx-icons/comment-alt-check'],
|
|
904
|
+
'fa-comment-lines': ['comment'],
|
|
905
|
+
'fa-comments': ['discussion'],
|
|
906
|
+
'fa-comments-alt': ['discussion'],
|
|
907
|
+
'fa-compass': ['business-objects-explorer'],
|
|
908
|
+
'fa-compress': ['exit-full-screen'],
|
|
909
|
+
'fa-confluence': ['lx-icons/confluence'],
|
|
910
|
+
'fa-copy': ['copy'],
|
|
911
|
+
'fa-database': ['database'],
|
|
912
|
+
'fa-diamond': ['rhombus-milestone', 'rhombus-milestone-2'],
|
|
913
|
+
'fa-do-not-enter': ['sys-minus'],
|
|
914
|
+
'fa-dollar-sign': ['lx-icons/dollar-sign'],
|
|
915
|
+
'fa-download': ['download'],
|
|
916
|
+
'fa-edit': ['edit'],
|
|
917
|
+
'fa-ellipsis-h': ['overflow'],
|
|
918
|
+
'fa-ellipsis-v': ['overflow'],
|
|
919
|
+
'fa-envelope': ['email'],
|
|
920
|
+
'fa-euro-sign': ['lx-icons/euro-sign'],
|
|
921
|
+
'fa-exchange': ['lx-icons/exchange'],
|
|
922
|
+
'fa-exclamation': ['business-suite/priority-1'],
|
|
923
|
+
'fa-exclamation-circle': ['lx-icons/exclamation-circle'],
|
|
924
|
+
'fa-exclamation-square': ['high-priority'],
|
|
925
|
+
'fa-exclamation-triangle': ['warning'],
|
|
926
|
+
'fa-expand': ['full-screen'],
|
|
927
|
+
'fa-expand-alt': ['full-screen'],
|
|
928
|
+
'fa-expand-wide': ['full-screen'],
|
|
929
|
+
'fa-external-link': ['action'],
|
|
930
|
+
'fa-external-link-alt': ['action'],
|
|
931
|
+
'fa-eye': ['show'],
|
|
932
|
+
'fa-eye-dropper': ['business-suite/pipette'],
|
|
933
|
+
'fa-eye-slash': ['hide'],
|
|
934
|
+
'fa-feather': ['lx-icons/feather'],
|
|
935
|
+
'fa-file': ['document'],
|
|
936
|
+
'fa-file-alt': ['document'],
|
|
937
|
+
'fa-file-audio': ['attachment-audio'],
|
|
938
|
+
'fa-file-certificate': ['verified'],
|
|
939
|
+
'fa-file-download': ['download'],
|
|
940
|
+
'fa-file-excel': ['excel-attachment'],
|
|
941
|
+
'fa-file-image': ['attachment-photo'],
|
|
942
|
+
'fa-file-pdf': ['pdf-attachment'],
|
|
943
|
+
'fa-file-plus': ['add-document'],
|
|
944
|
+
'fa-file-video': ['attachment-video'],
|
|
945
|
+
'fa-file-word': ['doc-attachment'],
|
|
946
|
+
'fa-filter': ['filter'],
|
|
947
|
+
'fa-fire': ['business-suite/fire'],
|
|
948
|
+
'fa-fire-alt': ['business-suite/fire'],
|
|
949
|
+
'fa-folder': ['folder-blank'],
|
|
950
|
+
'fa-folder-open': ['open-folder'],
|
|
951
|
+
'fa-folder-tree': ['lx-icons/folder-tree'],
|
|
952
|
+
'fa-gavel': ['lx-icons/gavel'],
|
|
953
|
+
'fa-globe': ['world'],
|
|
954
|
+
'fa-graduation-cap': ['study-leave'],
|
|
955
|
+
'fa-grip-lines': ['media-pause'],
|
|
956
|
+
'fa-hammer': ['lx-icons/hammer'],
|
|
957
|
+
'fa-handshake': ['decision'],
|
|
958
|
+
'fa-hat-wizard': ['lx-icons/hat-wizard'],
|
|
959
|
+
'fa-heading': ['heading1'],
|
|
960
|
+
'fa-headset': ['headset'],
|
|
961
|
+
'fa-history': ['history'],
|
|
962
|
+
'fa-home': ['home'],
|
|
963
|
+
'fa-hourglass-end': ['lx-icons/hourglass-end'],
|
|
964
|
+
'fa-hourglass-half': ['lateness'],
|
|
965
|
+
'fa-house': ['home'],
|
|
966
|
+
'fa-image': ['picture'],
|
|
967
|
+
'fa-info': ['message-information'],
|
|
968
|
+
'fa-info-circle': ['message-information', 'information'],
|
|
969
|
+
'fa-info-square': ['message-information', 'information'],
|
|
970
|
+
'fa-italic': ['italic-text'],
|
|
971
|
+
'fa-jira': ['rhombus-milestone'],
|
|
972
|
+
'fa-key': ['key'],
|
|
973
|
+
'fa-keyboard': ['keyboard-and-mouse'],
|
|
974
|
+
'fa-lemon': ['lx-icons/lemon'],
|
|
975
|
+
'fa-lightbulb': ['lightbulb'],
|
|
976
|
+
'fa-lightbulb-on': ['lx-icons/lightbulb-check'],
|
|
977
|
+
'fa-link': ['chain-link'],
|
|
978
|
+
'fa-list': ['list'],
|
|
979
|
+
'fa-list-ol': ['business-suite/icon-bulleting-with-numbers'],
|
|
980
|
+
'fa-list-ul': ['list'],
|
|
981
|
+
'fa-lock': ['locked'],
|
|
982
|
+
'fa-lock-alt': ['locked'],
|
|
983
|
+
'fa-lock-open': ['unlocked'],
|
|
984
|
+
'fa-long-arrow-left': ['arrow-left'],
|
|
985
|
+
'fa-long-arrow-right': ['arrow-right'],
|
|
986
|
+
'fa-map': ['map-3'],
|
|
987
|
+
'fa-map-pin': ['lx-icons/map-pin'],
|
|
988
|
+
'fa-map-signs': ['lx-icons/map-signs'],
|
|
989
|
+
'fa-minus': ['less'],
|
|
990
|
+
'fa-minus-circle': ['sys-minus'],
|
|
991
|
+
'fa-minus-square': ['negative'],
|
|
992
|
+
'fa-paragraph': ['text'],
|
|
993
|
+
'fa-pause': ['media-pause'],
|
|
994
|
+
'fa-pen': ['edit'],
|
|
995
|
+
'fa-pencil': ['edit'],
|
|
996
|
+
'fa-people-arrows': ['citizen-connect'],
|
|
997
|
+
'fa-phone-alt': ['call'],
|
|
998
|
+
'fa-play': ['media-play'],
|
|
999
|
+
'fa-play-circle': ['play'],
|
|
1000
|
+
'fa-plug': ['disconnected'],
|
|
1001
|
+
'fa-plus': ['add'],
|
|
1002
|
+
'fa-plus-circle': ['sys-add'],
|
|
1003
|
+
'fa-pound-sign': ['lx-icons/pound-sign'],
|
|
1004
|
+
'fa-power-off': ['log'],
|
|
1005
|
+
'fa-presentation': ['projector'],
|
|
1006
|
+
'fa-print': ['print'],
|
|
1007
|
+
'fa-project-diagram': ['lx-icons/project-diagram'],
|
|
1008
|
+
'fa-question': ['incident'],
|
|
1009
|
+
'fa-question-circle': ['question-mark'],
|
|
1010
|
+
'fa-question-square': ['question-mark'],
|
|
1011
|
+
'fa-quote-right': ['lx-icons/quote-right'],
|
|
1012
|
+
'fa-radar': ['business-suite/radius'],
|
|
1013
|
+
'fa-random': ['tnt/flow'],
|
|
1014
|
+
'fa-rectangle-landscape': ['iphone-2'],
|
|
1015
|
+
'fa-rectangle-portrait': ['iphone'],
|
|
1016
|
+
'fa-rectangle-wide': ['legend'],
|
|
1017
|
+
'fa-redo': ['refresh'],
|
|
1018
|
+
'fa-repeat': ['synchronize'],
|
|
1019
|
+
'fa-road': ['lx-icons/road'],
|
|
1020
|
+
'fa-robot': ['lx-icons/robot'],
|
|
1021
|
+
'fa-rocket': ['lx-icons/rocket'],
|
|
1022
|
+
'fa-save': ['save'],
|
|
1023
|
+
'fa-search': ['search'],
|
|
1024
|
+
'fa-seedling': ['e-care'],
|
|
1025
|
+
'fa-shapes': ['program-triangles'],
|
|
1026
|
+
'fa-share-alt': ['share-2'],
|
|
1027
|
+
'fa-share-square': ['action'],
|
|
1028
|
+
'fa-shield': ['lx-icons/shield'],
|
|
1029
|
+
'fa-shield-alt': ['lx-icons/shield'],
|
|
1030
|
+
'fa-shield-check': ['checklist-item'],
|
|
1031
|
+
'fa-shopping-cart': ['cart'],
|
|
1032
|
+
'fa-signal': ['lx-icons/signal'],
|
|
1033
|
+
'fa-sitemap': ['tree'],
|
|
1034
|
+
'fa-sort': ['sorting-ranking'],
|
|
1035
|
+
'fa-sort-alt': ['sort'],
|
|
1036
|
+
'fa-sort-down': ['megamenu'],
|
|
1037
|
+
'fa-sort-up': ['sorting-ranking'],
|
|
1038
|
+
'fa-sparkles': ['ai'],
|
|
1039
|
+
'fa-spinner': ['pending'],
|
|
1040
|
+
'fa-square': ['border'],
|
|
1041
|
+
'fa-star': ['unfavorite', 'favorite'],
|
|
1042
|
+
'fa-sticky-note': ['notes'],
|
|
1043
|
+
'fa-strikethrough': ['strikethrough'],
|
|
1044
|
+
'fa-sync': ['synchronize'],
|
|
1045
|
+
'fa-sync-alt': ['synchronize'],
|
|
1046
|
+
'fa-table': ['business-suite/2x2-grid-layout'],
|
|
1047
|
+
'fa-tachometer': ['performance'],
|
|
1048
|
+
'fa-tachometer-alt-average': ['performance'],
|
|
1049
|
+
'fa-tags': ['blank-tag-2'],
|
|
1050
|
+
'fa-tasks': ['activities'],
|
|
1051
|
+
'fa-tasks-alt': ['lx-icons/tasks'],
|
|
1052
|
+
'fa-text': ['text'],
|
|
1053
|
+
'fa-th': ['business-suite/2x2-grid-layout'],
|
|
1054
|
+
'fa-th-large': ['business-suite/2x2-grid-layout'],
|
|
1055
|
+
'fa-thumbs-down': ['thumb-down'],
|
|
1056
|
+
'fa-thumbs-up': ['thumb-up'],
|
|
1057
|
+
'fa-times': ['decline'],
|
|
1058
|
+
'fa-times-circle': ['error'],
|
|
1059
|
+
'fa-toolbox': ['lx-icons/toolbox'],
|
|
1060
|
+
'fa-tools': ['wrench'],
|
|
1061
|
+
'fa-trash': ['delete'],
|
|
1062
|
+
'fa-trash-restore': ['history'],
|
|
1063
|
+
'fa-trophy': ['competitor'],
|
|
1064
|
+
'fa-tshirt': ['lx-icons/tshirt'],
|
|
1065
|
+
'fa-umbrella-beach': ['umbrella'],
|
|
1066
|
+
'fa-underline': ['underline-text'],
|
|
1067
|
+
'fa-undo': ['undo'],
|
|
1068
|
+
'fa-unicorn': ['lx-icons/unicorn'],
|
|
1069
|
+
'fa-unlink': ['broken-link'],
|
|
1070
|
+
'fa-upload': ['upload'],
|
|
1071
|
+
'fa-user': ['person-placeholder'],
|
|
1072
|
+
'fa-user-friends': ['group'],
|
|
1073
|
+
'fa-user-hard-hat': ['lx-icons/user-hard-hat'],
|
|
1074
|
+
'fa-user-headset': ['headset'],
|
|
1075
|
+
'fa-user-robot': ['lx-icons/robot'],
|
|
1076
|
+
'fa-users': ['family-care'],
|
|
1077
|
+
'fa-window': ['lx-icons/window'], // ['tnt/subject'],
|
|
1078
|
+
'fa-wrench': ['wrench'],
|
|
1079
|
+
'fa-yen-sign': ['lx-icons/yen-sign']
|
|
1080
|
+
};
|
|
1081
|
+
/**
|
|
1082
|
+
* Retrieves the SAP icon for a given Font Awesome icon name.
|
|
1083
|
+
* @param faIcon Font Awesome icon name (e.g., 'fa-check')
|
|
1084
|
+
* @param solid If true, returns solid variant when available
|
|
1085
|
+
* @returns SAP icon name or undefined if not mapped
|
|
892
1086
|
*/
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
this.debounceMsAfterResize = debounceMsAfterResize;
|
|
898
|
-
this.cdRef = cdRef;
|
|
899
|
-
this.hostEl = hostEl;
|
|
900
|
-
this.resizeObserverService = resizeObserverService;
|
|
901
|
-
this.translateService = translateService;
|
|
902
|
-
this.content = '';
|
|
903
|
-
/**
|
|
904
|
-
* Only set this to false if the content is not a user provided string
|
|
905
|
-
* or if you sanitize the provided content yourself.
|
|
906
|
-
*/
|
|
907
|
-
this.escapeHtmlInContent = true;
|
|
908
|
-
/** @internal */
|
|
909
|
-
this.isShowingMore$ = new BehaviorSubject(false);
|
|
910
|
-
this.destroyed$ = new Subject();
|
|
911
|
-
this.viewChecked$ = new Subject();
|
|
912
|
-
}
|
|
913
|
-
ngOnInit() {
|
|
914
|
-
this.sanitizedContent$ = this.content$.pipe(map((content) => {
|
|
915
|
-
if (this.escapeHtmlInContent && typeof content === 'string') {
|
|
916
|
-
return escape(content);
|
|
917
|
-
}
|
|
918
|
-
return content;
|
|
919
|
-
}));
|
|
920
|
-
this.showMoreButtonLabel$ = this.isShowingMore$.pipe(switchMap((isShowingMore) => {
|
|
921
|
-
const translationKey = isShowingMore ? 'common.showLess' : 'common.showMore';
|
|
922
|
-
return this.translateService.get(translationKey);
|
|
923
|
-
}));
|
|
924
|
-
const newWidthOnResize$ = new Subject();
|
|
925
|
-
const newHeightOnResize$ = new Subject();
|
|
926
|
-
this.resizeObserverService.observe(this.hostEl.nativeElement, (resizedElement) => {
|
|
927
|
-
newWidthOnResize$.next(resizedElement.contentRect.width);
|
|
928
|
-
newHeightOnResize$.next(resizedElement.contentRect.height);
|
|
929
|
-
});
|
|
930
|
-
const containerWidthChangedSignificantlyAfterResize$ = newWidthOnResize$.pipe(startWith(0), pairwise(), filter(([previousWidth, newWidth]) => Math.abs(newWidth - previousWidth) > 1), map(([, newWidth]) => newWidth));
|
|
931
|
-
const userTriggeredTriggeredShowLess$ = this.isShowingMore$.pipe(filter((isShowingMore) => !isShowingMore));
|
|
932
|
-
const reevaluateIfContentIsOverflowing$ = combineLatest([
|
|
933
|
-
this.contentSpanEl$,
|
|
934
|
-
userTriggeredTriggeredShowLess$,
|
|
935
|
-
containerWidthChangedSignificantlyAfterResize$
|
|
936
|
-
]);
|
|
937
|
-
const isContentOverflowing$ = merge(concat(reevaluateIfContentIsOverflowing$.pipe(take(1)), // debounce all but the first output
|
|
938
|
-
reevaluateIfContentIsOverflowing$.pipe(debounceTime(this.debounceMsAfterResize))), this.content$.pipe(skip(1), switchMap(() => this.viewChecked$))).pipe(withLatestFrom(this.contentSpanEl$), map(([, contentSpanRef]) => this.isContentOverflowing(contentSpanRef)));
|
|
939
|
-
const userTriggeredTriggeredShowMore$ = this.isShowingMore$.pipe(filter((isShowingMore) => isShowingMore));
|
|
940
|
-
const buttonHeight$ = this.showMoreButtonEl$.pipe(filter((showMoreButtonEl) => !!showMoreButtonEl), map((showMoreButtonEl) => showMoreButtonEl.nativeElement.offsetHeight), distinctUntilChanged());
|
|
941
|
-
const userIncreasedBrowserWindowSizeToThePointOfNoTruncationNecessary$ = combineLatest([
|
|
942
|
-
buttonHeight$,
|
|
943
|
-
newHeightOnResize$.pipe(distinctUntilChanged())
|
|
944
|
-
]).pipe(withLatestFrom(this.isShowingMore$), filter(([, isShowingMore]) => isShowingMore), map(([[buttonHeight, newHeight]]) => {
|
|
945
|
-
const heightOfOneLine = buttonHeight;
|
|
946
|
-
const showLessButtonMarginTop = 4;
|
|
947
|
-
const heightOfSpanInShowMoreMode = newHeight - buttonHeight - showLessButtonMarginTop;
|
|
948
|
-
const thresholdToDetectContentInSingleLine = 4;
|
|
949
|
-
const differenceBetweenContentSpanAndButtonHeight = Math.abs(heightOfOneLine - heightOfSpanInShowMoreMode);
|
|
950
|
-
const isSpanContentDisplayedInOneLineAgain = differenceBetweenContentSpanAndButtonHeight < thresholdToDetectContentInSingleLine;
|
|
951
|
-
return isSpanContentDisplayedInOneLineAgain;
|
|
952
|
-
}));
|
|
953
|
-
const contentFitsInOneLineAgainWhileShowMoreIsEnabled$ = userIncreasedBrowserWindowSizeToThePointOfNoTruncationNecessary$.pipe(startWith(false), pairwise(), filter(([previousTextIsNowInOneLineAgain]) => !previousTextIsNowInOneLineAgain), map(([, textIsNowInOneLineAgain]) => !textIsNowInOneLineAgain));
|
|
954
|
-
const contentIsOverflowingAndShowMoreIsNotEnabled$ = isContentOverflowing$.pipe(withLatestFrom(this.isShowingMore$), filter(([, isShowingMore]) => !isShowingMore), map(([isContentLongerThanContainerWidth]) => {
|
|
955
|
-
return isContentLongerThanContainerWidth;
|
|
956
|
-
}));
|
|
957
|
-
this.showButton$ = merge(userTriggeredTriggeredShowMore$, contentFitsInOneLineAgainWhileShowMoreIsEnabled$, contentIsOverflowingAndShowMoreIsNotEnabled$);
|
|
958
|
-
// As long as no parent component is listening on resize events,
|
|
959
|
-
// the ChangeDetectorRef.markForCheck() call done by the async pipe
|
|
960
|
-
// will not result in a change detection cycle in this component when its size changes.
|
|
961
|
-
// This is the least amount of ChangeDetectorRef.detectChanges() calls
|
|
962
|
-
// I was able to come up with. The Angular profiler shows acceptable numbers of change detection.
|
|
963
|
-
this.detectChangesWhenObservableEmits(isContentOverflowing$);
|
|
964
|
-
this.detectChangesWhenObservableEmits(this.showButton$);
|
|
965
|
-
this.detectChangesWhenObservableEmits(this.content$);
|
|
966
|
-
this.detectChangesWhenObservableEmits(contentIsOverflowingAndShowMoreIsNotEnabled$);
|
|
967
|
-
this.detectChangesWhenObservableEmits(isContentOverflowing$);
|
|
968
|
-
}
|
|
969
|
-
ngAfterViewChecked() {
|
|
970
|
-
this.viewChecked$.next();
|
|
971
|
-
}
|
|
972
|
-
/** @internal */
|
|
973
|
-
onShowMoreToggle() {
|
|
974
|
-
this.isShowingMore$.next(!this.isShowingMore$.getValue());
|
|
975
|
-
this.cdRef.detectChanges();
|
|
976
|
-
}
|
|
977
|
-
ngOnDestroy() {
|
|
978
|
-
this.resizeObserverService.unobserve(this.hostEl.nativeElement);
|
|
979
|
-
}
|
|
980
|
-
detectChangesWhenObservableEmits(observable$) {
|
|
981
|
-
observable$.pipe(takeUntil(this.destroyed$)).subscribe(() => this.cdRef.detectChanges());
|
|
982
|
-
}
|
|
983
|
-
isContentOverflowing(contentSpanElRef) {
|
|
984
|
-
const scrollWidth = contentSpanElRef.nativeElement.scrollWidth;
|
|
985
|
-
const offsetWidth = contentSpanElRef.nativeElement.clientWidth;
|
|
986
|
-
return offsetWidth < scrollWidth;
|
|
987
|
-
}
|
|
988
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EllipsisComponent, deps: [{ token: LX_ELLIPSIS_DEBOUNCE_ON_RESIZE }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: ResizeObserverService }, { token: i1.TranslateService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
989
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: EllipsisComponent, isStandalone: true, selector: "lx-ellipsis", inputs: { content: "content", escapeHtmlInContent: "escapeHtmlInContent" }, viewQueries: [{ propertyName: "contentSpanEl", first: true, predicate: ["contentEl"], descendants: true }, { propertyName: "showMoreButtonEl", first: true, predicate: ["showMoreButton"], descendants: true, read: ElementRef }], ngImport: i0, template: "<span\n #contentEl\n [class.showMore]=\"isShowingMore$ | async\"\n class=\"content truncate lx-margin-right\"\n [innerHtml]=\"sanitizedContent$ | async\"\n></span>\n@if (showButton$ | async) {\n <button (click)=\"onShowMoreToggle()\" lx-button #showMoreButton size=\"auto\" mode=\"link\" color=\"primary\">\n {{ showMoreButtonLabel$ | async }}\n </button>\n}\n", styles: [":host{display:block;white-space:pre-line;overflow-wrap:break-word}.content{display:inline-block;word-break:break-word}.truncate:not(.showMore){width:calc(100% - 140px);white-space:nowrap;overflow-wrap:normal;overflow:hidden;text-overflow:ellipsis}.content.showMore+button{margin-top:4px;display:block}button{white-space:nowrap;vertical-align:top}\n"], dependencies: [{ kind: "component", type: ButtonComponent, selector: "button[lx-button]", inputs: ["size", "color", "mode", "pressed", "selected", "square", "circle", "disabled", "icon", "endIcon", "showSpinner"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
990
|
-
}
|
|
991
|
-
__decorate([
|
|
992
|
-
Observe('contentSpanEl')
|
|
993
|
-
], EllipsisComponent.prototype, "contentSpanEl$", void 0);
|
|
994
|
-
__decorate([
|
|
995
|
-
Observe('showMoreButtonEl')
|
|
996
|
-
], EllipsisComponent.prototype, "showMoreButtonEl$", void 0);
|
|
997
|
-
__decorate([
|
|
998
|
-
Observe('content')
|
|
999
|
-
], EllipsisComponent.prototype, "content$", void 0);
|
|
1000
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EllipsisComponent, decorators: [{
|
|
1001
|
-
type: Component,
|
|
1002
|
-
args: [{ selector: 'lx-ellipsis', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ButtonComponent, AsyncPipe], template: "<span\n #contentEl\n [class.showMore]=\"isShowingMore$ | async\"\n class=\"content truncate lx-margin-right\"\n [innerHtml]=\"sanitizedContent$ | async\"\n></span>\n@if (showButton$ | async) {\n <button (click)=\"onShowMoreToggle()\" lx-button #showMoreButton size=\"auto\" mode=\"link\" color=\"primary\">\n {{ showMoreButtonLabel$ | async }}\n </button>\n}\n", styles: [":host{display:block;white-space:pre-line;overflow-wrap:break-word}.content{display:inline-block;word-break:break-word}.truncate:not(.showMore){width:calc(100% - 140px);white-space:nowrap;overflow-wrap:normal;overflow:hidden;text-overflow:ellipsis}.content.showMore+button{margin-top:4px;display:block}button{white-space:nowrap;vertical-align:top}\n"] }]
|
|
1003
|
-
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
1004
|
-
type: Inject,
|
|
1005
|
-
args: [LX_ELLIPSIS_DEBOUNCE_ON_RESIZE]
|
|
1006
|
-
}] }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: ResizeObserverService }, { type: i1.TranslateService }], propDecorators: { content: [{
|
|
1007
|
-
type: Input
|
|
1008
|
-
}], escapeHtmlInContent: [{
|
|
1009
|
-
type: Input
|
|
1010
|
-
}], contentSpanEl$: [], contentSpanEl: [{
|
|
1011
|
-
type: ViewChild,
|
|
1012
|
-
args: ['contentEl']
|
|
1013
|
-
}], showMoreButtonEl$: [], showMoreButtonEl: [{
|
|
1014
|
-
type: ViewChild,
|
|
1015
|
-
args: ['showMoreButton', { read: ElementRef }]
|
|
1016
|
-
}], content$: [] } });
|
|
1017
|
-
|
|
1018
|
-
class EmptyStateComponent {
|
|
1019
|
-
constructor() {
|
|
1020
|
-
/**
|
|
1021
|
-
* The title to be displayed
|
|
1022
|
-
*/
|
|
1023
|
-
this.title = input.required();
|
|
1024
|
-
/**
|
|
1025
|
-
* The SAP icon to show in the empty state.
|
|
1026
|
-
*/
|
|
1027
|
-
this.icon = input();
|
|
1028
|
-
/**
|
|
1029
|
-
* The main call-to-action button label
|
|
1030
|
-
*/
|
|
1031
|
-
this.buttonLabel = input();
|
|
1032
|
-
/**
|
|
1033
|
-
* The secondary call-to-action button label
|
|
1034
|
-
*/
|
|
1035
|
-
this.secondaryButtonLabel = input();
|
|
1036
|
-
/**
|
|
1037
|
-
* Whether the empty state is in a loading state. If true, main call-to-action button will show a spinner
|
|
1038
|
-
*/
|
|
1039
|
-
this.loading = input(false);
|
|
1040
|
-
/**
|
|
1041
|
-
* The more link label
|
|
1042
|
-
*/
|
|
1043
|
-
this.moreLinkLabel = input();
|
|
1044
|
-
/**
|
|
1045
|
-
* The URL of the more link
|
|
1046
|
-
*/
|
|
1047
|
-
this.moreLink = input();
|
|
1048
|
-
/**
|
|
1049
|
-
* Whether the more link should be opened in a new tab
|
|
1050
|
-
*
|
|
1051
|
-
* @default true
|
|
1052
|
-
*/
|
|
1053
|
-
this.openMoreLinkInNewTab = input(true);
|
|
1054
|
-
/**
|
|
1055
|
-
* The size of the empty state
|
|
1056
|
-
*
|
|
1057
|
-
* @default medium
|
|
1058
|
-
*/
|
|
1059
|
-
this.size = input('medium');
|
|
1060
|
-
this.useRouterLink = computed(() => Array.isArray(this.moreLink()));
|
|
1061
|
-
/**
|
|
1062
|
-
* Emitted when the main call-to-action button is clicked
|
|
1063
|
-
*/
|
|
1064
|
-
this.buttonClicked = new EventEmitter();
|
|
1065
|
-
/**
|
|
1066
|
-
* Emitted when the secondary call-to-action button is clicked
|
|
1067
|
-
*/
|
|
1068
|
-
this.secondaryButtonClicked = new EventEmitter();
|
|
1069
|
-
/**
|
|
1070
|
-
* Emitted when the more link is clicked
|
|
1071
|
-
*/
|
|
1072
|
-
this.moreLinkClicked = new EventEmitter();
|
|
1073
|
-
}
|
|
1074
|
-
get _size() {
|
|
1075
|
-
return this.size();
|
|
1087
|
+
function getSapIcon(faIcon, solid = false) {
|
|
1088
|
+
const icons = ICON_MAP[faIcon];
|
|
1089
|
+
if (!icons) {
|
|
1090
|
+
return undefined;
|
|
1076
1091
|
}
|
|
1077
|
-
|
|
1078
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: EmptyStateComponent, isStandalone: true, selector: "lx-empty-state", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, buttonLabel: { classPropertyName: "buttonLabel", publicName: "buttonLabel", isSignal: true, isRequired: false, transformFunction: null }, secondaryButtonLabel: { classPropertyName: "secondaryButtonLabel", publicName: "secondaryButtonLabel", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, moreLinkLabel: { classPropertyName: "moreLinkLabel", publicName: "moreLinkLabel", isSignal: true, isRequired: false, transformFunction: null }, moreLink: { classPropertyName: "moreLink", publicName: "moreLink", isSignal: true, isRequired: false, transformFunction: null }, openMoreLinkInNewTab: { classPropertyName: "openMoreLinkInNewTab", publicName: "openMoreLinkInNewTab", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { buttonClicked: "buttonClicked", secondaryButtonClicked: "secondaryButtonClicked", moreLinkClicked: "moreLinkClicked" }, host: { properties: { "attr.size": "this._size" } }, ngImport: i0, template: "<div class=\"tw-max-w-[434px] tw-text-center\">\n @if (icon(); as icon) {\n <ui5-icon [name]=\"icon\" design=\"Information\" />\n }\n\n <h3 class=\"empty-state-title tw-mb-m tw-mt-xl tw-text-black\" [innerHTML]=\"title()\"></h3>\n\n <div class=\"empty-state-content tw-leading-[16px] tw-text-gray-50\">\n <ng-content />\n </div>\n\n <div class=\"tw-flex tw-justify-center tw-gap-m\">\n @if (secondaryButtonLabel()) {\n <div class=\"secondaryButton tw-my-xl\">\n <button lx-button size=\"large\" [showSpinner]=\"loading()\" (click)=\"secondaryButtonClicked.emit($event)\">\n {{ secondaryButtonLabel() }}\n </button>\n </div>\n }\n\n @if (buttonLabel()) {\n <div class=\"actionButton tw-my-xl\">\n <button lx-button size=\"large\" color=\"primary\" [showSpinner]=\"loading()\" (click)=\"buttonClicked.emit($event)\">\n {{ buttonLabel() }}\n </button>\n </div>\n }\n </div>\n\n @if (moreLinkLabel() && moreLink()) {\n <div>\n @if (useRouterLink()) {\n <a\n rel=\"noopener noreferrer\"\n class=\"tw-text-size-md tw-text-primary\"\n [routerLink]=\"moreLink()\"\n (click)=\"moreLinkClicked.emit($event)\"\n [target]=\"openMoreLinkInNewTab() ? '_blank' : '_self'\"\n >{{ moreLinkLabel() }}</a\n >\n } @else {\n <a\n rel=\"noopener noreferrer\"\n class=\"tw-text-size-md tw-text-primary\"\n [href]=\"moreLink()\"\n (click)=\"moreLinkClicked.emit($event)\"\n [target]=\"openMoreLinkInNewTab() ? '_blank' : '_self'\"\n >{{ moreLinkLabel() }}</a\n >\n }\n </div>\n }\n</div>\n", styles: [":host{display:flex;justify-content:center}:host[size=small] .empty-state-title{font-size:var(--lxFontSize, 14px)}:host[size=small] .empty-state-content{font-size:var(--lxFontSmallSize, 12px)}:host[size=medium] .empty-state-title{font-size:var(--lxFontHeader2Size, 24px)}:host[size=medium] .empty-state-content{font-size:var(--lxFontSize, 14px)}ui5-icon{position:relative;width:2rem;height:2rem}ui5-icon:after{content:\"\";position:absolute;bottom:-8px;left:50%;transform:translate(-50%);height:6px;width:44px;background-color:#f0f2f5;border-radius:100%}\n"], dependencies: [{ kind: "component", type: ButtonComponent, selector: "button[lx-button]", inputs: ["size", "color", "mode", "pressed", "selected", "square", "circle", "disabled", "icon", "endIcon", "showSpinner"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: IconComponent$1, selector: "ui5-icon", inputs: ["design", "name", "accessibleName", "showTooltip", "mode"], outputs: ["ui5Click"], exportAs: ["ui5Icon"] }] }); }
|
|
1092
|
+
return solid && icons[1] ? icons[1] : icons[0];
|
|
1079
1093
|
}
|
|
1080
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EmptyStateComponent, decorators: [{
|
|
1081
|
-
type: Component,
|
|
1082
|
-
args: [{ selector: 'lx-empty-state', imports: [ButtonComponent, RouterLink, IconComponent$1], template: "<div class=\"tw-max-w-[434px] tw-text-center\">\n @if (icon(); as icon) {\n <ui5-icon [name]=\"icon\" design=\"Information\" />\n }\n\n <h3 class=\"empty-state-title tw-mb-m tw-mt-xl tw-text-black\" [innerHTML]=\"title()\"></h3>\n\n <div class=\"empty-state-content tw-leading-[16px] tw-text-gray-50\">\n <ng-content />\n </div>\n\n <div class=\"tw-flex tw-justify-center tw-gap-m\">\n @if (secondaryButtonLabel()) {\n <div class=\"secondaryButton tw-my-xl\">\n <button lx-button size=\"large\" [showSpinner]=\"loading()\" (click)=\"secondaryButtonClicked.emit($event)\">\n {{ secondaryButtonLabel() }}\n </button>\n </div>\n }\n\n @if (buttonLabel()) {\n <div class=\"actionButton tw-my-xl\">\n <button lx-button size=\"large\" color=\"primary\" [showSpinner]=\"loading()\" (click)=\"buttonClicked.emit($event)\">\n {{ buttonLabel() }}\n </button>\n </div>\n }\n </div>\n\n @if (moreLinkLabel() && moreLink()) {\n <div>\n @if (useRouterLink()) {\n <a\n rel=\"noopener noreferrer\"\n class=\"tw-text-size-md tw-text-primary\"\n [routerLink]=\"moreLink()\"\n (click)=\"moreLinkClicked.emit($event)\"\n [target]=\"openMoreLinkInNewTab() ? '_blank' : '_self'\"\n >{{ moreLinkLabel() }}</a\n >\n } @else {\n <a\n rel=\"noopener noreferrer\"\n class=\"tw-text-size-md tw-text-primary\"\n [href]=\"moreLink()\"\n (click)=\"moreLinkClicked.emit($event)\"\n [target]=\"openMoreLinkInNewTab() ? '_blank' : '_self'\"\n >{{ moreLinkLabel() }}</a\n >\n }\n </div>\n }\n</div>\n", styles: [":host{display:flex;justify-content:center}:host[size=small] .empty-state-title{font-size:var(--lxFontSize, 14px)}:host[size=small] .empty-state-content{font-size:var(--lxFontSmallSize, 12px)}:host[size=medium] .empty-state-title{font-size:var(--lxFontHeader2Size, 24px)}:host[size=medium] .empty-state-content{font-size:var(--lxFontSize, 14px)}ui5-icon{position:relative;width:2rem;height:2rem}ui5-icon:after{content:\"\";position:absolute;bottom:-8px;left:50%;transform:translate(-50%);height:6px;width:44px;background-color:#f0f2f5;border-radius:100%}\n"] }]
|
|
1083
|
-
}], propDecorators: { _size: [{
|
|
1084
|
-
type: HostBinding,
|
|
1085
|
-
args: ['attr.size']
|
|
1086
|
-
}], buttonClicked: [{
|
|
1087
|
-
type: Output
|
|
1088
|
-
}], secondaryButtonClicked: [{
|
|
1089
|
-
type: Output
|
|
1090
|
-
}], moreLinkClicked: [{
|
|
1091
|
-
type: Output
|
|
1092
|
-
}] } });
|
|
1093
1094
|
|
|
1094
1095
|
class IconScaleComponent {
|
|
1095
1096
|
constructor() {
|
|
@@ -5536,7 +5537,7 @@ class DatepickerConfig {
|
|
|
5536
5537
|
this.formatDay = 'dd';
|
|
5537
5538
|
this.formatMonth = 'MMMM';
|
|
5538
5539
|
this.formatYear = 'yyyy';
|
|
5539
|
-
this.formatDayHeader = '
|
|
5540
|
+
this.formatDayHeader = 'EE';
|
|
5540
5541
|
this.formatDayTitle = 'MMMM yyyy';
|
|
5541
5542
|
this.formatMonthTitle = 'yyyy';
|
|
5542
5543
|
this.onlyCurrentMonth = false;
|
|
@@ -5791,7 +5792,7 @@ class DateInputComponent {
|
|
|
5791
5792
|
/** Format of year in year range */
|
|
5792
5793
|
this.formatYear = 'yyyy';
|
|
5793
5794
|
/** Format of day in week header */
|
|
5794
|
-
this.formatDayHeader = '
|
|
5795
|
+
this.formatDayHeader = 'EE';
|
|
5795
5796
|
/** Format of title when selecting day */
|
|
5796
5797
|
this.formatDayTitle = 'MMMM yyyy';
|
|
5797
5798
|
/** Format of title when selecting month */
|