mirror of
https://github.com/bitwarden/clients.git
synced 2025-12-10 00:08:42 -06:00
[PM-25037] add optional size input to app-vault-icon to prevent zoom issues (#17640)
This commit is contained in:
parent
ee582b2ebe
commit
5dbcb18b6a
@ -45,7 +45,11 @@
|
||||
tabindex="0"
|
||||
[attr.aria-label]="'viewItem' | i18n"
|
||||
>
|
||||
<app-vault-icon *ngIf="row.iconCipher" [cipher]="row.iconCipher"></app-vault-icon>
|
||||
<app-vault-icon
|
||||
*ngIf="row.iconCipher"
|
||||
[cipher]="row.iconCipher"
|
||||
[size]="24"
|
||||
></app-vault-icon>
|
||||
</td>
|
||||
<td
|
||||
class="tw-cursor-pointer"
|
||||
|
||||
@ -1,9 +1,5 @@
|
||||
<!-- Applying width and height styles directly to synchronize icon sizing between web/browser/desktop -->
|
||||
<div
|
||||
class="tw-flex tw-justify-center tw-items-center"
|
||||
[ngStyle]="coloredIcon() ? { width: '36px', height: '36px' } : {}"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div class="tw-flex tw-justify-center tw-items-center" [ngStyle]="iconStyle()" aria-hidden="true">
|
||||
<ng-container *ngIf="data$ | async as data">
|
||||
@if (data.imageEnabled && data.image) {
|
||||
<img
|
||||
@ -16,7 +12,7 @@
|
||||
'tw-invisible tw-absolute': !imageLoaded(),
|
||||
'tw-size-6': !coloredIcon(),
|
||||
}"
|
||||
[ngStyle]="coloredIcon() ? { width: '36px', height: '36px' } : {}"
|
||||
[ngStyle]="iconStyle()"
|
||||
(load)="imageLoaded.set(true)"
|
||||
(error)="imageLoaded.set(false)"
|
||||
/>
|
||||
@ -28,7 +24,7 @@
|
||||
'tw-bg-illustration-bg-primary tw-rounded-full':
|
||||
data.icon?.startsWith('bwi-') && coloredIcon(),
|
||||
}"
|
||||
[ngStyle]="coloredIcon() ? { width: '36px', height: '36px' } : {}"
|
||||
[ngStyle]="iconStyle()"
|
||||
>
|
||||
<i
|
||||
class="tw-text-muted bwi bwi-lg {{ data.icon }}"
|
||||
@ -36,6 +32,7 @@
|
||||
color: coloredIcon() ? 'rgb(var(--color-illustration-outline))' : null,
|
||||
width: data.icon?.startsWith('credit-card') && coloredIcon() ? '36px' : null,
|
||||
height: data.icon?.startsWith('credit-card') && coloredIcon() ? '30px' : null,
|
||||
fontSize: size() ? size() + 'px' : null,
|
||||
}"
|
||||
></i>
|
||||
</div>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ChangeDetectionStrategy, Component, input, signal } from "@angular/core";
|
||||
import { ChangeDetectionStrategy, Component, computed, input, signal } from "@angular/core";
|
||||
import { toObservable } from "@angular/core/rxjs-interop";
|
||||
import {
|
||||
combineLatest,
|
||||
@ -32,8 +32,32 @@ export class IconComponent {
|
||||
*/
|
||||
readonly coloredIcon = input<boolean>(false);
|
||||
|
||||
/**
|
||||
* Optional custom size for the icon in pixels.
|
||||
* When provided, forces explicit dimensions on the icon wrapper to prevent layout collapse at different zoom levels.
|
||||
* If not provided, the wrapper has no explicit dimensions and relies on CSS classes (tw-size-6/24px for images).
|
||||
* This can cause the wrapper to collapse when images are loading/hidden, especially at high browser zoom levels.
|
||||
* Reference: default image size is tw-size-6 (24px), coloredIcon uses 36px.
|
||||
*/
|
||||
readonly size = input<number>();
|
||||
|
||||
readonly imageLoaded = signal(false);
|
||||
|
||||
/**
|
||||
* Computed style object for icon dimensions.
|
||||
* Centralizes the sizing logic to avoid repetition in the template.
|
||||
*/
|
||||
protected readonly iconStyle = computed(() => {
|
||||
if (this.coloredIcon()) {
|
||||
return { width: "36px", height: "36px" };
|
||||
}
|
||||
const size = this.size();
|
||||
if (size) {
|
||||
return { width: size + "px", height: size + "px" };
|
||||
}
|
||||
return {};
|
||||
});
|
||||
|
||||
protected data$: Observable<CipherIconDetails>;
|
||||
|
||||
constructor(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user