Skip to content

Commit

Permalink
feat(card-list): replace resize observer with CSS (#262)
Browse files Browse the repository at this point in the history
  • Loading branch information
sonallux authored Jul 28, 2024
1 parent 054540b commit 25b5833
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 97 deletions.
8 changes: 2 additions & 6 deletions src/app/main-layout/main-layout.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,15 @@
<div class="mat-app-background relative flex-grow overflow-hidden">
@if (showNavigationItems) {
<div
class="absolute z-50 h-full w-60 -translate-x-60 overflow-auto border-r border-r-gray-700 bg-gray-800 shadow duration-300 md:translate-x-0 md:shadow-none"
class="absolute z-50 h-full w-60 -translate-x-60 overflow-auto border-r border-r-gray-700 bg-gray-800 shadow max-md:duration-300 md:translate-x-0 md:shadow-none"
[class.translate-x-0]="sidenavOpened"
>
@defer {
<app-sidenav (itemClick)="sidenavOpened = false" />
}
</div>
}
<main
class="h-full overflow-auto duration-300"
[class.md:ml-60]="showNavigationItems"
#scrollContainer
>
<main class="h-full overflow-auto" [class.md:ml-60]="showNavigationItems" #scrollContainer>
<div class="p-6">
@if (showSearchResults) {
@defer {
Expand Down
11 changes: 7 additions & 4 deletions src/app/shared/card-list/card-list.component.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
<div
#container
class="gap-6"
[ngClass]="overflow === 'scroll' ? 'flex overflow-x-auto' : 'grid ' + gridColsClass"
[class]="
overflow === 'scroll'
? 'flex overflow-x-auto'
: 'grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6 2xl:grid-cols-8'
"
>
@if (items) {
@for (item of items; track item; let i = $index) {
Expand All @@ -13,8 +16,8 @@
/>
}
} @else {
@for (i of skeletonItems; track i) {
<app-clickable-card fixedWidth [item]="null" />
@for (i of [0, 1, 2, 3]; track i) {
<app-clickable-card [item]="null" [fixedWidth]="overflow === 'scroll'" />
}
}
</div>
63 changes: 3 additions & 60 deletions src/app/shared/card-list/card-list.component.ts
Original file line number Diff line number Diff line change
@@ -1,73 +1,16 @@
import {
AfterViewInit,
ChangeDetectorRef,
Component,
ElementRef,
EventEmitter,
Input,
OnDestroy,
Output,
ViewChild,
} from '@angular/core';
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { CardItem, ClickableCardComponent } from '../clickable-card/clickable-card.component';
import { NgClass } from '@angular/common';

const CARD_WIDTH = 128;
const GAB_WIDTH = 24;

@Component({
selector: 'app-card-list',
templateUrl: './card-list.component.html',
standalone: true,
imports: [NgClass, ClickableCardComponent],
imports: [ClickableCardComponent],
})
export class CardListComponent implements AfterViewInit, OnDestroy {
export class CardListComponent {
@Input({ required: true }) items!: CardItem[] | null;

@Input() overflow: 'wrap' | 'scroll' = 'wrap';

@Output() itemClick = new EventEmitter<CardItem>();

@ViewChild('container') containerElement!: ElementRef<HTMLElement>;

maxItemsForOneLine = 3;
skeletonItems = Array(this.maxItemsForOneLine)
.fill(0)
.map((_, i) => i);
gridColsClass = 'grid-cols-3';

private resizeObserver: ResizeObserver;

constructor(private cdr: ChangeDetectorRef) {
this.resizeObserver = new ResizeObserver(this.onResize);
}

ngAfterViewInit(): void {
this.resizeObserver.observe(this.containerElement.nativeElement);
}

ngOnDestroy(): void {
this.resizeObserver.disconnect();
}

private onResize: ResizeObserverCallback = ([entry]) => {
if (this.overflow === 'scroll') {
return;
}

const oldMaxItemsForOneLine = this.maxItemsForOneLine;
this.maxItemsForOneLine = Math.max(
2,
Math.floor((entry.contentBoxSize[0].inlineSize + GAB_WIDTH) / (CARD_WIDTH + GAB_WIDTH)),
);
this.gridColsClass = `grid-cols-${this.maxItemsForOneLine}`;
this.skeletonItems = Array(this.maxItemsForOneLine)
.fill(0)
.map((_, i) => i);

// ResizeObserver does not run in Angular Zone, so trigger change detection if value has changed
if (oldMaxItemsForOneLine !== this.maxItemsForOneLine) {
this.cdr.detectChanges();
}
};
}
53 changes: 26 additions & 27 deletions tailwind.config.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,36 @@
const plugin = require("tailwindcss/plugin");
const plugin = require('tailwindcss/plugin');

/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./src/**/*.{html,ts}"],
safelist: [{ pattern: /grid-cols-[0-9]+/ }],
content: ['./src/**/*.{html,ts}'],
theme: {
extend: {
colors: {
"spotify-green": {
50: "#e6f7ae",
100: "#c3eacb",
200: "#9cdcaa",
300: "#71cf88",
400: "#4cc46e",
500: "#1db954",
600: "#10aa4a",
700: "#00973e",
800: "#006833",
900: "#00671e",
'spotify-green': {
50: '#e6f7ae',
100: '#c3eacb',
200: '#9cdcaa',
300: '#71cf88',
400: '#4cc46e',
500: '#1db954',
600: '#10aa4a',
700: '#00973e',
800: '#006833',
900: '#00671e',
},

// overwrite the default gray color palette with the $grey-palette from @angular/material
gray: {
50: "#fafafa",
100: "#f5f5f5",
200: "#eeeeee",
300: "#e0e0e0",
400: "#bdbdbd",
500: "#9e9e9e",
600: "#757575",
700: "#616161",
800: "#424242",
900: "#212121",
50: '#fafafa',
100: '#f5f5f5',
200: '#eeeeee',
300: '#e0e0e0',
400: '#bdbdbd',
500: '#9e9e9e',
600: '#757575',
700: '#616161',
800: '#424242',
900: '#212121',
},
},
},
Expand All @@ -56,12 +55,12 @@ module.exports = {
plugins: [
// https://github.com/tailwindlabs/tailwindcss/discussions/10190
plugin(({ addVariant }) =>
addVariant("search-cancel-button", "&::-webkit-search-cancel-button"),
addVariant('search-cancel-button', '&::-webkit-search-cancel-button'),
),
plugin(({ matchUtilities, theme }) =>
matchUtilities(
{ "filter-opacity": (value) => ({ filter: `opacity(${value})` }) },
{ values: theme("filterOpacity") },
{ 'filter-opacity': (value) => ({ filter: `opacity(${value})` }) },
{ values: theme('filterOpacity') },
),
),
],
Expand Down

0 comments on commit 25b5833

Please sign in to comment.