Skip to content

Commit

Permalink
Refactor: Use resize observer instead of css container query
Browse files Browse the repository at this point in the history
  • Loading branch information
RasmusTraeholt committed Feb 24, 2025
1 parent d547c02 commit db34849
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
<ng-container *ngTemplateOutlet="sharedCardContent"></ng-container>
</kirby-card>

<div aria-hidden="true" class="banner-ruler"></div>

<ng-template #sharedCardContent>
<div class="blur-image-wrapper">
<img class="blur-image" [src]="imagePath" alt="" />
Expand Down
134 changes: 55 additions & 79 deletions libs/extensions/angular/image-banner/src/image-banner.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,45 +6,11 @@ $max-content-width: 324px;
$main-image-height-small: 132px;
$main-image-height-large: 164px;

// The breakpoint where container should switch from "narrow" to "wide"
$container-query-breakpoint: 600px;

@mixin container-less-than-width() {
@container banner (width < #{$container-query-breakpoint}) {
@content;
}
}

@mixin container-more-than-width() {
@container banner (width >= #{$container-query-breakpoint}) {
@content;
}
}

// Container-type: inline-size currently causes block elements to collapse in certain scenarios on Safari
// To avoid content collapsing we use an empty block element as the container instead (we only need the inline size)
.banner-ruler {
container-name: banner;
container-type: inline-size;
content: none;
visibility: hidden;
}

:host(.none) {
.blur-image {
display: none;
}

.dismiss {
// on mobile we always want the button to be white as it sits on top of the image
@include container-less-than-width {
--kirby-inputs-background-color: var(--kirby-white);
--kirby-inputs-background-color-hover: var(--kirby-dark-overlay-10);
--kirby-inputs-background-color-active: var(--kirby-dark-overlay-20);
--kirby-inputs-color: var(--kirby-black);
}
}

.main-content-body-action-link {
color: var(--kirby-semi-dark);
}
Expand All @@ -58,6 +24,61 @@ $container-query-breakpoint: 600px;
filter: blur($blur-radius) brightness(1.3);
}

:host(.container-less-than-width) {
.dismiss {
// on mobile we always want the button to be white as it sits on top of the image
--kirby-inputs-background-color: var(--kirby-white);
--kirby-inputs-background-color-hover: var(--kirby-dark-overlay-10);
--kirby-inputs-background-color-active: var(--kirby-dark-overlay-20);
--kirby-inputs-color: var(--kirby-black);
}
}

:host(.container-more-than-width) {
.main-content-wrapper {
gap: utils.size('s');
flex-direction: initial;
}

.main-content-image-wrapper {
flex: 1;
}

.main-content {
flex: 1;
gap: utils.size('xs');
padding: utils.size('xxs') utils.size('xxs') utils.size('xxs') 0;

.main-content-header {
padding-inline-end: utils.size('xl');
}
}

.main-content-image {
height: $main-image-height-large;
}

.main-content-body {
flex-direction: column;
max-width: $max-content-width;

.main-content-body-action-link {
display: none;
}
}

.main-content-body-text {
padding-inline-end: utils.size('xxl');
max-height: utils.size('xxxxl');
}

.main-content-body-action-text {
align-self: start;
display: inline-flex;
margin: 0; // buttons have xxxs margin so reset that
}
}

.blur-image-wrapper {
// We scale the image here with inset to avoid halo-bleed when using blur.
position: absolute;
Expand All @@ -83,21 +104,12 @@ kirby-card {
box-sizing: border-box;
display: flex;
flex-direction: column;

@include container-more-than-width {
gap: utils.size('s');
flex-direction: initial;
}
}

.main-content-image-wrapper {
display: flex;
overflow: hidden;
border-radius: utils.border-radius('s');

@include container-more-than-width {
flex: 1;
}
}

.main-content {
Expand All @@ -114,10 +126,6 @@ kirby-card {

.main-content-header {
padding-inline-end: utils.size('xxs');

@include container-more-than-width {
padding-inline-end: utils.size('xl');
}
}

&:has(.main-content-body-action-link) {
Expand All @@ -133,12 +141,6 @@ kirby-card {
&:has(.body-text:empty):has(.header-text:empty) {
padding-block-end: 0;
}

@include container-more-than-width {
flex: 1;
gap: utils.size('xs');
padding: utils.size('xxs') utils.size('xxs') utils.size('xxs') 0;
}
}

.main-content-anchor {
Expand All @@ -160,50 +162,24 @@ kirby-card {
height: $main-image-height-small;
object-fit: cover;
object-position: center;

@include container-more-than-width {
height: $main-image-height-large;
}
}

.main-content-body {
display: flex;
justify-content: space-between;
gap: utils.size('s');
height: 100%;

@include container-more-than-width {
flex-direction: column;
max-width: $max-content-width;
}

.main-content-body-action-link {
@include container-more-than-width {
display: none;
}
}
}

.main-content-body-text {
display: block;
overflow: hidden;
max-height: utils.size('xl');
padding-inline-end: utils.size('xxs');

@include container-more-than-width {
padding-inline-end: utils.size('xxl');
max-height: utils.size('xxxxl');
}
}

.main-content-body-action-text {
display: none;

@include container-more-than-width {
align-self: start;
display: inline-flex;
margin: 0; // buttons have xxxs margin so reset that
}
}

.dismiss {
Expand Down
41 changes: 37 additions & 4 deletions libs/extensions/angular/image-banner/src/image-banner.component.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,35 @@
import { CommonModule } from '@angular/common';
import { Component, EventEmitter, HostBinding, Input, Output } from '@angular/core';
import {
AfterViewInit,
Component,
ElementRef,
EventEmitter,
HostBinding,
inject,
Input,
Output,
Renderer2,
} from '@angular/core';
import { CardModule } from '@kirbydesign/designsystem/card';
import { ButtonComponent } from '@kirbydesign/designsystem/button';
import { IconModule } from '@kirbydesign/designsystem/icon';
import { TranslationService } from '@kirbydesign/designsystem/shared';
import { ResizeObserverService, TranslationService } from '@kirbydesign/designsystem/shared';

@Component({
selector: 'kirby-x-image-banner',
imports: [CardModule, ButtonComponent, IconModule, CommonModule],
templateUrl: './image-banner.component.html',
styleUrl: './image-banner.component.scss',
})
export class ImageBannerComponent {
export class ImageBannerComponent implements AfterViewInit {
private host = inject(ElementRef);
private renderer = inject(Renderer2);
private resizeObserverService = inject(ResizeObserverService);

public translations = inject(TranslationService);

private readonly CONTAINER_BREAKPOINT = 600;

/**
* The title placed inside the image banners header.
*/
Expand Down Expand Up @@ -60,7 +78,22 @@ export class ImageBannerComponent {
@Output()
imageError = new EventEmitter<ErrorEvent>();

constructor(public translations: TranslationService) {}
ngAfterViewInit() {
this.resizeObserverService.observe(this.host.nativeElement, (entry) =>
this.handleHostResize(entry)
);
}

private handleHostResize(entry: ResizeObserverEntry) {
console.log(entry);
if (entry.contentRect.width < this.CONTAINER_BREAKPOINT) {
this.renderer.removeClass(this.host.nativeElement, 'container-more-than-width');
this.renderer.addClass(this.host.nativeElement, 'container-less-than-width');
} else {
this.renderer.removeClass(this.host.nativeElement, 'container-less-than-width');
this.renderer.addClass(this.host.nativeElement, 'container-more-than-width');
}
}

public bannerClicked(event: Event) {
const eventTarget = event.target as HTMLElement;
Expand Down

0 comments on commit db34849

Please sign in to comment.