Skip to content

Commit 1d977ae

Browse files
committed
feat: add gravatar-generator example
1 parent 0c5c0f3 commit 1d977ae

File tree

6 files changed

+170
-1
lines changed

6 files changed

+170
-1
lines changed

apps/docs/src/app/app.routes.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { QrCode } from './pages/pipes/qrcode';
88
import { PipesList } from './pages/pipes/pipes-list';
99
import { Barcode } from './pages/pipes/barcode';
1010
import { Replace } from './pages/pipes/replace';
11+
import { Gravatar } from './pages/pipes/gravatar';
1112

1213
export const appRoutes: Route[] = [
1314
{
@@ -50,6 +51,10 @@ export const appRoutes: Route[] = [
5051
path: 'replace',
5152
component: Replace,
5253
},
54+
{
55+
path: 'gravatar',
56+
component: Gravatar,
57+
},
5358
],
5459
},
5560
],
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
2+
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
3+
import { FormsModule } from '@angular/forms';
4+
import { GravatarPipe } from '@ngx-transforms';
5+
import { SafeHtml } from '@angular/platform-browser';
6+
import { NgIconComponent, provideIcons } from '@ng-icons/core';
7+
import { lucideImage } from '@ng-icons/lucide';
8+
import {HlmInputImports} from '@spartan-ng/helm/input';
9+
import {HlmButtonImports} from '@spartan-ng/helm/button';
10+
import { HlmLabelImports } from '@spartan-ng/helm/label';
11+
12+
13+
@Component({
14+
selector: 'app-gravatar-generator',
15+
standalone: true,
16+
imports: [
17+
FormsModule,
18+
HlmInputImports,
19+
HlmButtonImports,
20+
NgIconComponent,
21+
HlmLabelImports
22+
],
23+
providers: [provideIcons({ lucideImage })],
24+
template: `
25+
<div class="grid grid-cols-1 md:grid-cols-2 gap-8 items-center p-4">
26+
<!-- Left Column: Controls -->
27+
<div class="flex flex-col gap-4 mx-0 md:mx-5">
28+
<div>
29+
<h3 class="text-xl font-semibold">Gravatar Generator</h3>
30+
<p class="text-muted-foreground text-sm mt-1">
31+
Enter an email address to generate its associated Gravatar image.
32+
</p>
33+
</div>
34+
<div class="flex flex-col gap-2">
35+
<label hlmLabel for="email-input">Email Address</label>
36+
<input
37+
hlmInput
38+
id="email-input"
39+
type="email"
40+
class="w-full"
41+
[(ngModel)]="email"
42+
placeholder="e.g., contact@example.com"
43+
/>
44+
</div>
45+
<button hlmBtn (click)="generateGravatar()">Generate</button>
46+
<p class="text-xs text-center text-muted-foreground mt-2">
47+
Avatars are generated based on the public
48+
<a href="https://gravatar.com/" class="font-bold text-primary cursor-pointer hover:underline" target="_blank" rel="noopener noreferrer">Gravatar</a>
49+
service.
50+
</p>
51+
</div>
52+
53+
<!-- Right Column: Image Display -->
54+
<div class="flex items-center justify-center rounded-md border border-border aspect-square w-full max-w-62.5 mx-auto">
55+
@if (gravatarUrl()) {
56+
<img [src]="gravatarUrl()" alt="Generated Gravatar" class="rounded-md h-full w-full" />
57+
} @else {
58+
<div class="flex flex-col items-center justify-center text-muted-foreground">
59+
<ng-icon name="lucideImage" class="h-16 w-16" />
60+
<span class="mt-2 text-sm">Gravatar will appear here</span>
61+
</div>
62+
}
63+
</div>
64+
</div>
65+
`,
66+
changeDetection: ChangeDetectionStrategy.OnPush,
67+
})
68+
export class GravatarGenerator {
69+
email = '';
70+
gravatarUrl = signal<string | SafeHtml>('');
71+
72+
private readonly gravatarPipe = new GravatarPipe();
73+
74+
generateGravatar(): void {
75+
if (this.email) {
76+
this.gravatarUrl.set(this.gravatarPipe.transform(this.email));
77+
}
78+
}
79+
}

apps/docs/src/app/pages/model.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,10 @@ export const PIPES: Pipe[] = [
3333
name: "Replace",
3434
url: "/docs/pipes/replace",
3535
description: "A pipe to replace parts of a string."
36+
},
37+
{
38+
name: "Gravatar",
39+
url: "/docs/pipes/gravatar",
40+
description: "Generate a gravatar from an email address."
3641
}
3742
];
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { Component } from '@angular/core';
2+
import { CodePreview } from '../../reusables/code-preview/code-preview';
3+
import { NextPrevNavigation } from '../../reusables/next-prev-navigation/next-prev-navigation';
4+
import { MacosWindow } from '../../reusables/macos-window/macos-window';
5+
import { AuthorCredit } from '../../reusables/author-credit/author-credit';
6+
import { GravatarGenerator } from '../../examples/gravatar-generator/gravatar-generator';
7+
import {GravatarPipe} from '@ngx-transforms';
8+
9+
@Component({
10+
selector: 'app-gravatar',
11+
standalone: true,
12+
imports: [
13+
CodePreview,
14+
NextPrevNavigation,
15+
MacosWindow,
16+
GravatarPipe,
17+
AuthorCredit,
18+
GravatarGenerator,
19+
],
20+
template: `
21+
<div class="container mx-auto py-10 px-4 md:px-8 max-w-4xl">
22+
<nav class="flex items-center text-sm text-muted-foreground mb-6">
23+
<a href="/docs/pipes" class="hover:text-foreground transition-colors">Pipes</a>
24+
<span class="h-4 w-4 mx-2">/</span>
25+
<span class="text-foreground font-medium">Gravatar</span>
26+
</nav>
27+
28+
<h1 class="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl mb-2">
29+
Gravatar Pipe
30+
</h1>
31+
<p class="text-lg text-muted-foreground mb-8">
32+
A pipe to generate a Gravatar URL from an email address.
33+
</p>
34+
35+
<h2 class="text-2xl font-bold my-8">Example</h2>
36+
<app-macos-window title="Gravatar Generator">
37+
<div>
38+
<app-gravatar-generator />
39+
</div>
40+
</app-macos-window>
41+
42+
<h2 class="text-2xl font-bold my-8">Usage</h2>
43+
<app-code-preview [code]="usageCode" language="typescript">
44+
<div class="rounded-md bg-muted p-6 border border-border flex items-center justify-center">
45+
<img [src]="'example@example.com' | gravatar" alt="Gravatar" class="rounded-full h-24 w-24" />
46+
</div>
47+
</app-code-preview>
48+
49+
<div class="mt-16 pt-8 border-t border-border flex justify-between items-center text-sm text-muted-foreground">
50+
<app-author-credit author="John Doe" url="https://github.com/johndoe" />
51+
<div class="flex gap-4">
52+
<app-next-prev-navigation
53+
[previous]="{ label: 'Highlight', link: '/docs/pipes/highlight' }"
54+
[next]="{ label: 'HTML Escape', link: '/docs/pipes/html-escape' }"
55+
/>
56+
</div>
57+
</div>
58+
</div>
59+
`,
60+
})
61+
export class Gravatar {
62+
usageCode = `
63+
import { Component } from '@angular/core';
64+
import { GravatarPipe } from '@ngx-transforms/ngx-transforms';
65+
66+
@Component({
67+
selector: 'app-example',
68+
standalone: true,
69+
imports: [GravatarPipe],
70+
template: \
71+
<img [src]="'example@example.com' | gravatar" alt="Gravatar" />
72+
\
73+
})
74+
export class ExampleComponent {}
75+
`;
76+
}

apps/docs/src/app/pages/pipes/replace.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,15 @@ import {AuthorCredit} from '../../reusables/author-credit/author-credit';
5151
<div class="flex gap-4">
5252
<app-next-prev-navigation
5353
[previous]="{ label: 'Barcode', link: '/docs/pipes/barcode' }"
54-
[next]="{ label: 'Reverse', link: '/docs/pipes/reverse' }"
54+
[next]="{ label: 'Gravatar', link: '/docs/pipes/gravatar' }"
5555
/>
5656
</div>
5757
</div>
5858
</div>
5959
`,
6060
})
6161
export class Replace {
62+
6263
usageCode = `
6364
import { Component } from '@angular/core';
6465
import { ReplacePipe } from '@ngx-transforms';

tsconfig.base.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@
4040
],
4141
"@spartan-ng/helm/scroll-area": [
4242
"libs/components/ui/scroll-area/src/index.ts"
43+
],
44+
"@spartan-ng/helm/label": [
45+
"libs/components/ui/label/src/index.ts"
4346
]
4447
}
4548
},

0 commit comments

Comments
 (0)