From f6f10eb9893878613c2bae7c0a30cfd104d549ec Mon Sep 17 00:00:00 2001 From: John White <750350+johnhwhite@users.noreply.github.com> Date: Wed, 16 Oct 2024 10:26:42 -0400 Subject: [PATCH] fix(components/pages): constrain page sizing --- .../page-header/page-header.component.spec.ts | 25 +++++++---- .../page-header/page-header.component.ts | 41 ++----------------- .../modules/page/page-content.component.ts | 4 +- .../src/lib/modules/page/page.component.ts | 20 ++++++++- .../theme/src/lib/styles/_layout-host.scss | 18 ++++++-- 5 files changed, 57 insertions(+), 51 deletions(-) diff --git a/libs/components/pages/src/lib/modules/page-header/page-header.component.spec.ts b/libs/components/pages/src/lib/modules/page-header/page-header.component.spec.ts index c2ec741767..24d7d1dab8 100644 --- a/libs/components/pages/src/lib/modules/page-header/page-header.component.spec.ts +++ b/libs/components/pages/src/lib/modules/page-header/page-header.component.spec.ts @@ -1,19 +1,27 @@ +import { provideLocationMocks } from '@angular/common/testing'; import { TestBed } from '@angular/core/testing'; -import { RouterModule } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; +import { provideRouter } from '@angular/router'; import { expect } from '@skyux-sdk/testing'; +import { SkyMediaBreakpoints, SkyMediaQueryService } from '@skyux/core'; +import { MockSkyMediaQueryService } from '@skyux/core/testing'; import { PageHeaderFixturesComponent } from './fixtures/page-header-fixtures.component'; import { SkyPageHeaderModule } from './page-header.module'; describe('Page header component', () => { + let mediaQueryService: MockSkyMediaQueryService; + beforeEach(() => { + mediaQueryService = new MockSkyMediaQueryService(); TestBed.configureTestingModule({ - imports: [ - PageHeaderFixturesComponent, - RouterModule, - SkyPageHeaderModule, - RouterTestingModule.withRoutes([]), + imports: [PageHeaderFixturesComponent, SkyPageHeaderModule], + providers: [ + provideRouter([]), + provideLocationMocks(), + { + provide: SkyMediaQueryService, + useValue: mediaQueryService, + }, ], }); }); @@ -39,7 +47,7 @@ describe('Page header component', () => { it('should render an avatar at size large when page is at a large breakpoint', () => { const fixture = TestBed.createComponent(PageHeaderFixturesComponent); fixture.componentInstance.showAvatar = true; - fixture.componentInstance.width = 900; + mediaQueryService.fire(SkyMediaBreakpoints.lg); fixture.detectChanges(); const largeAvatar = fixture.nativeElement.querySelector( @@ -52,6 +60,7 @@ describe('Page header component', () => { it('should render an avatar at size small when page is at an xs breakpoint', () => { const fixture = TestBed.createComponent(PageHeaderFixturesComponent); fixture.componentInstance.showAvatar = true; + mediaQueryService.fire(SkyMediaBreakpoints.xs); fixture.detectChanges(); const smallAvatar = fixture.nativeElement.querySelector( diff --git a/libs/components/pages/src/lib/modules/page-header/page-header.component.ts b/libs/components/pages/src/lib/modules/page-header/page-header.component.ts index 07b12797fe..31924ac789 100644 --- a/libs/components/pages/src/lib/modules/page-header/page-header.component.ts +++ b/libs/components/pages/src/lib/modules/page-header/page-header.component.ts @@ -1,20 +1,7 @@ -import { - Component, - ElementRef, - Input, - OnDestroy, - OnInit, - inject, -} from '@angular/core'; -import { - SkyMediaQueryService, - SkyResizeObserverMediaQueryService, -} from '@skyux/core'; +import { Component, Input } from '@angular/core'; import { SkyPageLink } from '../action-hub/types/page-link'; -let parentLink: SkyPageLink; - /** * Displays page heading's contents using spacing that corresponds to the parent page's layout */ @@ -22,37 +9,17 @@ let parentLink: SkyPageLink; selector: 'sky-page-header', templateUrl: './page-header.component.html', styleUrls: ['./page-header.component.scss'], - providers: [ - SkyResizeObserverMediaQueryService, - { - provide: SkyMediaQueryService, - useExisting: SkyResizeObserverMediaQueryService, - }, - ], }) -export class SkyPageHeaderComponent implements OnInit, OnDestroy { +export class SkyPageHeaderComponent { /** * A link to the parent page of the current page. */ @Input() - public parentLink?: typeof parentLink; + public parentLink?: SkyPageLink; /** * The title of the current page. */ @Input() - public pageTitle!: string; - - #elementRef = inject(ElementRef); - #mediaQueryService = inject(SkyResizeObserverMediaQueryService); - - public ngOnInit(): void { - this.#mediaQueryService.observe(this.#elementRef, { - updateResponsiveClasses: true, - }); - } - - public ngOnDestroy(): void { - this.#mediaQueryService.unobserve(); - } + public pageTitle?: string; } diff --git a/libs/components/pages/src/lib/modules/page/page-content.component.ts b/libs/components/pages/src/lib/modules/page/page-content.component.ts index f675e2d9e2..4053ebfb7b 100644 --- a/libs/components/pages/src/lib/modules/page/page-content.component.ts +++ b/libs/components/pages/src/lib/modules/page/page-content.component.ts @@ -30,7 +30,9 @@ import { }) export class SkyPageContentComponent implements OnInit, OnDestroy { #elementRef = inject(ElementRef); - #mediaQueryService = inject(SkyResizeObserverMediaQueryService); + #mediaQueryService = inject(SkyResizeObserverMediaQueryService, { + self: true, + }); public ngOnInit(): void { this.#mediaQueryService.observe(this.#elementRef, { diff --git a/libs/components/pages/src/lib/modules/page/page.component.ts b/libs/components/pages/src/lib/modules/page/page.component.ts index c19043cb69..34c9c382cf 100644 --- a/libs/components/pages/src/lib/modules/page/page.component.ts +++ b/libs/components/pages/src/lib/modules/page/page.component.ts @@ -1,5 +1,6 @@ import { Component, + ElementRef, HostBinding, Input, OnDestroy, @@ -10,6 +11,8 @@ import { SkyHelpService, SkyLayoutHostForChildArgs, SkyLayoutHostService, + SkyMediaQueryService, + SkyResizeObserverMediaQueryService, } from '@skyux/core'; import { Subject } from 'rxjs'; @@ -32,7 +35,15 @@ const LAYOUT_CLASS_DEFAULT = `${LAYOUT_CLASS_PREFIX}${LAYOUT_DEFAULT}`; @Component({ selector: 'sky-page', template: ``, - providers: [SkyPageThemeAdapterService, SkyLayoutHostService], + providers: [ + SkyPageThemeAdapterService, + SkyLayoutHostService, + SkyResizeObserverMediaQueryService, + { + provide: SkyMediaQueryService, + useExisting: SkyResizeObserverMediaQueryService, + }, + ], }) export class SkyPageComponent implements OnInit, OnDestroy { /** @@ -67,6 +78,10 @@ export class SkyPageComponent implements OnInit, OnDestroy { #themeAdapter = inject(SkyPageThemeAdapterService); #layoutHostSvc = inject(SkyLayoutHostService); #helpSvc = inject(SkyHelpService, { optional: true }); + readonly #elementRef = inject(ElementRef); + readonly #resizeObserverSvc = inject(SkyResizeObserverMediaQueryService, { + self: true, + }); public ngOnInit(): void { this.#themeAdapter.addTheme(); @@ -77,10 +92,13 @@ export class SkyPageComponent implements OnInit, OnDestroy { this.#layoutForChild = args.layout as SkyPageLayoutType; this.#updateCssClass(); }); + + this.#resizeObserverSvc.observe(this.#elementRef); } public ngOnDestroy(): void { this.#themeAdapter.removeTheme(); + this.#resizeObserverSvc.destroy(); this.#ngUnsubscribe.next(); this.#ngUnsubscribe.complete(); diff --git a/libs/components/theme/src/lib/styles/_layout-host.scss b/libs/components/theme/src/lib/styles/_layout-host.scss index 307ff1cb2c..1ba8a2fdce 100644 --- a/libs/components/theme/src/lib/styles/_layout-host.scss +++ b/libs/components/theme/src/lib/styles/_layout-host.scss @@ -1,4 +1,5 @@ -@use 'mixins' as mixins; +@use './mixins' as mixins; +@use './variables' as variables; // xs breakpoint .sky-layout-host { @@ -130,11 +131,20 @@ minmax(var(--sky-margin-stacked-xl), min-content) minmax(var(--sky-margin-stacked-xl), min-content) minmax(var(--sky-margin-stacked-xl), min-content) - 1fr; - grid-template-columns: 0 auto 25%; + auto; + grid-template-columns: 0 75% 25%; &:has(sky-page-header-avatar:not(:empty)) { - grid-template-columns: min-content auto 25%; + grid-template-columns: + calc( + #{variables.$sky-avatar-height} + var(--sky-margin-inline-xl) + var(--sky-margin-inline-lg) + ) + calc( + 75% - #{variables.$sky-avatar-height} - var( + --sky-margin-inline-xl + ) - var(--sky-margin-inline-lg) + ) + 25%; h1.sky-page-header-text { margin: 0;