mirror of
https://github.com/bitwarden/browser
synced 2025-12-13 06:43:35 +00:00
[CL-473] Adjust popup page max width and scroll containers (#14853)
This commit is contained in:
@@ -54,6 +54,9 @@ page looks nice when the extension is popped out.
|
|||||||
`false`.
|
`false`.
|
||||||
- `loadingText`
|
- `loadingText`
|
||||||
- Custom text to be applied to the loading element for screenreaders only. Defaults to "Loading".
|
- Custom text to be applied to the loading element for screenreaders only. Defaults to "Loading".
|
||||||
|
- `disablePadding`
|
||||||
|
- When `true`, disables the padding of the scrollable region inside of `main`. You will need to
|
||||||
|
add your own padding to the element you place inside of this area.
|
||||||
|
|
||||||
Basic usage example:
|
Basic usage example:
|
||||||
|
|
||||||
@@ -169,6 +172,22 @@ When the browser extension is popped out, the "popout" button should not be pass
|
|||||||
|
|
||||||
<Canvas of={stories.PoppedOut} />
|
<Canvas of={stories.PoppedOut} />
|
||||||
|
|
||||||
|
## With Virtual Scroll
|
||||||
|
|
||||||
|
If you are using a virtual scrolling container inside of the popup page, you'll want to apply the
|
||||||
|
`bitScrollLayout` directive to the `cdk-virtual-scroll-viewport` element. This tells the virtual
|
||||||
|
scroll viewport to use the popup page's scroll layout div as the scrolling container.
|
||||||
|
|
||||||
|
See the code in the example below.
|
||||||
|
|
||||||
|
<Canvas of={stories.WithVirtualScrollChild} />
|
||||||
|
|
||||||
|
### Known Virtual Scroll Issues
|
||||||
|
|
||||||
|
See [Virtual Scrolling](?path=/docs/documentation-virtual-scrolling--docs#known-footgun) for more
|
||||||
|
information about how to structure virtual scrolling containers with layout components and avoid a
|
||||||
|
known issue with template construction.
|
||||||
|
|
||||||
# Other stories
|
# Other stories
|
||||||
|
|
||||||
## Centered Content
|
## Centered Content
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// FIXME: Update this file to be type safe and remove this and next line
|
import { ScrollingModule } from "@angular/cdk/scrolling";
|
||||||
// @ts-strict-ignore
|
|
||||||
import { CommonModule } from "@angular/common";
|
import { CommonModule } from "@angular/common";
|
||||||
import { Component, importProvidersFrom } from "@angular/core";
|
import { Component, importProvidersFrom } from "@angular/core";
|
||||||
import { RouterModule } from "@angular/router";
|
import { RouterModule } from "@angular/router";
|
||||||
@@ -20,6 +19,7 @@ import {
|
|||||||
NoItemsModule,
|
NoItemsModule,
|
||||||
SearchModule,
|
SearchModule,
|
||||||
SectionComponent,
|
SectionComponent,
|
||||||
|
ScrollLayoutDirective,
|
||||||
} from "@bitwarden/components";
|
} from "@bitwarden/components";
|
||||||
|
|
||||||
import { PopupRouterCacheService } from "../view-cache/popup-router-cache.service";
|
import { PopupRouterCacheService } from "../view-cache/popup-router-cache.service";
|
||||||
@@ -39,6 +39,17 @@ import { PopupTabNavigationComponent } from "./popup-tab-navigation.component";
|
|||||||
})
|
})
|
||||||
class ExtensionContainerComponent {}
|
class ExtensionContainerComponent {}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "extension-popped-container",
|
||||||
|
template: `
|
||||||
|
<div class="tw-h-[640px] tw-w-[900px] tw-border tw-border-solid tw-border-secondary-300">
|
||||||
|
<ng-content></ng-content>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
standalone: true,
|
||||||
|
})
|
||||||
|
class ExtensionPoppedContainerComponent {}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "vault-placeholder",
|
selector: "vault-placeholder",
|
||||||
template: /*html*/ `
|
template: /*html*/ `
|
||||||
@@ -295,6 +306,7 @@ export default {
|
|||||||
decorators: [
|
decorators: [
|
||||||
moduleMetadata({
|
moduleMetadata({
|
||||||
imports: [
|
imports: [
|
||||||
|
ScrollLayoutDirective,
|
||||||
PopupTabNavigationComponent,
|
PopupTabNavigationComponent,
|
||||||
PopupHeaderComponent,
|
PopupHeaderComponent,
|
||||||
PopupPageComponent,
|
PopupPageComponent,
|
||||||
@@ -302,6 +314,7 @@ export default {
|
|||||||
CommonModule,
|
CommonModule,
|
||||||
RouterModule,
|
RouterModule,
|
||||||
ExtensionContainerComponent,
|
ExtensionContainerComponent,
|
||||||
|
ExtensionPoppedContainerComponent,
|
||||||
MockBannerComponent,
|
MockBannerComponent,
|
||||||
MockSearchComponent,
|
MockSearchComponent,
|
||||||
MockVaultSubpageComponent,
|
MockVaultSubpageComponent,
|
||||||
@@ -312,6 +325,11 @@ export default {
|
|||||||
MockVaultPagePoppedComponent,
|
MockVaultPagePoppedComponent,
|
||||||
NoItemsModule,
|
NoItemsModule,
|
||||||
VaultComponent,
|
VaultComponent,
|
||||||
|
ScrollingModule,
|
||||||
|
ItemModule,
|
||||||
|
SectionComponent,
|
||||||
|
IconButtonModule,
|
||||||
|
BadgeModule,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{
|
{
|
||||||
@@ -495,7 +513,21 @@ export const CompactMode: Story = {
|
|||||||
const compact = canvasEl.querySelector(
|
const compact = canvasEl.querySelector(
|
||||||
`#${containerId} [data-testid=popup-layout-scroll-region]`,
|
`#${containerId} [data-testid=popup-layout-scroll-region]`,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (!compact) {
|
||||||
|
// eslint-disable-next-line
|
||||||
|
console.error(`#${containerId} [data-testid=popup-layout-scroll-region] not found`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const label = canvasEl.querySelector(`#${containerId} .example-label`);
|
const label = canvasEl.querySelector(`#${containerId} .example-label`);
|
||||||
|
|
||||||
|
if (!label) {
|
||||||
|
// eslint-disable-next-line
|
||||||
|
console.error(`#${containerId} .example-label not found`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const percentVisible =
|
const percentVisible =
|
||||||
100 -
|
100 -
|
||||||
Math.round((100 * (compact.scrollHeight - compact.clientHeight)) / compact.scrollHeight);
|
Math.round((100 * (compact.scrollHeight - compact.clientHeight)) / compact.scrollHeight);
|
||||||
@@ -510,9 +542,9 @@ export const PoppedOut: Story = {
|
|||||||
render: (args) => ({
|
render: (args) => ({
|
||||||
props: args,
|
props: args,
|
||||||
template: /* HTML */ `
|
template: /* HTML */ `
|
||||||
<div class="tw-h-[640px] tw-w-[900px] tw-border tw-border-solid tw-border-secondary-300">
|
<extension-popped-container>
|
||||||
<mock-vault-page-popped></mock-vault-page-popped>
|
<mock-vault-page-popped></mock-vault-page-popped>
|
||||||
</div>
|
</extension-popped-container>
|
||||||
`,
|
`,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
@@ -560,10 +592,9 @@ export const TransparentHeader: Story = {
|
|||||||
template: /* HTML */ `
|
template: /* HTML */ `
|
||||||
<extension-container>
|
<extension-container>
|
||||||
<popup-page>
|
<popup-page>
|
||||||
<popup-header slot="header" background="alt"
|
<popup-header slot="header" background="alt">
|
||||||
><span class="tw-italic tw-text-main">🤠 Custom Content</span></popup-header
|
<span class="tw-italic tw-text-main">🤠 Custom Content</span>
|
||||||
>
|
</popup-header>
|
||||||
|
|
||||||
<vault-placeholder></vault-placeholder>
|
<vault-placeholder></vault-placeholder>
|
||||||
</popup-page>
|
</popup-page>
|
||||||
</extension-container>
|
</extension-container>
|
||||||
@@ -608,3 +639,56 @@ export const WidthOptions: Story = {
|
|||||||
`,
|
`,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const WithVirtualScrollChild: Story = {
|
||||||
|
render: (args) => ({
|
||||||
|
props: { ...args, data: Array.from(Array(20).keys()) },
|
||||||
|
template: /* HTML */ `
|
||||||
|
<extension-popped-container>
|
||||||
|
<popup-page>
|
||||||
|
<popup-header slot="header" pageTitle="Test"> </popup-header>
|
||||||
|
<mock-search slot="above-scroll-area"></mock-search>
|
||||||
|
<bit-section>
|
||||||
|
@defer (on immediate) {
|
||||||
|
<bit-item-group aria-label="Mock Vault Items">
|
||||||
|
<cdk-virtual-scroll-viewport itemSize="61" bitScrollLayout>
|
||||||
|
<bit-item *cdkVirtualFor="let item of data; index as i">
|
||||||
|
<button type="button" bit-item-content>
|
||||||
|
<i
|
||||||
|
slot="start"
|
||||||
|
class="bwi bwi-globe tw-text-3xl tw-text-muted"
|
||||||
|
aria-hidden="true"
|
||||||
|
></i>
|
||||||
|
{{ i }} of {{ data.length - 1 }}
|
||||||
|
<span slot="secondary">Bar</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<ng-container slot="end">
|
||||||
|
<bit-item-action>
|
||||||
|
<button type="button" bitBadge variant="primary">Fill</button>
|
||||||
|
</bit-item-action>
|
||||||
|
<bit-item-action>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
bitIconButton="bwi-clone"
|
||||||
|
aria-label="Copy item"
|
||||||
|
></button>
|
||||||
|
</bit-item-action>
|
||||||
|
<bit-item-action>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
bitIconButton="bwi-ellipsis-v"
|
||||||
|
aria-label="More options"
|
||||||
|
></button>
|
||||||
|
</bit-item-action>
|
||||||
|
</ng-container>
|
||||||
|
</bit-item>
|
||||||
|
</cdk-virtual-scroll-viewport>
|
||||||
|
</bit-item-group>
|
||||||
|
}
|
||||||
|
</bit-section>
|
||||||
|
</popup-page>
|
||||||
|
</extension-popped-container>
|
||||||
|
`,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,30 +1,40 @@
|
|||||||
<ng-content select="[slot=header]"></ng-content>
|
<ng-content select="[slot=header]"></ng-content>
|
||||||
<main class="tw-flex-1 tw-overflow-hidden tw-flex tw-flex-col tw-relative tw-bg-background-alt">
|
<main class="tw-flex-1 tw-overflow-hidden tw-flex tw-flex-col tw-relative tw-bg-background-alt">
|
||||||
<ng-content select="[slot=full-width-notice]"></ng-content>
|
<ng-content select="[slot=full-width-notice]"></ng-content>
|
||||||
|
<!--
|
||||||
|
x padding on this container is designed to always be a minimum of 0.75rem (equivalent to tailwind's tw-px-3), or 0.5rem (equivalent
|
||||||
|
to tailwind's tw-px-2) in compact mode, but stretch to fill the remainder of the container when the content reaches a maximum of
|
||||||
|
640px in width (equivalent to tailwind's `sm` breakpoint)
|
||||||
|
-->
|
||||||
<div
|
<div
|
||||||
#nonScrollable
|
#nonScrollable
|
||||||
class="tw-transition-colors tw-duration-200 tw-border-0 tw-border-b tw-border-solid tw-p-3 bit-compact:tw-p-2"
|
class="tw-transition-colors tw-duration-200 tw-border-0 tw-border-b tw-border-solid tw-py-3 bit-compact:tw-py-2 tw-px-[max(0.75rem,calc((100%-(var(--tw-sm-breakpoint)))/2))] bit-compact:tw-px-[max(0.5rem,calc((100%-(var(--tw-sm-breakpoint)))/2))]"
|
||||||
[ngClass]="{
|
[ngClass]="{
|
||||||
'tw-invisible !tw-p-0': loading || nonScrollable.childElementCount === 0,
|
'tw-invisible !tw-p-0 !tw-border-none': loading || nonScrollable.childElementCount === 0,
|
||||||
'tw-border-secondary-300': scrolled(),
|
'tw-border-secondary-300': scrolled(),
|
||||||
'tw-border-transparent': !scrolled(),
|
'tw-border-transparent': !scrolled(),
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<ng-content select="[slot=above-scroll-area]"></ng-content>
|
<ng-content select="[slot=above-scroll-area]"></ng-content>
|
||||||
</div>
|
</div>
|
||||||
|
<!--
|
||||||
|
x padding on this container is designed to always be a minimum of 0.75rem (equivalent to tailwind's tw-px-3), or 0.5rem (equivalent
|
||||||
|
to tailwind's tw-px-2) in compact mode, but stretch to fill the remainder of the container when the content reaches a maximum of
|
||||||
|
640px in width (equivalent to tailwind's `sm` breakpoint)
|
||||||
|
-->
|
||||||
<div
|
<div
|
||||||
class="tw-max-w-screen-sm tw-mx-auto tw-overflow-y-auto tw-flex tw-flex-col tw-size-full tw-styled-scrollbar"
|
class="tw-overflow-y-auto tw-size-full tw-styled-scrollbar"
|
||||||
data-testid="popup-layout-scroll-region"
|
data-testid="popup-layout-scroll-region"
|
||||||
(scroll)="handleScroll($event)"
|
(scroll)="handleScroll($event)"
|
||||||
[ngClass]="{ 'tw-invisible': loading }"
|
[ngClass]="{
|
||||||
>
|
'tw-invisible': loading,
|
||||||
<div
|
'tw-py-3 bit-compact:tw-py-2 tw-px-[max(0.75rem,calc((100%-(var(--tw-sm-breakpoint)))/2))] bit-compact:tw-px-[max(0.5rem,calc((100%-(var(--tw-sm-breakpoint)))/2))]':
|
||||||
class="tw-max-w-screen-sm tw-mx-auto tw-flex-1 tw-flex tw-flex-col tw-w-full"
|
!disablePadding,
|
||||||
[ngClass]="{ 'tw-p-3 bit-compact:tw-p-2': !disablePadding }"
|
}"
|
||||||
|
bitScrollLayoutHost
|
||||||
>
|
>
|
||||||
<ng-content></ng-content>
|
<ng-content></ng-content>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<span
|
<span
|
||||||
class="tw-absolute tw-inset-0 tw-flex tw-items-center tw-justify-center tw-text-main"
|
class="tw-absolute tw-inset-0 tw-flex tw-items-center tw-justify-center tw-text-main"
|
||||||
[ngClass]="{ 'tw-invisible': !loading }"
|
[ngClass]="{ 'tw-invisible': !loading }"
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { CommonModule } from "@angular/common";
|
|||||||
import { booleanAttribute, Component, inject, Input, signal } from "@angular/core";
|
import { booleanAttribute, Component, inject, Input, signal } from "@angular/core";
|
||||||
|
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
|
import { ScrollLayoutHostDirective } from "@bitwarden/components";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "popup-page",
|
selector: "popup-page",
|
||||||
@@ -9,7 +10,7 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic
|
|||||||
host: {
|
host: {
|
||||||
class: "tw-h-full tw-flex tw-flex-col tw-overflow-y-hidden",
|
class: "tw-h-full tw-flex tw-flex-col tw-overflow-y-hidden",
|
||||||
},
|
},
|
||||||
imports: [CommonModule],
|
imports: [CommonModule, ScrollLayoutHostDirective],
|
||||||
})
|
})
|
||||||
export class PopupPageComponent {
|
export class PopupPageComponent {
|
||||||
protected i18nService = inject(I18nService);
|
protected i18nService = inject(I18nService);
|
||||||
|
|||||||
@@ -381,14 +381,6 @@ app-root {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds padding on each side of the content if opened in a tab
|
|
||||||
@media only screen and (min-width: 601px) {
|
|
||||||
header,
|
|
||||||
main {
|
|
||||||
padding: 0 calc((100% - 500px) / 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
main:not(popup-page main) {
|
main:not(popup-page main) {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 44px;
|
top: 44px;
|
||||||
|
|||||||
@@ -89,10 +89,7 @@
|
|||||||
</h3>
|
</h3>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<cdk-virtual-scroll-viewport
|
<cdk-virtual-scroll-viewport [itemSize]="itemHeight$ | async" bitScrollLayout>
|
||||||
[itemSize]="itemHeight$ | async"
|
|
||||||
class="tw-overflow-visible [&>.cdk-virtual-scroll-content-wrapper]:[contain:layout_style]"
|
|
||||||
>
|
|
||||||
<bit-item *cdkVirtualFor="let cipher of group.ciphers">
|
<bit-item *cdkVirtualFor="let cipher of group.ciphers">
|
||||||
<button
|
<button
|
||||||
bit-item-content
|
bit-item-content
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import {
|
|||||||
SectionComponent,
|
SectionComponent,
|
||||||
SectionHeaderComponent,
|
SectionHeaderComponent,
|
||||||
TypographyModule,
|
TypographyModule,
|
||||||
|
ScrollLayoutDirective,
|
||||||
} from "@bitwarden/components";
|
} from "@bitwarden/components";
|
||||||
import {
|
import {
|
||||||
DecryptionFailureDialogComponent,
|
DecryptionFailureDialogComponent,
|
||||||
@@ -74,6 +75,7 @@ import { ItemMoreOptionsComponent } from "../item-more-options/item-more-options
|
|||||||
ScrollingModule,
|
ScrollingModule,
|
||||||
DisclosureComponent,
|
DisclosureComponent,
|
||||||
DisclosureTriggerForDirective,
|
DisclosureTriggerForDirective,
|
||||||
|
ScrollLayoutDirective,
|
||||||
],
|
],
|
||||||
selector: "app-vault-list-items-container",
|
selector: "app-vault-list-items-container",
|
||||||
templateUrl: "vault-list-items-container.component.html",
|
templateUrl: "vault-list-items-container.component.html",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<popup-page [loading]="loading$ | async" disablePadding>
|
<popup-page [loading]="loading$ | async">
|
||||||
<popup-header slot="header" [pageTitle]="'vault' | i18n">
|
<popup-header slot="header" [pageTitle]="'vault' | i18n">
|
||||||
<ng-container slot="end">
|
<ng-container slot="end">
|
||||||
<app-new-item-dropdown [initialValues]="newItemItemValues$ | async"></app-new-item-dropdown>
|
<app-new-item-dropdown [initialValues]="newItemItemValues$ | async"></app-new-item-dropdown>
|
||||||
@@ -84,11 +84,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<ng-container *ngIf="vaultState === null">
|
||||||
*ngIf="vaultState === null"
|
|
||||||
cdkVirtualScrollingElement
|
|
||||||
class="tw-h-full tw-p-3 bit-compact:tw-p-2 tw-styled-scrollbar"
|
|
||||||
>
|
|
||||||
<app-autofill-vault-list-items></app-autofill-vault-list-items>
|
<app-autofill-vault-list-items></app-autofill-vault-list-items>
|
||||||
<app-vault-list-items-container
|
<app-vault-list-items-container
|
||||||
[title]="'favorites' | i18n"
|
[title]="'favorites' | i18n"
|
||||||
@@ -103,6 +99,6 @@
|
|||||||
disableSectionMargin
|
disableSectionMargin
|
||||||
collapsibleKey="allItems"
|
collapsibleKey="allItems"
|
||||||
></app-vault-list-items-container>
|
></app-vault-list-items-container>
|
||||||
</div>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</popup-page>
|
</popup-page>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ We export a similar directive, `bitScrollLayout`, that integrates with `bit-layo
|
|||||||
and should be used instead of `scrollWindow`.
|
and should be used instead of `scrollWindow`.
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<!-- Descendant of bit-layout -->
|
<!-- Descendant of bit-layout or popup-page -->
|
||||||
<cdk-virtual-scroll-viewport bitScrollLayout>
|
<cdk-virtual-scroll-viewport bitScrollLayout>
|
||||||
<!-- virtual scroll implementation here -->
|
<!-- virtual scroll implementation here -->
|
||||||
</cdk-virtual-scroll-viewport>
|
</cdk-virtual-scroll-viewport>
|
||||||
@@ -27,7 +27,10 @@ and should be used instead of `scrollWindow`.
|
|||||||
Due to the initialization order of Angular components and their templates, `bitScrollLayout` will
|
Due to the initialization order of Angular components and their templates, `bitScrollLayout` will
|
||||||
error if it is used _in the same template_ as the layout component:
|
error if it is used _in the same template_ as the layout component:
|
||||||
|
|
||||||
|
With `bit-layout`:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
|
<!-- Will cause `bitScrollLayout` to error -->
|
||||||
<bit-layout>
|
<bit-layout>
|
||||||
<cdk-virtual-scroll-viewport bitScrollLayout>
|
<cdk-virtual-scroll-viewport bitScrollLayout>
|
||||||
<!-- virtual scroll implementation here -->
|
<!-- virtual scroll implementation here -->
|
||||||
@@ -35,20 +38,43 @@ error if it is used _in the same template_ as the layout component:
|
|||||||
</bit-layout>
|
</bit-layout>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
With `popup-page`:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!-- Will cause `bitScrollLayout` to error -->
|
||||||
|
<popup-page>
|
||||||
|
<cdk-virtual-scroll-viewport bitScrollLayout>
|
||||||
|
<!-- virtual scroll implementation here -->
|
||||||
|
</cdk-virtual-scroll-viewport>
|
||||||
|
</popup-page>
|
||||||
|
```
|
||||||
|
|
||||||
In this particular composition, the child content gets constructed before the template of
|
In this particular composition, the child content gets constructed before the template of
|
||||||
`bit-layout` and thus has no scroll container to reference. Workarounds include:
|
`bit-layout` (or `popup-page`) and thus has no scroll container to reference. Workarounds include:
|
||||||
|
|
||||||
1. Wrap the child in another component. (This tends to happen by default when the layout is
|
1. Wrap the child in another component. (This tends to happen by default when the layout is
|
||||||
integrated with a `router-outlet`.)
|
integrated with a `router-outlet`.)
|
||||||
|
|
||||||
|
With `bit-layout`:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<bit-layout>
|
<bit-layout>
|
||||||
<component-that-contains-bitScrollLayout></component-that-contains-bitScrollLayout>
|
<component-that-contains-bitScrollLayout></component-that-contains-bitScrollLayout>
|
||||||
</bit-layout>
|
</bit-layout>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
With `popup-page`:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<popup-page>
|
||||||
|
<component-that-contains-bitScrollLayout></component-that-contains-bitScrollLayout>
|
||||||
|
</popup-page>
|
||||||
|
```
|
||||||
|
|
||||||
2. Use a `defer` block.
|
2. Use a `defer` block.
|
||||||
|
|
||||||
|
With `bit-layout`:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<bit-layout>
|
<bit-layout>
|
||||||
@defer (on immediate) {
|
@defer (on immediate) {
|
||||||
@@ -58,3 +84,15 @@ In this particular composition, the child content gets constructed before the te
|
|||||||
}
|
}
|
||||||
</bit-layout>
|
</bit-layout>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
With `popup-page`:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<popup-page>
|
||||||
|
@defer (on immediate) {
|
||||||
|
<cdk-virtual-scroll-viewport bitScrollLayout>
|
||||||
|
<!-- virtual scroll implementation here -->
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</popup-page>
|
||||||
|
```
|
||||||
|
|||||||
@@ -58,6 +58,8 @@
|
|||||||
--color-marketing-logo: 23 93 220;
|
--color-marketing-logo: 23 93 220;
|
||||||
|
|
||||||
--tw-ring-offset-color: #ffffff;
|
--tw-ring-offset-color: #ffffff;
|
||||||
|
|
||||||
|
--tw-sm-breakpoint: 640px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme_light {
|
.theme_light {
|
||||||
|
|||||||
Reference in New Issue
Block a user