@leanix/components 0.4.511 → 0.4.512
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/esm2022/index.mjs +6 -1
- package/esm2022/lib/core-ui/components/avatar/avatar.component.mjs +40 -0
- package/esm2022/lib/core-ui/components/avatar/avatar.helpers.mjs +49 -0
- package/esm2022/lib/core-ui/components/avatar/avatar.model.mjs +33 -0
- package/esm2022/lib/core-ui/components/avatar-group/avatar-group.component.mjs +73 -0
- package/esm2022/lib/core-ui/pipes/display-avatars.pipe.mjs +37 -0
- package/fesm2022/leanix-components.mjs +217 -1
- package/fesm2022/leanix-components.mjs.map +1 -1
- package/index.d.ts +4 -0
- package/lib/core-ui/components/avatar/avatar.component.d.ts +18 -0
- package/lib/core-ui/components/avatar/avatar.helpers.d.ts +8 -0
- package/lib/core-ui/components/avatar/avatar.model.d.ts +38 -0
- package/lib/core-ui/components/avatar-group/avatar-group.component.d.ts +28 -0
- package/lib/core-ui/pipes/display-avatars.pipe.d.ts +12 -0
- package/package.json +1 -1
@@ -2593,6 +2593,174 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImpor
|
|
2593
2593
|
}]
|
2594
2594
|
}] });
|
2595
2595
|
|
2596
|
+
class DisplayAvatarsPipe {
|
2597
|
+
transform(users, type, size, userGroupWidth, autoScale, maxLength) {
|
2598
|
+
if (maxLength) {
|
2599
|
+
return users.slice(0, maxLength);
|
2600
|
+
}
|
2601
|
+
if (autoScale) {
|
2602
|
+
if (type === 'group') {
|
2603
|
+
const usersToShow = Math.floor((userGroupWidth - 2 * SIZES[size]) / ((SIZES[size] * 2) / 3)) + 1;
|
2604
|
+
return users.slice(0, usersToShow);
|
2605
|
+
}
|
2606
|
+
else {
|
2607
|
+
const usersToShow = Math.floor(userGroupWidth / (SIZES[size] + 2)) - 1;
|
2608
|
+
return users.slice(0, usersToShow);
|
2609
|
+
}
|
2610
|
+
}
|
2611
|
+
return users;
|
2612
|
+
}
|
2613
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: DisplayAvatarsPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
2614
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.8", ngImport: i0, type: DisplayAvatarsPipe, isStandalone: true, name: "displayAvatars" }); }
|
2615
|
+
}
|
2616
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: DisplayAvatarsPipe, decorators: [{
|
2617
|
+
type: Pipe,
|
2618
|
+
args: [{
|
2619
|
+
name: 'displayAvatars',
|
2620
|
+
standalone: true
|
2621
|
+
}]
|
2622
|
+
}] });
|
2623
|
+
const SIZES = {
|
2624
|
+
XS: 16,
|
2625
|
+
S: 24,
|
2626
|
+
M: 32,
|
2627
|
+
L: 40,
|
2628
|
+
XL: 64
|
2629
|
+
};
|
2630
|
+
|
2631
|
+
const IMAGE_READER = new InjectionToken('IMAGE_READER');
|
2632
|
+
const DEFAULT_IMAGE_ID = '00000000-0000-4000-0000-000000000001';
|
2633
|
+
const REFERENCE_SIZE_MAPPING = {
|
2634
|
+
XS: 16,
|
2635
|
+
S: 24,
|
2636
|
+
M: 32,
|
2637
|
+
L: 40,
|
2638
|
+
XL: 64
|
2639
|
+
};
|
2640
|
+
// We want to use 2x bigger images for avatars to support high resolution displays
|
2641
|
+
// So we want to draw them in their original size but use 2x the size as reference
|
2642
|
+
const AVATAR_SIZE_MAPPING = {
|
2643
|
+
XS: REFERENCE_SIZE_MAPPING.XS * 2,
|
2644
|
+
S: REFERENCE_SIZE_MAPPING.S * 2,
|
2645
|
+
M: REFERENCE_SIZE_MAPPING.M * 2,
|
2646
|
+
L: REFERENCE_SIZE_MAPPING.L * 2,
|
2647
|
+
XL: REFERENCE_SIZE_MAPPING.XL * 2
|
2648
|
+
};
|
2649
|
+
const AVATAR_COLORS = [
|
2650
|
+
'#00a399',
|
2651
|
+
'#0f7eb5',
|
2652
|
+
'#18aece',
|
2653
|
+
'#2889ff',
|
2654
|
+
'#ff914d',
|
2655
|
+
'#fad71e',
|
2656
|
+
'#fe6690',
|
2657
|
+
'#ab657a',
|
2658
|
+
'#916b50',
|
2659
|
+
'#9755cd',
|
2660
|
+
'#fc9785'
|
2661
|
+
];
|
2662
|
+
|
2663
|
+
class AvatarComponent {
|
2664
|
+
constructor(imageReader) {
|
2665
|
+
this.imageReader = imageReader;
|
2666
|
+
this.size = 'M';
|
2667
|
+
this.showMailToLink = true;
|
2668
|
+
this.disabled = false;
|
2669
|
+
this.NAME = 'AvatarComponent';
|
2670
|
+
this.imageURL = this.imageReader.getAvatar(DEFAULT_IMAGE_ID, this.size, this.user?.displayName);
|
2671
|
+
}
|
2672
|
+
ngOnChanges(changes) {
|
2673
|
+
const { user } = changes;
|
2674
|
+
if (user && user.currentValue && !user.currentValue.technicalUser) {
|
2675
|
+
const { id, displayName } = this.user || {};
|
2676
|
+
this.imageURL = this.imageReader.getAvatar(id ?? undefined, this.size, displayName);
|
2677
|
+
}
|
2678
|
+
}
|
2679
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: AvatarComponent, deps: [{ token: IMAGE_READER }], target: i0.ɵɵFactoryTarget.Component }); }
|
2680
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.8", type: AvatarComponent, isStandalone: true, selector: "lx-avatar", inputs: { user: "user", size: "size", showMailToLink: "showMailToLink", disabled: "disabled" }, usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"imageURL | async; else loading\">\n <ng-container *ngIf=\"!user.technicalUser; else technicalUserIcon\">\n <a\n *ngIf=\"showMailToLink && user.email; else profilePicture\"\n class=\"userLink\"\n href=\"mailto:{{ user.email }}\"\n lxTooltip=\"{{ user.displayName }}\"\n >\n <img\n [src]=\"imageURL | async\"\n class=\"avatarImage\"\n [class]=\"size\"\n [class.disabled]=\"disabled\"\n role=\"presentation\"\n alt=\"{{ user.displayName }}\"\n />\n </a>\n <ng-template #profilePicture>\n <img\n [src]=\"imageURL | async\"\n class=\"avatarImage\"\n [class]=\"size\"\n [class.disabled]=\"disabled\"\n role=\"presentation\"\n alt=\"{{ user.displayName }}\"\n />\n </ng-template>\n </ng-container>\n <ng-template #technicalUserIcon>\n <i class=\"avatarImage fas fa-robot\" lxTooltip=\"{{ user.displayName }}\" [class]=\"size\" [class.disabled]=\"disabled\"></i>\n </ng-template>\n</ng-container>\n<ng-template #loading>\n <div class=\"avatarImage userLink loading\" [ngClass]=\"size\"></div>\n</ng-template>\n", styles: [".userLink{display:inline-block;width:fit-content;height:fit-content}.avatarImage{border-radius:50%}.avatarImage.disabled{opacity:.4}.loading{background:linear-gradient(270deg,#ccc,#eee,#ccc);background-size:200% 100%;animation:loading 1.5s infinite;object-fit:cover;vertical-align:middle}@keyframes loading{0%{background-position:200% 0}to{background-position:-200% 0}}.fa-robot{background-color:#b2bccc;color:#fff;vertical-align:middle;text-align:center}.fa-robot.XS{line-height:14px;font-size:10px}.fa-robot.S{line-height:22px;font-size:13px}.fa-robot.M{line-height:30px;font-size:18px}.fa-robot.L{line-height:38px;font-size:22px}.fa-robot.XL{line-height:62px;font-size:40px}.XS{width:16px;height:16px}.S{width:24px;height:24px}.M{width:32px;height:32px}.L{width:40px;height:40px}.XL{width:64px;height:64px}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: TooltipDirective, selector: "[lxTooltip]", inputs: ["lxTooltip", "lxTooltipPosition", "lxTooltipDelay", "lxTooltipIsHtmlContent"] }] }); }
|
2681
|
+
}
|
2682
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: AvatarComponent, decorators: [{
|
2683
|
+
type: Component,
|
2684
|
+
args: [{ selector: 'lx-avatar', standalone: true, imports: [NgIf, AsyncPipe, NgClass, TooltipDirective], template: "<ng-container *ngIf=\"imageURL | async; else loading\">\n <ng-container *ngIf=\"!user.technicalUser; else technicalUserIcon\">\n <a\n *ngIf=\"showMailToLink && user.email; else profilePicture\"\n class=\"userLink\"\n href=\"mailto:{{ user.email }}\"\n lxTooltip=\"{{ user.displayName }}\"\n >\n <img\n [src]=\"imageURL | async\"\n class=\"avatarImage\"\n [class]=\"size\"\n [class.disabled]=\"disabled\"\n role=\"presentation\"\n alt=\"{{ user.displayName }}\"\n />\n </a>\n <ng-template #profilePicture>\n <img\n [src]=\"imageURL | async\"\n class=\"avatarImage\"\n [class]=\"size\"\n [class.disabled]=\"disabled\"\n role=\"presentation\"\n alt=\"{{ user.displayName }}\"\n />\n </ng-template>\n </ng-container>\n <ng-template #technicalUserIcon>\n <i class=\"avatarImage fas fa-robot\" lxTooltip=\"{{ user.displayName }}\" [class]=\"size\" [class.disabled]=\"disabled\"></i>\n </ng-template>\n</ng-container>\n<ng-template #loading>\n <div class=\"avatarImage userLink loading\" [ngClass]=\"size\"></div>\n</ng-template>\n", styles: [".userLink{display:inline-block;width:fit-content;height:fit-content}.avatarImage{border-radius:50%}.avatarImage.disabled{opacity:.4}.loading{background:linear-gradient(270deg,#ccc,#eee,#ccc);background-size:200% 100%;animation:loading 1.5s infinite;object-fit:cover;vertical-align:middle}@keyframes loading{0%{background-position:200% 0}to{background-position:-200% 0}}.fa-robot{background-color:#b2bccc;color:#fff;vertical-align:middle;text-align:center}.fa-robot.XS{line-height:14px;font-size:10px}.fa-robot.S{line-height:22px;font-size:13px}.fa-robot.M{line-height:30px;font-size:18px}.fa-robot.L{line-height:38px;font-size:22px}.fa-robot.XL{line-height:62px;font-size:40px}.XS{width:16px;height:16px}.S{width:24px;height:24px}.M{width:32px;height:32px}.L{width:40px;height:40px}.XL{width:64px;height:64px}\n"] }]
|
2685
|
+
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
2686
|
+
type: Inject,
|
2687
|
+
args: [IMAGE_READER]
|
2688
|
+
}] }], propDecorators: { user: [{
|
2689
|
+
type: Input
|
2690
|
+
}], size: [{
|
2691
|
+
type: Input
|
2692
|
+
}], showMailToLink: [{
|
2693
|
+
type: Input
|
2694
|
+
}], disabled: [{
|
2695
|
+
type: Input
|
2696
|
+
}] } });
|
2697
|
+
|
2698
|
+
class AvatarGroupComponent {
|
2699
|
+
get userNames() {
|
2700
|
+
return this.users
|
2701
|
+
.map(({ displayName }) => displayName)
|
2702
|
+
.sort()
|
2703
|
+
.join('<br>');
|
2704
|
+
}
|
2705
|
+
constructor(cdr, zone) {
|
2706
|
+
this.cdr = cdr;
|
2707
|
+
this.zone = zone;
|
2708
|
+
this.NAME = 'AvatarGroupComponent';
|
2709
|
+
this.users = [];
|
2710
|
+
this.size = 'M';
|
2711
|
+
this.type = 'group';
|
2712
|
+
this.maxLength = 0;
|
2713
|
+
this.autoScale = false;
|
2714
|
+
this.disabledUserIds = [];
|
2715
|
+
this.overlayVisible = false;
|
2716
|
+
this.resizeObserver = new ResizeObserver(() => {
|
2717
|
+
this.zone.runOutsideAngular(() => {
|
2718
|
+
this.zone.run(() => {
|
2719
|
+
this.cdr.detectChanges();
|
2720
|
+
});
|
2721
|
+
});
|
2722
|
+
});
|
2723
|
+
}
|
2724
|
+
ngAfterViewInit() {
|
2725
|
+
this.resizeObserver.observe(this.userGroupElement.nativeElement);
|
2726
|
+
}
|
2727
|
+
handleClick(event) {
|
2728
|
+
event.stopPropagation();
|
2729
|
+
this.overlayVisible = true;
|
2730
|
+
}
|
2731
|
+
ngOnDestroy() {
|
2732
|
+
if (this.resizeObserver && this.userGroupElement) {
|
2733
|
+
this.resizeObserver.unobserve(this.userGroupElement.nativeElement);
|
2734
|
+
}
|
2735
|
+
}
|
2736
|
+
isUserDisabled(user) {
|
2737
|
+
return !!user.id && this.disabledUserIds.includes(user.id);
|
2738
|
+
}
|
2739
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: AvatarGroupComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
|
2740
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.8", type: AvatarGroupComponent, isStandalone: true, selector: "lx-avatar-group", inputs: { title: "title", users: "users", size: "size", type: "type", maxLength: "maxLength", autoScale: "autoScale", disabledUserIds: "disabledUserIds" }, viewQueries: [{ propertyName: "userGroupElement", first: true, predicate: ["userGroup"], descendants: true }], ngImport: i0, template: "<div\n #userGroup\n (click)=\"handleClick($event)\"\n (keydown.enter)=\"handleClick($event)\"\n (keydown.space)=\"handleClick($event)\"\n cdkOverlayOrigin\n #trigger=\"cdkOverlayOrigin\"\n [lxTooltip]=\"!overlayVisible ? userNames : null\"\n [lxTooltipIsHtmlContent]=\"true\"\n tabindex=\"0\"\n role=\"button\"\n aria-haspopup=\"dialog\"\n>\n <div *ngIf=\"users | displayAvatars: type : size : userGroup.offsetWidth : autoScale : maxLength as filteredUsers\" class=\"group-container\">\n <lx-avatar\n [user]=\"user\"\n [size]=\"size\"\n [showMailToLink]=\"false\"\n [disabled]=\"isUserDisabled(user)\"\n [ngClass]=\"[type === 'individual' ? 'individual' : 'group', size]\"\n *ngFor=\"let user of filteredUsers\"\n />\n <div\n *ngIf=\"filteredUsers.length < users.length\"\n [ngClass]=\"[type === 'individual' ? 'individual' : 'group', size]\"\n class=\"more-users-icon\"\n >\n +{{ users.length - filteredUsers.length }}\n </div>\n </div>\n</div>\n\n<ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"overlayVisible\"\n (overlayOutsideClick)=\"overlayVisible = false\"\n>\n <div class=\"avatars-overlay\">\n <div *ngIf=\"title\" class=\"avatars-overlay-title\">{{ title }}</div>\n <div class=\"avatars-list\">\n <div *ngFor=\"let user of users\" class=\"individual\">\n <lx-avatar [user]=\"user\" [size]=\"size\" [showMailToLink]=\"true\" [disabled]=\"isUserDisabled(user)\" />\n </div>\n </div>\n </div>\n</ng-template>\n", styles: [".group-container{display:flex;align-items:center}.group-container lx-avatar{display:flex;align-items:center}.group-container .more-users-icon{color:#61779d;background-color:#fff;border:1px solid #c2c9d6;border-radius:50%;font-weight:700;-webkit-user-select:none;user-select:none}.individual{margin-right:2px!important}.avatars-overlay{max-width:360px;overflow:auto;margin-top:5px;border-radius:10px;background-color:#fff;border:1px solid #c2c9d6;box-shadow:0 6px 12px #0000002d}.avatars-overlay .avatars-list{display:flex;flex-wrap:wrap;padding:10px}.avatars-overlay .avatars-list lx-avatar{display:block;margin-bottom:5px}.avatars-overlay .avatars-overlay-title{border-bottom:1px solid #c2c9d6;padding:10px;font-weight:700}.XS{width:16px;height:16px;line-height:16px;font-size:8px}.XS.group:not(:first-child){margin-left:-8px}.S{width:24px;height:24px;line-height:24px;font-size:11.25px}.S.group:not(:first-child){margin-left:-12px}.M{width:32px;height:32px;line-height:32px;text-align:center;vertical-align:middle;font-size:15.5px}.M.group:not(:first-child){margin-left:-10px}.L{width:40px;height:40px;line-height:40px;text-align:center;vertical-align:middle;font-size:large}.L.group:not(:first-child){margin-left:-20px}.XL{width:64px;height:64px;line-height:64px;text-align:center;vertical-align:middle;font-size:large}.XL.group:not(:first-child){margin-left:-50px}\n"], dependencies: [{ kind: "directive", type: CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "directive", type: TooltipDirective, selector: "[lxTooltip]", inputs: ["lxTooltip", "lxTooltipPosition", "lxTooltipDelay", "lxTooltipIsHtmlContent"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: AvatarComponent, selector: "lx-avatar", inputs: ["user", "size", "showMailToLink", "disabled"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "pipe", type: DisplayAvatarsPipe, name: "displayAvatars" }] }); }
|
2741
|
+
}
|
2742
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: AvatarGroupComponent, decorators: [{
|
2743
|
+
type: Component,
|
2744
|
+
args: [{ selector: 'lx-avatar-group', standalone: true, imports: [CdkOverlayOrigin, TooltipDirective, NgIf, NgFor, AvatarComponent, NgClass, CdkConnectedOverlay, DisplayAvatarsPipe], template: "<div\n #userGroup\n (click)=\"handleClick($event)\"\n (keydown.enter)=\"handleClick($event)\"\n (keydown.space)=\"handleClick($event)\"\n cdkOverlayOrigin\n #trigger=\"cdkOverlayOrigin\"\n [lxTooltip]=\"!overlayVisible ? userNames : null\"\n [lxTooltipIsHtmlContent]=\"true\"\n tabindex=\"0\"\n role=\"button\"\n aria-haspopup=\"dialog\"\n>\n <div *ngIf=\"users | displayAvatars: type : size : userGroup.offsetWidth : autoScale : maxLength as filteredUsers\" class=\"group-container\">\n <lx-avatar\n [user]=\"user\"\n [size]=\"size\"\n [showMailToLink]=\"false\"\n [disabled]=\"isUserDisabled(user)\"\n [ngClass]=\"[type === 'individual' ? 'individual' : 'group', size]\"\n *ngFor=\"let user of filteredUsers\"\n />\n <div\n *ngIf=\"filteredUsers.length < users.length\"\n [ngClass]=\"[type === 'individual' ? 'individual' : 'group', size]\"\n class=\"more-users-icon\"\n >\n +{{ users.length - filteredUsers.length }}\n </div>\n </div>\n</div>\n\n<ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"overlayVisible\"\n (overlayOutsideClick)=\"overlayVisible = false\"\n>\n <div class=\"avatars-overlay\">\n <div *ngIf=\"title\" class=\"avatars-overlay-title\">{{ title }}</div>\n <div class=\"avatars-list\">\n <div *ngFor=\"let user of users\" class=\"individual\">\n <lx-avatar [user]=\"user\" [size]=\"size\" [showMailToLink]=\"true\" [disabled]=\"isUserDisabled(user)\" />\n </div>\n </div>\n </div>\n</ng-template>\n", styles: [".group-container{display:flex;align-items:center}.group-container lx-avatar{display:flex;align-items:center}.group-container .more-users-icon{color:#61779d;background-color:#fff;border:1px solid #c2c9d6;border-radius:50%;font-weight:700;-webkit-user-select:none;user-select:none}.individual{margin-right:2px!important}.avatars-overlay{max-width:360px;overflow:auto;margin-top:5px;border-radius:10px;background-color:#fff;border:1px solid #c2c9d6;box-shadow:0 6px 12px #0000002d}.avatars-overlay .avatars-list{display:flex;flex-wrap:wrap;padding:10px}.avatars-overlay .avatars-list lx-avatar{display:block;margin-bottom:5px}.avatars-overlay .avatars-overlay-title{border-bottom:1px solid #c2c9d6;padding:10px;font-weight:700}.XS{width:16px;height:16px;line-height:16px;font-size:8px}.XS.group:not(:first-child){margin-left:-8px}.S{width:24px;height:24px;line-height:24px;font-size:11.25px}.S.group:not(:first-child){margin-left:-12px}.M{width:32px;height:32px;line-height:32px;text-align:center;vertical-align:middle;font-size:15.5px}.M.group:not(:first-child){margin-left:-10px}.L{width:40px;height:40px;line-height:40px;text-align:center;vertical-align:middle;font-size:large}.L.group:not(:first-child){margin-left:-20px}.XL{width:64px;height:64px;line-height:64px;text-align:center;vertical-align:middle;font-size:large}.XL.group:not(:first-child){margin-left:-50px}\n"] }]
|
2745
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i0.NgZone }], propDecorators: { title: [{
|
2746
|
+
type: Input
|
2747
|
+
}], users: [{
|
2748
|
+
type: Input
|
2749
|
+
}], size: [{
|
2750
|
+
type: Input
|
2751
|
+
}], type: [{
|
2752
|
+
type: Input
|
2753
|
+
}], maxLength: [{
|
2754
|
+
type: Input
|
2755
|
+
}], autoScale: [{
|
2756
|
+
type: Input
|
2757
|
+
}], disabledUserIds: [{
|
2758
|
+
type: Input
|
2759
|
+
}], userGroupElement: [{
|
2760
|
+
type: ViewChild,
|
2761
|
+
args: ['userGroup']
|
2762
|
+
}] } });
|
2763
|
+
|
2596
2764
|
/**
|
2597
2765
|
* Skeleton is a component that can be used to show a loading state of a component.
|
2598
2766
|
*
|
@@ -2827,6 +2995,54 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImpor
|
|
2827
2995
|
args: [SatPopoverComponent]
|
2828
2996
|
}] } });
|
2829
2997
|
|
2998
|
+
/**
|
2999
|
+
* Generates an SVG for the avatar initials
|
3000
|
+
* @param displayName The name of the user
|
3001
|
+
* @param size The size of the avatar
|
3002
|
+
* @returns A promise with the data URL of the generated SVG
|
3003
|
+
*/
|
3004
|
+
function getInitialsUrl(displayName, size) {
|
3005
|
+
const twoWordsName = displayName.split(' ').slice(0, 2);
|
3006
|
+
const initials = twoWordsName.length === 1 ? `${twoWordsName[0]?.[0]}` : `${twoWordsName[0]?.[0]}${twoWordsName[1]?.[0]}`;
|
3007
|
+
const svg = generateInitialsSVG(initials.toUpperCase(), size && AVATAR_SIZE_MAPPING[size]);
|
3008
|
+
const blob = new Blob([svg], { type: 'image/svg+xml' });
|
3009
|
+
return blobToDataURL(blob);
|
3010
|
+
}
|
3011
|
+
function hashString(s) {
|
3012
|
+
let hash = 0;
|
3013
|
+
let i = 0;
|
3014
|
+
const l = s.length;
|
3015
|
+
if (l > 0)
|
3016
|
+
while (i < l)
|
3017
|
+
hash = ((hash << 5) - hash + s.charCodeAt(i++)) | 0;
|
3018
|
+
return Math.abs(hash);
|
3019
|
+
}
|
3020
|
+
function getAvatarColorHex(initials) {
|
3021
|
+
const tagNameHash = hashString(initials.toUpperCase());
|
3022
|
+
return AVATAR_COLORS[(tagNameHash % 11) + 1];
|
3023
|
+
}
|
3024
|
+
function generateInitialsSVG(initials, size = 24) {
|
3025
|
+
const fontSize = (size * 40) / 100;
|
3026
|
+
const textY = (size * 63) / 100;
|
3027
|
+
const svgTemplate = `
|
3028
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${size} ${size}" width="${size}" height="${size}" preserveAspectRatio="xMidYMid meet">
|
3029
|
+
<circle cx="${size / 2}" cy="${size / 2}" r="${size / 2}" fill="${getAvatarColorHex(initials)}"></circle>
|
3030
|
+
<text x="${size / 2}" y="${textY}" font-family="Arial" font-size="${fontSize}" text-anchor="middle" fill="#ffffff" style="user-select:none;-webkit-user-select:none;-ms-user-select:none;-moz-user-select:none;">
|
3031
|
+
${initials}
|
3032
|
+
</text>
|
3033
|
+
</svg>`;
|
3034
|
+
return svgTemplate;
|
3035
|
+
}
|
3036
|
+
function blobToDataURL(blob) {
|
3037
|
+
return new Promise((resolve, reject) => {
|
3038
|
+
const reader = new FileReader();
|
3039
|
+
reader.onload = (_e) => resolve(reader.result);
|
3040
|
+
reader.onerror = (_e) => reject(reader.error);
|
3041
|
+
reader.onabort = (_e) => reject(new Error('Read aborted'));
|
3042
|
+
reader.readAsDataURL(blob);
|
3043
|
+
});
|
3044
|
+
}
|
3045
|
+
|
2830
3046
|
const defaultElement = 'span';
|
2831
3047
|
const defaultClassName = 'highlight';
|
2832
3048
|
/**
|
@@ -10135,5 +10351,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImpor
|
|
10135
10351
|
* Generated bundle index. Do not edit.
|
10136
10352
|
*/
|
10137
10353
|
|
10138
|
-
export { ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT, ARROW_UP, AfterViewInitDirective, AutocloseDirective, AutocloseGroupService, AutofocusDirective, BACKSPACE, BadgeComponent, BannerComponent, BaseSelectDirective, BasicDropdownComponent, BasicDropdownItemComponent, BrPipe, BreadcrumbComponent, ButtonComponent, ButtonGroupComponent, CORE_MODULE_EXPORTS, CURRENCY_SYMBOL_MAP, CardComponent, CdkOptionsDropdownComponent, CdkOptionsSubDropdownComponent, CollapsibleComponent, ContenteditableDirective, ContrastColorPipe, CounterComponent, CurrencyInputComponent, CurrencySymbolComponent, CustomDatePipe, DATEPICKER_CONTROL_VALUE_ACCESSOR, DATE_FN_LOCALE, DATE_FORMATS, DateFormatter, DateInputComponent, DatePickerComponent, DatepickerConfig, DatepickerUiModule, DragAndDropListComponent, DragAndDropListItemComponent, END, ENTER, ESCAPE, EllipsisComponent, EmptyStateComponent, ErrorMessageComponent, ExpandedDropdownComponent, FORMS_MODULE_EXPORTS, FORM_CONTROL_ERROR_DISPLAY_STRATEGY, FORM_CONTROL_ERROR_NAMESPACE, FilterSelectionPipe, FilterTermPipe, FormErrorComponent, FormErrorDirective, FormSubmitDirective, FormatNumberPipe, GLOBAL_TRANSLATION_OPTIONS, HOME, HighlightRangePipe, HighlightTermPipe, ICON_MAP, IconComponent, IconScaleComponent, InputComponent, KeyboardActionSourceDirective, KeyboardSelectAction, KeyboardSelectDirective, LOCALE_FN, LX_BUTTON_USE_SAP_ICONS, LX_ELLIPSIS_DEBOUNCE_ON_RESIZE, LxCoreUiModule, LxDragAndDropListModule, LxFormsModule, LxIsUuidPipe, LxLinkifyPipe, LxModalModule, LxPopoverUiModule, LxTabUiModule, LxTimeAgo, LxTranslatePipe, LxUnlinkifyPipe, MODAL_CLOSE, MODAL_MODULE_EXPORTS, MarkInvalidDirective, MarkdownPipe, MaxLengthCounterDirective, ModalCloseClickLocation, ModalComponent, ModalContentDirective, ModalFooterComponent, ModalHeaderComponent, MultiSelectComponent, NbspPipe, OptionComponent, OptionGroupComponent, OptionGroupDropdownComponent, OptionsDropdownComponent, OptionsSubDropdownComponent, PickerComponent, PickerOptionComponent, PickerTriggerDirective, PillItemComponent, PillListComponent, PopoverClickDirective, PopoverComponent, PopoverContentDirective, PopoverHoverDirective, RELEVANCE_SORTING_KEY, ResizeObserverService, ResponsiveInputComponent, SPACE, SelectDropdownDirective, SelectListComponent, SelectableItemDirective, SelectedOptionDirective, SingleSelectComponent, SkeletonComponent, SortPipe, Sorting, SortingDropdownComponent, SortingDropdownTriggerComponent, SpinnerComponent, StepperComponent, SwitchComponent, TAB, TabComponent, TabGroupComponent, TableComponent, TableHeaderComponent, TinySpinnerComponent, TokenComponent, TokenizerComponent, TokenizerOverflowPopoverComponent, TooltipComponent, TooltipDirective, TranslationAfterPipe, TranslationBeforePipe, TranslationBetweenPipe, UnescapeCurlyBracesPipe, ValidateDateInForeseeableFuture, ValidateStringNotInArray, ValidateStringNotInArrayAsync, getContrastColor, getTranslationParts, highlightText, isValidHexColor, isValidX, isValidY, provideFormControlErrorDisplayStrategy, provideFormControlErrorNamespace, shorthandHexHandle };
|
10354
|
+
export { ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT, ARROW_UP, AVATAR_COLORS, AVATAR_SIZE_MAPPING, AfterViewInitDirective, AutocloseDirective, AutocloseGroupService, AutofocusDirective, AvatarComponent, AvatarGroupComponent, BACKSPACE, BadgeComponent, BannerComponent, BaseSelectDirective, BasicDropdownComponent, BasicDropdownItemComponent, BrPipe, BreadcrumbComponent, ButtonComponent, ButtonGroupComponent, CORE_MODULE_EXPORTS, CURRENCY_SYMBOL_MAP, CardComponent, CdkOptionsDropdownComponent, CdkOptionsSubDropdownComponent, CollapsibleComponent, ContenteditableDirective, ContrastColorPipe, CounterComponent, CurrencyInputComponent, CurrencySymbolComponent, CustomDatePipe, DATEPICKER_CONTROL_VALUE_ACCESSOR, DATE_FN_LOCALE, DATE_FORMATS, DEFAULT_IMAGE_ID, DateFormatter, DateInputComponent, DatePickerComponent, DatepickerConfig, DatepickerUiModule, DragAndDropListComponent, DragAndDropListItemComponent, END, ENTER, ESCAPE, EllipsisComponent, EmptyStateComponent, ErrorMessageComponent, ExpandedDropdownComponent, FORMS_MODULE_EXPORTS, FORM_CONTROL_ERROR_DISPLAY_STRATEGY, FORM_CONTROL_ERROR_NAMESPACE, FilterSelectionPipe, FilterTermPipe, FormErrorComponent, FormErrorDirective, FormSubmitDirective, FormatNumberPipe, GLOBAL_TRANSLATION_OPTIONS, HOME, HighlightRangePipe, HighlightTermPipe, ICON_MAP, IMAGE_READER, IconComponent, IconScaleComponent, InputComponent, KeyboardActionSourceDirective, KeyboardSelectAction, KeyboardSelectDirective, LOCALE_FN, LX_BUTTON_USE_SAP_ICONS, LX_ELLIPSIS_DEBOUNCE_ON_RESIZE, LxCoreUiModule, LxDragAndDropListModule, LxFormsModule, LxIsUuidPipe, LxLinkifyPipe, LxModalModule, LxPopoverUiModule, LxTabUiModule, LxTimeAgo, LxTranslatePipe, LxUnlinkifyPipe, MODAL_CLOSE, MODAL_MODULE_EXPORTS, MarkInvalidDirective, MarkdownPipe, MaxLengthCounterDirective, ModalCloseClickLocation, ModalComponent, ModalContentDirective, ModalFooterComponent, ModalHeaderComponent, MultiSelectComponent, NbspPipe, OptionComponent, OptionGroupComponent, OptionGroupDropdownComponent, OptionsDropdownComponent, OptionsSubDropdownComponent, PickerComponent, PickerOptionComponent, PickerTriggerDirective, PillItemComponent, PillListComponent, PopoverClickDirective, PopoverComponent, PopoverContentDirective, PopoverHoverDirective, RELEVANCE_SORTING_KEY, ResizeObserverService, ResponsiveInputComponent, SPACE, SelectDropdownDirective, SelectListComponent, SelectableItemDirective, SelectedOptionDirective, SingleSelectComponent, SkeletonComponent, SortPipe, Sorting, SortingDropdownComponent, SortingDropdownTriggerComponent, SpinnerComponent, StepperComponent, SwitchComponent, TAB, TabComponent, TabGroupComponent, TableComponent, TableHeaderComponent, TinySpinnerComponent, TokenComponent, TokenizerComponent, TokenizerOverflowPopoverComponent, TooltipComponent, TooltipDirective, TranslationAfterPipe, TranslationBeforePipe, TranslationBetweenPipe, UnescapeCurlyBracesPipe, ValidateDateInForeseeableFuture, ValidateStringNotInArray, ValidateStringNotInArrayAsync, getContrastColor, getInitialsUrl, getTranslationParts, highlightText, isValidHexColor, isValidX, isValidY, provideFormControlErrorDisplayStrategy, provideFormControlErrorNamespace, shorthandHexHandle };
|
10139
10355
|
//# sourceMappingURL=leanix-components.mjs.map
|