diff --git a/libs/auth/src/angular/anon-layout/anon-layout.component.html b/libs/auth/src/angular/anon-layout/anon-layout.component.html new file mode 100644 index 0000000000..1f583edf20 --- /dev/null +++ b/libs/auth/src/angular/anon-layout/anon-layout.component.html @@ -0,0 +1,26 @@ +
+
+
+
+ +
+ +
+

+ {{ title }} +

+

{{ subtitle }}

+
+
+
+ +
+ +
+ +
diff --git a/libs/auth/src/angular/anon-layout/anon-layout.component.ts b/libs/auth/src/angular/anon-layout/anon-layout.component.ts new file mode 100644 index 0000000000..d247a010bf --- /dev/null +++ b/libs/auth/src/angular/anon-layout/anon-layout.component.ts @@ -0,0 +1,31 @@ +import { CommonModule } from "@angular/common"; +import { Component, Input } from "@angular/core"; + +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; + +import { IconModule, Icon } from "../../../../components/src/icon"; +import { TypographyModule } from "../../../../components/src/typography"; +import { BitwardenLogo } from "../../icons/bitwarden-logo"; + +@Component({ + standalone: true, + selector: "auth-anon-layout", + templateUrl: "./anon-layout.component.html", + imports: [IconModule, CommonModule, TypographyModule], +}) +export class AnonLayoutComponent { + @Input() title: string; + @Input() subtitle: string; + @Input() icon: Icon; + + protected logo = BitwardenLogo; + protected version: string; + protected year = "2024"; + + constructor(private platformUtilsService: PlatformUtilsService) {} + + async ngOnInit() { + this.year = new Date().getFullYear().toString(); + this.version = await this.platformUtilsService.getApplicationVersion(); + } +} diff --git a/libs/auth/src/angular/anon-layout/anon-layout.stories.ts b/libs/auth/src/angular/anon-layout/anon-layout.stories.ts new file mode 100644 index 0000000000..daba5b5e53 --- /dev/null +++ b/libs/auth/src/angular/anon-layout/anon-layout.stories.ts @@ -0,0 +1,107 @@ +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; + +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; + +import { ButtonModule } from "../../../../components/src/button"; +import { IconLock } from "../../icons/icon-lock"; + +import { AnonLayoutComponent } from "./anon-layout.component"; + +class MockPlatformUtilsService implements Partial { + getApplicationVersion = () => Promise.resolve("Version 2023.1.1"); +} + +export default { + title: "Auth/Anon Layout", + component: AnonLayoutComponent, + decorators: [ + moduleMetadata({ + imports: [ButtonModule], + providers: [ + { + provide: PlatformUtilsService, + useClass: MockPlatformUtilsService, + }, + ], + }), + ], + args: { + title: "The Page Title", + subtitle: "The subtitle (optional)", + icon: IconLock, + }, +} as Meta; + +type Story = StoryObj; + +export const WithPrimaryContent: Story = { + render: (args) => ({ + props: args, + template: + /** + * The projected content (i.e. the
) and styling below is just a + * sample and could be replaced with any content and styling + */ + ` + +
Primary Projected Content Area (customizable)
+
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?
+
+ `, + }), +}; + +export const WithSecondaryContent: Story = { + render: (args) => ({ + props: args, + template: + // Notice that slot="secondary" is requred to project any secondary content: + ` + +
+
Primary Projected Content Area (customizable)
+
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?
+
+ +
+
Secondary Projected Content (optional)
+ +
+
+ `, + }), +}; + +export const WithLongContent: Story = { + render: (args) => ({ + props: args, + template: ` + +
+
Primary Projected Content Area (customizable)
+
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.
+
+ +
+
Secondary Projected Content (optional)
+

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?

+ +
+
+ `, + }), +}; + +export const WithIcon: Story = { + render: (args) => ({ + props: args, + template: ` + +
+
Primary Projected Content Area (customizable)
+
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?
+
+
+ `, + }), +}; diff --git a/libs/auth/src/icons/bitwarden-logo.ts b/libs/auth/src/icons/bitwarden-logo.ts new file mode 100644 index 0000000000..90591e0fe7 --- /dev/null +++ b/libs/auth/src/icons/bitwarden-logo.ts @@ -0,0 +1,9 @@ +import { svgIcon } from "@bitwarden/components"; + +export const BitwardenLogo = svgIcon` + + Bitwarden + + + +`; diff --git a/libs/auth/src/icons/icon-lock.ts b/libs/auth/src/icons/icon-lock.ts new file mode 100644 index 0000000000..b56c1ea36d --- /dev/null +++ b/libs/auth/src/icons/icon-lock.ts @@ -0,0 +1,7 @@ +import { svgIcon } from "@bitwarden/components"; + +export const IconLock = svgIcon` + + + +`; diff --git a/libs/components/tailwind.config.base.js b/libs/components/tailwind.config.base.js index 9d22588fb4..5f49c6fc26 100644 --- a/libs/components/tailwind.config.base.js +++ b/libs/components/tailwind.config.base.js @@ -8,7 +8,11 @@ function rgba(color) { module.exports = { prefix: "tw-", - content: ["./src/**/*.{html,ts}", "../../libs/components/src/**/*.{html,ts}"], + content: [ + "./src/**/*.{html,ts}", + "../../libs/components/src/**/*.{html,ts}", + "../../libs/auth/src/**/*.{html,ts}", + ], safelist: [], corePlugins: { preflight: false }, theme: {