mirror of
https://github.com/bitwarden/browser
synced 2025-12-16 08:13:42 +00:00
[CL-700] Move auth-owned layout components to UIF ownership (#15093)
This commit is contained in:
168
libs/components/src/anon-layout/anon-layout.mdx
Normal file
168
libs/components/src/anon-layout/anon-layout.mdx
Normal file
@@ -0,0 +1,168 @@
|
||||
import { Meta, Story, Controls } from "@storybook/addon-docs";
|
||||
|
||||
import * as stories from "./anon-layout.stories";
|
||||
|
||||
<Meta of={stories} />
|
||||
|
||||
# AnonLayout Component
|
||||
|
||||
The AnonLayoutComponent is to be used primarily for unauthenticated pages\*, where we don't know who
|
||||
the user is.
|
||||
|
||||
\*There will be a few exceptions to this—that is, AnonLayout will also be used for the Unlock
|
||||
and View Send pages.
|
||||
|
||||
---
|
||||
|
||||
### Incorrect Usage ❌
|
||||
|
||||
The AnonLayoutComponent is **not** to be implemented by every component that uses it in that
|
||||
component's template directly. For example, if you have a component template called
|
||||
`example.component.html`, and you want it to use the AnonLayoutComponent, you will **not** be
|
||||
writing:
|
||||
|
||||
```html
|
||||
<!-- File: example.component.html -->
|
||||
|
||||
<auth-anon-layout>
|
||||
<div>Example component content</div>
|
||||
</auth-anon-layout>
|
||||
```
|
||||
|
||||
### Correct Usage ✅
|
||||
|
||||
Instead the AnonLayoutComponent is implemented solely in the router via routable composition, which
|
||||
gives us the advantages of nested routes in Angular.
|
||||
|
||||
To allow for routable composition, Auth also provides an AnonLayout**Wrapper**Component which embeds
|
||||
the AnonLayoutComponent.
|
||||
|
||||
For clarity:
|
||||
|
||||
- AnonLayoutComponent = the base, Auth-owned library component - `<auth-anon-layout>`
|
||||
- AnonLayout**Wrapper**Component = the wrapper to be used in client routing modules
|
||||
|
||||
The AnonLayout**Wrapper**Component embeds the AnonLayoutComponent along with the router outlets:
|
||||
|
||||
```html
|
||||
<!-- File: anon-layout-wrapper.component.html -->
|
||||
|
||||
<auth-anon-layout
|
||||
[title]="pageTitle"
|
||||
[subtitle]="pageSubtitle"
|
||||
[icon]="pageIcon"
|
||||
[showReadonlyHostname]="showReadonlyHostname"
|
||||
>
|
||||
<router-outlet></router-outlet>
|
||||
<router-outlet slot="secondary" name="secondary"></router-outlet>
|
||||
<router-outlet slot="environment-selector" name="environment-selector"></router-outlet>
|
||||
</auth-anon-layout>
|
||||
```
|
||||
|
||||
To implement, the developer does not need to work with the base AnonLayoutComponent directly. The
|
||||
devoloper simply uses the AnonLayout**Wrapper**Component in `oss-routing.module.ts` (for Web, for
|
||||
example) to construct the page via routable composition:
|
||||
|
||||
```typescript
|
||||
// File: oss-routing.module.ts
|
||||
import { AnonLayoutWrapperComponent, AnonLayoutWrapperData, LockIcon } from "@bitwarden/auth/angular";
|
||||
|
||||
{
|
||||
path: "",
|
||||
component: AnonLayoutWrapperComponent, // Wrapper component
|
||||
children: [
|
||||
{
|
||||
path: "sample-route", // replace with your route
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
component: MyPrimaryComponent, // replace with your component
|
||||
},
|
||||
{
|
||||
path: "",
|
||||
component: MySecondaryComponent, // replace with your component (or remove this secondary outlet object entirely if not needed)
|
||||
outlet: "secondary",
|
||||
},
|
||||
],
|
||||
data: {
|
||||
pageTitle: "logIn", // example of a translation key from messages.json
|
||||
pageSubtitle: "loginWithMasterPassword", // example of a translation key from messages.json
|
||||
pageIcon: LockIcon, // example of an icon to pass in
|
||||
} satisfies AnonLayoutWrapperData,
|
||||
},
|
||||
],
|
||||
},
|
||||
```
|
||||
|
||||
(Notice that you can optionally add an `outlet: "secondary"` if you want to project secondary
|
||||
content below the primary content).
|
||||
|
||||
If the AnonLayout**Wrapper**Component is already being used in your client's routing module, then
|
||||
your work will be as simple as just adding another child route under the `children` array.
|
||||
|
||||
<br />
|
||||
|
||||
### Data Properties
|
||||
|
||||
Routes that use the AnonLayou**tWrapper**Component can take several unique data properties defined
|
||||
in the `AnonLayoutWrapperData` interface:
|
||||
|
||||
- For the `pageTitle` and `pageSubtitle` - pass in a translation key from `messages.json`.
|
||||
- For the `pageIcon` - import an icon (of type `Icon`) into the router file and use the icon
|
||||
directly.
|
||||
- `showReadonlyHostname` - set to `true` if you want to show the hostname in the footer (ex:
|
||||
"Accessing bitwarden.com")
|
||||
|
||||
All of these properties are optional.
|
||||
|
||||
```typescript
|
||||
import { AnonLayoutWrapperComponent, AnonLayoutWrapperData, LockIcon } from "@bitwarden/auth/angular";
|
||||
|
||||
{
|
||||
// ...
|
||||
data: {
|
||||
pageTitle: "logIn",
|
||||
pageSubtitle: "loginWithMasterPassword",
|
||||
pageIcon: LockIcon,
|
||||
showReadonlyHostname: true,
|
||||
} satisfies AnonLayoutWrapperData,
|
||||
}
|
||||
```
|
||||
|
||||
### Environment Selector
|
||||
|
||||
For some routes, you may want to display the environment selector in the footer of the
|
||||
AnonLayoutComponent. To do so, add the relevant environment selector (Web or Libs version, depending
|
||||
on your client) as a component with `outlet: "environment-selector"`.
|
||||
|
||||
```javascript
|
||||
// File: oss-routing.module.ts
|
||||
import { AnonLayoutWrapperComponent, AnonLayoutWrapperData, LockIcon } from "@bitwarden/auth/angular";
|
||||
import { EnvironmentSelectorComponent } from "./components/environment-selector/environment-selector.component";
|
||||
|
||||
{
|
||||
path: "",
|
||||
component: AnonLayoutWrapperComponent,
|
||||
children: [
|
||||
{
|
||||
path: "sample-route",
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
component: MyPrimaryComponent,
|
||||
},
|
||||
{
|
||||
path: "",
|
||||
component: EnvironmentSelectorComponent, // use Web or Libs component depending on your client
|
||||
outlet: "environment-selector",
|
||||
},
|
||||
],
|
||||
// ...
|
||||
},
|
||||
],
|
||||
},
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
<Story of={stories.WithSecondaryContent} />
|
||||
Reference in New Issue
Block a user