1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-14 15:23:33 +00:00

[PM-8307] AnonLayout Design Changes (#10166)

* update logo, padding, and add hideFooter property and hideLogo input

* typography and icon adjustments

* add story with hidden logo input

* handle updating the icon

* update storybook docs

* update border radius

* update icon colors to use tw classes

* update storybook docs

* handle default icon

* make hideFooter an input

* update icon sizing

* update icon sizing
This commit is contained in:
rr-bw
2024-07-30 13:48:51 -05:00
committed by GitHub
parent d915bd8c86
commit 18ef51449f
6 changed files with 106 additions and 21 deletions

View File

@@ -1,35 +1,37 @@
<main
class="tw-flex tw-min-h-screen tw-w-full tw-mx-auto tw-flex-col tw-gap-9 tw-bg-background-alt tw-px-4 tw-pb-4 tw-pt-14 tw-text-main"
class="tw-flex tw-min-h-screen tw-w-full tw-mx-auto tw-flex-col tw-gap-7 tw-bg-background-alt tw-px-8 tw-pb-4 tw-pt-8 tw-text-main"
>
<bit-icon *ngIf="!hideLogo" [icon]="logo" class="tw-max-w-36"></bit-icon>
<div class="tw-text-center">
<div class="tw-px-8">
<div *ngIf="icon" class="tw-mb-8">
<bit-icon [icon]="icon"></bit-icon>
</div>
<bit-icon [icon]="logo" class="tw-mx-auto tw-block tw-max-w-72 sm:tw-max-w-xs"></bit-icon>
<div class="tw-mx-auto tw-max-w-28 sm:tw-max-w-32">
<bit-icon [icon]="icon"></bit-icon>
</div>
<h1 *ngIf="title" bitTypography="h3" class="tw-mt-8 sm:tw-text-2xl">
<h1 *ngIf="title" bitTypography="h3" class="tw-mt-2 sm:tw-text-2xl">
{{ title }}
</h1>
<p *ngIf="subtitle" bitTypography="body1">{{ subtitle }}</p>
<div *ngIf="subtitle" class="tw-text-sm sm:tw-text-base">{{ subtitle }}</div>
</div>
<div
class="tw-mb-auto tw-w-full tw-max-w-md tw-mx-auto tw-flex tw-flex-col tw-items-center sm:tw-min-w-[28rem]"
[ngClass]="{ 'tw-max-w-md': maxWidth === 'md', 'tw-max-w-3xl': maxWidth === '3xl' }"
>
<div
class="tw-rounded-xl tw-mb-9 tw-mx-auto tw-w-full sm:tw-bg-background sm:tw-border sm:tw-border-solid sm:tw-border-secondary-300 sm:tw-p-8"
class="tw-rounded-2xl tw-mb-9 tw-mx-auto tw-w-full sm:tw-bg-background sm:tw-border sm:tw-border-solid sm:tw-border-secondary-300 sm:tw-p-8"
>
<ng-content></ng-content>
</div>
<ng-content select="[slot=secondary]"></ng-content>
</div>
<footer class="tw-text-center">
<footer *ngIf="!hideFooter" class="tw-text-center">
<div *ngIf="showReadonlyHostname">{{ "accessing" | i18n }} {{ hostname }}</div>
<ng-container *ngIf="!showReadonlyHostname">
<ng-content select="[slot=environment-selector]"></ng-content>
</ng-container>
<ng-container *ngIf="showYearAndVersion">
<ng-container *ngIf="!hideYearAndVersion">
<div>&copy; {{ year }} Bitwarden Inc.</div>
<div>{{ version }}</div>
</ng-container>

View File

@@ -1,5 +1,5 @@
import { CommonModule } from "@angular/common";
import { Component, Input } from "@angular/core";
import { Component, Input, OnChanges, OnInit, SimpleChanges } from "@angular/core";
import { firstValueFrom } from "rxjs";
import { ClientType } from "@bitwarden/common/enums";
@@ -10,7 +10,8 @@ import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-stat
import { IconModule, Icon } from "../../../../components/src/icon";
import { SharedModule } from "../../../../components/src/shared";
import { TypographyModule } from "../../../../components/src/typography";
import { BitwardenLogoPrimary, BitwardenLogoWhite } from "../icons/bitwarden-logo.icon";
import { BitwardenLogoPrimary, BitwardenLogoWhite } from "../icons";
import { BitwardenShieldPrimary, BitwardenShieldWhite } from "../icons/bitwarden-shield.icon";
@Component({
standalone: true,
@@ -18,11 +19,13 @@ import { BitwardenLogoPrimary, BitwardenLogoWhite } from "../icons/bitwarden-log
templateUrl: "./anon-layout.component.html",
imports: [IconModule, CommonModule, TypographyModule, SharedModule],
})
export class AnonLayoutComponent {
export class AnonLayoutComponent implements OnInit, OnChanges {
@Input() title: string;
@Input() subtitle: string;
@Input() icon: Icon;
@Input() showReadonlyHostname: boolean;
@Input() hideLogo: boolean = false;
@Input() hideFooter: boolean = false;
/**
* Max width of the layout content
*
@@ -38,7 +41,7 @@ export class AnonLayoutComponent {
protected version: string;
protected theme: string;
protected showYearAndVersion = true;
protected hideYearAndVersion = false;
constructor(
private environmentService: EnvironmentService,
@@ -47,13 +50,12 @@ export class AnonLayoutComponent {
) {
this.year = new Date().getFullYear().toString();
this.clientType = this.platformUtilsService.getClientType();
this.showYearAndVersion = this.clientType === ClientType.Web;
this.hideYearAndVersion = this.clientType !== ClientType.Web;
}
async ngOnInit() {
this.maxWidth = this.maxWidth ?? "md";
this.hostname = (await firstValueFrom(this.environmentService.environment$)).getHostname();
this.version = await this.platformUtilsService.getApplicationVersion();
this.theme = await firstValueFrom(this.themeStateService.selectedTheme$);
if (this.theme === "dark") {
@@ -61,5 +63,29 @@ export class AnonLayoutComponent {
} else {
this.logo = BitwardenLogoPrimary;
}
await this.updateIcon(this.theme);
this.hostname = (await firstValueFrom(this.environmentService.environment$)).getHostname();
this.version = await this.platformUtilsService.getApplicationVersion();
}
async ngOnChanges(changes: SimpleChanges) {
if (changes.icon) {
const theme = await firstValueFrom(this.themeStateService.selectedTheme$);
await this.updateIcon(theme);
}
}
private async updateIcon(theme: string) {
if (this.icon == null) {
if (theme === "dark") {
this.icon = BitwardenShieldWhite;
}
if (theme !== "dark") {
this.icon = BitwardenShieldPrimary;
}
}
}
}

View File

@@ -61,6 +61,7 @@ export default {
subtitle: "The subtitle (optional)",
showReadonlyHostname: true,
icon: LockIcon,
hideLogo: false,
},
} as Meta;
@@ -144,7 +145,7 @@ export const WithThinPrimaryContent: Story = {
}),
};
export const WithIcon: Story = {
export const WithCustomIcon: Story = {
render: (args) => ({
props: args,
template:
@@ -159,3 +160,35 @@ export const WithIcon: Story = {
`,
}),
};
export const HideLogo: Story = {
render: (args) => ({
props: args,
template:
// Projected content (the <div>) and styling is just a sample and can be replaced with any content/styling.
`
<auth-anon-layout [title]="title" [subtitle]="subtitle" [showReadonlyHostname]="showReadonlyHostname" [hideLogo]="true">
<div>
<div class="tw-font-bold">Primary Projected Content Area (customizable)</div>
<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Necessitatibus illum vero, placeat recusandae esse ratione eius minima veniam nemo, quas beatae! Impedit molestiae alias sapiente explicabo. Sapiente corporis ipsa numquam?</div>
</div>
</auth-anon-layout>
`,
}),
};
export const HideFooter: Story = {
render: (args) => ({
props: args,
template:
// Projected content (the <div>) and styling is just a sample and can be replaced with any content/styling.
`
<auth-anon-layout [title]="title" [subtitle]="subtitle" [showReadonlyHostname]="showReadonlyHostname" [hideFooter]="true">
<div>
<div class="tw-font-bold">Primary Projected Content Area (customizable)</div>
<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Necessitatibus illum vero, placeat recusandae esse ratione eius minima veniam nemo, quas beatae! Impedit molestiae alias sapiente explicabo. Sapiente corporis ipsa numquam?</div>
</div>
</auth-anon-layout>
`,
}),
};