Skip to content

Commit

Permalink
fix: avatar fallback calling
Browse files Browse the repository at this point in the history
  • Loading branch information
GODrums committed Aug 7, 2024
1 parent 793445a commit df98b8d
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 95 deletions.
2 changes: 1 addition & 1 deletion webapp/.prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
"semi": true,
"bracketSpacing": true,
"trailingComma": "none",
"endOfLine": "lf"
"endOfLine": "auto"
}
12 changes: 1 addition & 11 deletions webapp/src/app/ui/avatar/avatar.component.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,3 @@
<div [class]="computedClass()">
@if (canShow()) {
<img
[src]="src()"
[alt]="alt()"
[class]="computedImageClass()"
placeholder
(error)="onError()"
/>
} @else {
<img [class]="computedImageClass()" src="https://placehold.co/64" />
}
<img [ngSrc]="computedSrc()" [alt]="alt()" [class]="computedImageClass()" (error)="onError()" fill />
</div>
76 changes: 19 additions & 57 deletions webapp/src/app/ui/avatar/avatar.component.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,22 @@
import {
ChangeDetectionStrategy,
Component,
computed,
input,
signal,
} from '@angular/core';
import { ChangeDetectionStrategy, Component, computed, input, signal } from '@angular/core';
import type { ClassValue } from 'clsx';
import type { VariantProps } from 'class-variance-authority';
import { cn } from 'app/utils';
import { cva } from 'app/storybook.helper';
import { NgOptimizedImage } from '@angular/common';

const [avatarVariants, args, argTypes] = cva(
'relative flex shrink-0 overflow-hidden rounded-full',
{
variants: {
variant: {
small: 'h-6 w-6 text-xs',
medium: 'h-10 w-10',
large: 'h-14 w-14 text-lg',
},
},
defaultVariants: {
variant: 'medium',
},
const [avatarVariants, args, argTypes] = cva('relative flex shrink-0 overflow-hidden rounded-full', {
variants: {
variant: {
small: 'h-6 w-6 text-xs',
medium: 'h-10 w-10',
large: 'h-14 w-14 text-lg'
}
},
);
defaultVariants: {
variant: 'medium'
}
});

export { args, argTypes };

Expand All @@ -36,55 +27,26 @@ interface AvatarVariants extends VariantProps<typeof avatarVariants> {}
standalone: true,
imports: [NgOptimizedImage],
changeDetection: ChangeDetectionStrategy.OnPush,
// template: `
// <ng-container *ngIf="image?.canShow(); else fallback">
// <ng-content
// select="[appAvatarImage]"
// (error)="onError()"
// (load)="onLoad()"
// />
// </ng-container>
// <ng-template #fallback>
// <ng-content select="[avatarFallback]" />
// </ng-template>
// `,
templateUrl: './avatar.component.html',
templateUrl: './avatar.component.html'
})
// export class AppAvatarComponent {
// class = input<ClassValue>('');
// variant = input<AvatarVariants['variant']>('medium');

// @ContentChild(AvatarImageDirective, { static: true })
// image: AvatarImageDirective | null = null;

// computedClass = computed(() =>
// cn(avatarVariants({ variant: this.variant() }), this.class()),
// );
// }
export class AppAvatarComponent {
class = input<ClassValue>('');
variant = input<AvatarVariants['variant']>('medium');

src = input<string>('');
alt = input<string>('');
imageClass = input<string>('');
fallback = input<string>('');
fallback = input<string>('https://placehold.co/56');

canShow = signal(true);

onError = () => {
if (this.fallback.length > 0) {
this.src = this.fallback;
} else {
this.canShow.set(false);
}
this.canShow.set(false);
};

computedClass = computed(() =>
cn(avatarVariants({ variant: this.variant() }), this.class()),
);
computedClass = computed(() => cn(avatarVariants({ variant: this.variant() }), this.class()));

computedSrc = computed(() => (this.canShow() ? this.src() : this.fallback()));

computedImageClass = computed(() =>
cn('aspect-square object-cover h-full w-full', this.imageClass()),
);
computedImageClass = computed(() => cn('aspect-square object-cover h-full w-full', this.imageClass()));
}
64 changes: 38 additions & 26 deletions webapp/src/app/ui/avatar/avatar.stories.ts
Original file line number Diff line number Diff line change
@@ -1,84 +1,96 @@
import { argsToTemplate, type Meta, type StoryObj } from '@storybook/angular';
import { AppAvatarComponent, args, argTypes } from './avatar.component';

// More on how to set up stories at: https://storybook.js.org/docs/writing-stories
const meta: Meta<AppAvatarComponent> = {
title: 'UI/Avatar',
component: AppAvatarComponent,
tags: ['autodocs'],
args: {
...args,
...args
},
argTypes: {
...argTypes,
},
...argTypes
}
};

export default meta;
type Story = StoryObj<AppAvatarComponent>;

// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
export const Default: Story = {
args: {
variant: 'medium',
src: 'https://i.pravatar.cc/64?img=1',
src: 'https://i.pravatar.cc/40?img=1',
alt: 'avatar',
class: '',
class: ''
},

render: (args) => ({
props: args,
template: `<app-avatar ${argsToTemplate(args)}></app-avatar>`,
}),
template: `<app-avatar ${argsToTemplate(args)}></app-avatar>`
})
};

export const Small: Story = {
args: {
variant: 'small',
src: 'https://placehold.co/24',
src: 'https://i.pravatar.cc/24?img=1'
},

render: (args) => ({
props: args,
template: `<app-avatar ${argsToTemplate(args)}></app-avatar>`,
}),
template: `<app-avatar ${argsToTemplate(args)}></app-avatar>`
})
};

export const Medium: Story = {
args: {
variant: 'medium',
src: 'https://placehold.co/40',
src: 'https://i.pravatar.cc/40?img=1'
},

render: (args) => ({
props: args,
template: `<app-avatar ${argsToTemplate(args)}>MD</app-avatar>`,
}),
template: `<app-avatar ${argsToTemplate(args)}>MD</app-avatar>`
})
};

export const Large: Story = {
args: {
variant: 'large',
src: 'https://placehold.co/56',
src: 'https://i.pravatar.cc/56?img=1',
alt: 'avatar',
class: ''
},

render: (args) => ({
props: args,
template: `<app-avatar ${argsToTemplate(args)}>LG</app-avatar>`,
}),
template: `<app-avatar ${argsToTemplate(args)}>LG</app-avatar>`
})
};

export const WithImage: Story = {
export const WithRandomImage: Story = {
args: {
variant: 'large',
src: 'https://i.pravatar.cc/56',
alt: 'avatar'
},

render: (args) => ({
props: args,
template: `<app-avatar ${argsToTemplate(args)}></app-avatar>`
})
};

export const WithFallback: Story = {
args: {
variant: 'medium',
src: 'https://i.pravatar.cc/40',
src: 'foobar.jpg',
fallback: 'https://placehold.co/40',
alt: 'fallback'
},

render: (args) => ({
props: {
variant: 'outline',
size: 'icon',
},
template: `<app-avatar ${argsToTemplate(args)}></app-avatar>`,
}),
props: args,
template: `<app-avatar ${argsToTemplate(args)}></app-avatar>`
})
};

0 comments on commit df98b8d

Please sign in to comment.