mirror of
https://github.com/bitwarden/browser
synced 2025-12-06 00:13:28 +00:00
[CL-613] Support non-card primary content in anon-layout (#15273)
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
[maxWidth]="maxWidth"
|
||||
[hideFooter]="hideFooter"
|
||||
[hideIcon]="hideIcon"
|
||||
[hideCardWrapper]="hideCardWrapper"
|
||||
>
|
||||
<router-outlet></router-outlet>
|
||||
<router-outlet slot="secondary" name="secondary"></router-outlet>
|
||||
|
||||
@@ -60,6 +60,7 @@ export class ExtensionAnonLayoutWrapperComponent implements OnInit, OnDestroy {
|
||||
protected maxWidth: "md" | "3xl";
|
||||
protected hasLoggedInAccount: boolean = false;
|
||||
protected hideFooter: boolean;
|
||||
protected hideCardWrapper: boolean = false;
|
||||
|
||||
protected theme: string;
|
||||
protected logo = Icons.ExtensionBitwardenLogo;
|
||||
@@ -137,6 +138,10 @@ export class ExtensionAnonLayoutWrapperComponent implements OnInit, OnDestroy {
|
||||
if (firstChildRouteData["hideIcon"] !== undefined) {
|
||||
this.hideIcon = Boolean(firstChildRouteData["hideIcon"]);
|
||||
}
|
||||
|
||||
if (firstChildRouteData["hideCardWrapper"] !== undefined) {
|
||||
this.hideCardWrapper = Boolean(firstChildRouteData["hideCardWrapper"]);
|
||||
}
|
||||
}
|
||||
|
||||
private listenForServiceDataChanges() {
|
||||
@@ -177,6 +182,10 @@ export class ExtensionAnonLayoutWrapperComponent implements OnInit, OnDestroy {
|
||||
this.showReadonlyHostname = data.showReadonlyHostname;
|
||||
}
|
||||
|
||||
if (data.hideCardWrapper !== undefined) {
|
||||
this.hideCardWrapper = data.hideCardWrapper;
|
||||
}
|
||||
|
||||
if (data.showAcctSwitcher !== undefined) {
|
||||
this.showAcctSwitcher = data.showAcctSwitcher;
|
||||
}
|
||||
@@ -214,6 +223,7 @@ export class ExtensionAnonLayoutWrapperComponent implements OnInit, OnDestroy {
|
||||
this.showLogo = null;
|
||||
this.maxWidth = null;
|
||||
this.hideFooter = null;
|
||||
this.hideCardWrapper = null;
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
[showReadonlyHostname]="showReadonlyHostname"
|
||||
[maxWidth]="maxWidth"
|
||||
[titleAreaMaxWidth]="titleAreaMaxWidth"
|
||||
[hideCardWrapper]="hideCardWrapper"
|
||||
>
|
||||
<router-outlet></router-outlet>
|
||||
<router-outlet slot="secondary" name="secondary"></router-outlet>
|
||||
|
||||
@@ -41,6 +41,10 @@ export interface AnonLayoutWrapperData {
|
||||
* Optional flag to set the max-width of the title area. Defaults to null if not provided.
|
||||
*/
|
||||
titleAreaMaxWidth?: "md";
|
||||
/**
|
||||
* Hide the card that wraps the default content. Defaults to false.
|
||||
*/
|
||||
hideCardWrapper?: boolean;
|
||||
}
|
||||
|
||||
@Component({
|
||||
@@ -56,6 +60,7 @@ export class AnonLayoutWrapperComponent implements OnInit, OnDestroy {
|
||||
protected showReadonlyHostname: boolean;
|
||||
protected maxWidth: "md" | "3xl";
|
||||
protected titleAreaMaxWidth: "md";
|
||||
protected hideCardWrapper: boolean;
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
@@ -107,6 +112,7 @@ export class AnonLayoutWrapperComponent implements OnInit, OnDestroy {
|
||||
this.showReadonlyHostname = Boolean(firstChildRouteData["showReadonlyHostname"]);
|
||||
this.maxWidth = firstChildRouteData["maxWidth"];
|
||||
this.titleAreaMaxWidth = firstChildRouteData["titleAreaMaxWidth"];
|
||||
this.hideCardWrapper = Boolean(firstChildRouteData["hideCardWrapper"]);
|
||||
}
|
||||
|
||||
private listenForServiceDataChanges() {
|
||||
@@ -143,6 +149,10 @@ export class AnonLayoutWrapperComponent implements OnInit, OnDestroy {
|
||||
this.showReadonlyHostname = data.showReadonlyHostname;
|
||||
}
|
||||
|
||||
if (data.hideCardWrapper !== undefined) {
|
||||
this.hideCardWrapper = data.hideCardWrapper;
|
||||
}
|
||||
|
||||
// Manually fire change detection to avoid ExpressionChangedAfterItHasBeenCheckedError
|
||||
// when setting the page data from a service
|
||||
this.changeDetectorRef.detectChanges();
|
||||
@@ -165,6 +175,7 @@ export class AnonLayoutWrapperComponent implements OnInit, OnDestroy {
|
||||
this.showReadonlyHostname = null;
|
||||
this.maxWidth = null;
|
||||
this.titleAreaMaxWidth = null;
|
||||
this.hideCardWrapper = null;
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
|
||||
@@ -87,6 +87,7 @@ const decorators = (options: {
|
||||
appLogoLabel: "app logo label",
|
||||
finishCreatingYourAccountBySettingAPassword:
|
||||
"Finish creating your account by setting a password",
|
||||
enterpriseSingleSignOn: "Enterprise Single Sign-On",
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
@@ -39,11 +39,17 @@
|
||||
class="tw-grow 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-2xl tw-mb-6 sm:tw-mb-10 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>
|
||||
@if (hideCardWrapper) {
|
||||
<div class="tw-mb-6 sm:tw-mb-10">
|
||||
<ng-container *ngTemplateOutlet="defaultContent"></ng-container>
|
||||
</div>
|
||||
} @else {
|
||||
<div
|
||||
class="tw-rounded-2xl tw-mb-6 sm:tw-mb-10 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-container *ngTemplateOutlet="defaultContent"></ng-container>
|
||||
</div>
|
||||
}
|
||||
<ng-content select="[slot=secondary]"></ng-content>
|
||||
</div>
|
||||
|
||||
@@ -60,3 +66,7 @@
|
||||
</ng-container>
|
||||
</footer>
|
||||
</main>
|
||||
|
||||
<ng-template #defaultContent>
|
||||
<ng-content></ng-content>
|
||||
</ng-template>
|
||||
|
||||
@@ -33,6 +33,7 @@ export class AnonLayoutComponent implements OnInit, OnChanges {
|
||||
@Input() hideLogo: boolean = false;
|
||||
@Input() hideFooter: boolean = false;
|
||||
@Input() hideIcon: boolean = false;
|
||||
@Input() hideCardWrapper: boolean = false;
|
||||
|
||||
/**
|
||||
* Max width of the title area content
|
||||
|
||||
@@ -61,6 +61,7 @@ export default {
|
||||
showReadonlyHostname: true,
|
||||
icon: LockIcon,
|
||||
hideLogo: false,
|
||||
hideCardWrapper: false,
|
||||
},
|
||||
} as Meta;
|
||||
|
||||
@@ -95,7 +96,7 @@ export const WithSecondaryContent: Story = {
|
||||
<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>
|
||||
|
||||
<div slot="secondary" class="text-center">
|
||||
<div slot="secondary" class="tw-text-center">
|
||||
<div class="tw-font-bold tw-mb-2">Secondary Projected Content (optional)</div>
|
||||
<button bitButton>Perform Action</button>
|
||||
</div>
|
||||
@@ -116,7 +117,7 @@ export const WithLongContent: Story = {
|
||||
<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? Lorem ipsum dolor sit amet consectetur adipisicing elit. Lorem ipsum dolor sit amet consectetur adipisicing elit. Lorem ipsum dolor sit amet consectetur adipisicing elit. Lorem ipsum dolor sit amet consectetur adipisicing elit. Lorem ipsum dolor sit amet consectetur adipisicing elit. Lorem ipsum dolor sit amet consectetur adipisicing elit. Lorem ipsum dolor sit amet consectetur adipisicing elit. Lorem ipsum dolor sit amet consectetur adipisicing elit. Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
|
||||
</div>
|
||||
|
||||
<div slot="secondary" class="text-center">
|
||||
<div slot="secondary" class="tw-text-center">
|
||||
<div class="tw-font-bold tw-mb-2">Secondary Projected Content (optional)</div>
|
||||
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestias laborum nostrum natus. Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestias laborum nostrum natus. Expedita, quod est? </p>
|
||||
<button bitButton>Perform Action</button>
|
||||
@@ -133,9 +134,9 @@ export const WithThinPrimaryContent: Story = {
|
||||
// Projected content (the <div>'s) and styling is just a sample and can be replaced with any content/styling.
|
||||
`
|
||||
<auth-anon-layout [title]="title" [subtitle]="subtitle" [showReadonlyHostname]="showReadonlyHostname" [hideLogo]="hideLogo" >
|
||||
<div class="text-center">Lorem ipsum</div>
|
||||
<div class="tw-text-center">Lorem ipsum</div>
|
||||
|
||||
<div slot="secondary" class="text-center">
|
||||
<div slot="secondary" class="tw-text-center">
|
||||
<div class="tw-font-bold tw-mb-2">Secondary Projected Content (optional)</div>
|
||||
<button bitButton>Perform Action</button>
|
||||
</div>
|
||||
@@ -160,6 +161,27 @@ export const WithCustomIcon: Story = {
|
||||
}),
|
||||
};
|
||||
|
||||
export const HideCardWrapper: Story = {
|
||||
render: (args) => ({
|
||||
props: {
|
||||
...args,
|
||||
hideCardWrapper: true,
|
||||
},
|
||||
template: `
|
||||
<auth-anon-layout [title]="title" [subtitle]="subtitle" [showReadonlyHostname]="showReadonlyHostname" [hideLogo]="hideLogo" [hideCardWrapper]="hideCardWrapper">
|
||||
<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>
|
||||
<div slot="secondary" class="tw-text-center">
|
||||
<div class="tw-font-bold tw-mb-2">Secondary Projected Content (optional)</div>
|
||||
<button bitButton>Perform Action</button>
|
||||
</div>
|
||||
</auth-anon-layout>
|
||||
`,
|
||||
}),
|
||||
};
|
||||
|
||||
export const HideIcon: Story = {
|
||||
render: (args) => ({
|
||||
props: args,
|
||||
|
||||
Reference in New Issue
Block a user