Skip to content

Commit 95086a7

Browse files
authored
feat: avatar and breadcrumb styles support, change aspect-ratio styles (#1311)
* docs(accordion): update preview * feat(aspect-ratio): update classes to use aspect-(--ratio), update examples * feat(avatar): add style support * feat(breadcrumb): add styles support * rename HlmBreadCrumbImports to HlmBreadcrumbImports * feat(aspect-ratio): rename to hlm-aspect-ratio * feat(aspect-ratio): check --ratio style * feat(avatar): update styles in tests * docs: add rtl example for aspect ratio, avatar and breadcrumb * docs(badge): add rtl example
1 parent db6d84b commit 95086a7

37 files changed

Lines changed: 505 additions & 74 deletions

apps/app/src/app/pages/(blocks-preview)/blocks-preview/sidebar-inset/sidebar-inset/site-header.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { ChangeDetectionStrategy, Component } from '@angular/core';
2-
import { HlmBreadCrumbImports } from '@spartan-ng/helm/breadcrumb';
2+
import { HlmBreadcrumbImports } from '@spartan-ng/helm/breadcrumb';
33
import { HlmSeparatorImports } from '@spartan-ng/helm/separator';
44
import { HlmSidebarImports } from '@spartan-ng/helm/sidebar';
55

66
@Component({
77
selector: 'spartan-site-header-inset',
8-
imports: [HlmSidebarImports, HlmSeparatorImports, HlmBreadCrumbImports],
8+
imports: [HlmSidebarImports, HlmSeparatorImports, HlmBreadcrumbImports],
99
changeDetection: ChangeDetectionStrategy.OnPush,
1010
template: `
1111
<header class="flex h-16 shrink-0 items-center gap-2">

apps/app/src/app/pages/(blocks-preview)/blocks-preview/sidebar-sticky-header/sticky-header/site-header.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import { ChangeDetectionStrategy, Component } from '@angular/core';
22
import { NgIcon, provideIcons } from '@ng-icons/core';
33
import { lucideSearch } from '@ng-icons/lucide';
4-
import { HlmBreadCrumbImports } from '@spartan-ng/helm/breadcrumb';
4+
import { HlmBreadcrumbImports } from '@spartan-ng/helm/breadcrumb';
55
import { HlmInputGroupImports } from '@spartan-ng/helm/input-group';
66
import { HlmSeparatorImports } from '@spartan-ng/helm/separator';
77
import { HlmSidebarImports } from '@spartan-ng/helm/sidebar';
88

99
@Component({
1010
selector: 'spartan-site-header-sticky',
11-
imports: [HlmSidebarImports, HlmSeparatorImports, HlmBreadCrumbImports, HlmInputGroupImports, NgIcon],
11+
imports: [HlmSidebarImports, HlmSeparatorImports, HlmBreadcrumbImports, HlmInputGroupImports, NgIcon],
1212
providers: [provideIcons({ lucideSearch })],
1313
changeDetection: ChangeDetectionStrategy.OnPush,
1414
template: `

apps/app/src/app/pages/(components)/components/(accordion)/accordion.preview.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,23 @@ import { HlmAccordionImports } from '@spartan-ng/helm/accordion';
1212
<hlm-accordion-item>
1313
<hlm-accordion-trigger>What are your shipping options?</hlm-accordion-trigger>
1414
<hlm-accordion-content>
15-
<p>
16-
We offer standard (5-7 days), express (2-3 days), and overnight shipping. Free shipping on international
17-
orders.
18-
</p>
15+
We offer standard (5-7 days), express (2-3 days), and overnight shipping. Free shipping on international
16+
orders.
1917
</hlm-accordion-content>
2018
</hlm-accordion-item>
2119
2220
<hlm-accordion-item>
2321
<hlm-accordion-trigger>What is your return policy?</hlm-accordion-trigger>
2422
<hlm-accordion-content>
25-
<p>
26-
Returns accepted within 30 days. Items must be unused and in original packaging. Refunds processed within
27-
5-7 business days.
28-
</p>
23+
Returns accepted within 30 days. Items must be unused and in original packaging. Refunds processed within 5-7
24+
business days.
2925
</hlm-accordion-content>
3026
</hlm-accordion-item>
3127
3228
<hlm-accordion-item>
33-
<hlm-accordion-trigger>Return Policy</hlm-accordion-trigger>
29+
<hlm-accordion-trigger>How can I contact customer support?</hlm-accordion-trigger>
3430
<hlm-accordion-content>
35-
<p>Reach us via email, live chat, or phone. We respond within 24 hours during business days.</p>
31+
Reach us via email, live chat, or phone. We respond within 24 hours during business days.
3632
</hlm-accordion-content>
3733
</hlm-accordion-item>
3834
</hlm-accordion>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { NgOptimizedImage } from '@angular/common';
2+
import { ChangeDetectionStrategy, Component } from '@angular/core';
3+
import { HlmAspectRatioImports } from '@spartan-ng/helm/aspect-ratio';
4+
5+
@Component({
6+
selector: 'spartan-aspect-ratio-portrait',
7+
imports: [HlmAspectRatioImports, NgOptimizedImage],
8+
changeDetection: ChangeDetectionStrategy.OnPush,
9+
host: {
10+
class: 'flex items-center justify-center h-72 w-full',
11+
},
12+
template: `
13+
<div [hlmAspectRatio]="9 / 16" class="w-full max-w-40 overflow-hidden">
14+
<img ngSrc="/assets/mountains.jpg" fill alt="Mountain views" class="rounded-lg object-cover" />
15+
</div>
16+
`,
17+
})
18+
export class AspectRatioPortrait {}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { NgOptimizedImage } from '@angular/common';
2+
import { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core';
3+
import { TranslateService, Translations } from '@spartan-ng/app/app/shared/translate.service';
4+
import { HlmAspectRatioImports } from '@spartan-ng/helm/aspect-ratio';
5+
6+
@Component({
7+
selector: 'spartan-aspect-ratio-rtl',
8+
imports: [HlmAspectRatioImports, NgOptimizedImage],
9+
changeDetection: ChangeDetectionStrategy.OnPush,
10+
host: {
11+
class: 'flex items-center justify-center h-72 w-full',
12+
'[dir]': '_dir()',
13+
},
14+
template: `
15+
<figure class="w-full max-w-sm">
16+
<div [hlmAspectRatio]="16 / 9" class="overflow-hidden">
17+
<img ngSrc="/assets/mountains.jpg" fill alt="Mountain views" class="rounded-lg object-cover" />
18+
</div>
19+
<figcaption class="text-muted-foreground mt-2 text-start text-sm">
20+
{{ _t()['caption'] }}
21+
</figcaption>
22+
</figure>
23+
`,
24+
})
25+
export class AspectRatioRtl {
26+
private readonly _language = inject(TranslateService).language;
27+
28+
private readonly _translations: Translations = {
29+
en: {
30+
dir: 'ltr',
31+
values: {
32+
caption: 'Beautiful landscape',
33+
},
34+
},
35+
ar: {
36+
dir: 'rtl',
37+
values: {
38+
caption: 'منظر طبيعي جميل',
39+
},
40+
},
41+
he: {
42+
dir: 'rtl',
43+
values: {
44+
caption: 'נוף יפה',
45+
},
46+
},
47+
};
48+
49+
private readonly _translation = computed(() => this._translations[this._language()]);
50+
protected readonly _t = computed(() => this._translation().values);
51+
protected readonly _dir = computed(() => this._translation().dir);
52+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { NgOptimizedImage } from '@angular/common';
2+
import { ChangeDetectionStrategy, Component } from '@angular/core';
3+
import { HlmAspectRatioImports } from '@spartan-ng/helm/aspect-ratio';
4+
5+
@Component({
6+
selector: 'spartan-aspect-ratio-square',
7+
imports: [HlmAspectRatioImports, NgOptimizedImage],
8+
changeDetection: ChangeDetectionStrategy.OnPush,
9+
host: {
10+
class: 'flex items-center justify-center h-72 w-full',
11+
},
12+
template: `
13+
<div [hlmAspectRatio]="1 / 1" class="w-full max-w-48 overflow-hidden">
14+
<img ngSrc="/assets/mountains.jpg" fill alt="Mountain views" class="rounded-lg object-cover" />
15+
</div>
16+
`,
17+
})
18+
export class AspectRatioSquare {}

apps/app/src/app/pages/(components)/components/(aspect-ratio)/aspect-ratio.page.ts

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import type { RouteMeta } from '@analogjs/router';
22
import { Component, computed, inject } from '@angular/core';
3+
import { CodeRtlPreview } from '@spartan-ng/app/app/shared/code/code-rtl-preview';
4+
import { RtlHeader } from '@spartan-ng/app/app/shared/code/rtl-header';
35
import { InstallTabs } from '@spartan-ng/app/app/shared/layout/install-tabs';
6+
import { SectionSubSubHeading } from '@spartan-ng/app/app/shared/layout/section-sub-sub-heading';
7+
import { hlmCode, hlmP } from '@spartan-ng/helm/typography';
48
import { PrimitiveSnippetsService } from '../../../../core/services/primitive-snippets.service';
59
import { Code } from '../../../../shared/code/code';
610
import { CodePreview } from '../../../../shared/code/code-preview';
@@ -13,6 +17,9 @@ import { SectionSubHeading } from '../../../../shared/layout/section-sub-heading
1317
import { Tabs } from '../../../../shared/layout/tabs';
1418
import { UIApiDocs } from '../../../../shared/layout/ui-docs-section/ui-docs-section';
1519
import { metaWith } from '../../../../shared/meta/meta.util';
20+
import { AspectRatioPortrait } from './aspect-ratio--portrait.example';
21+
import { AspectRatioRtl } from './aspect-ratio--rtl.example';
22+
import { AspectRatioSquare } from './aspect-ratio--square.example';
1623
import { AspectRatioPreview, defaultImports, defaultSkeleton } from './aspect-ratio.preview';
1724

1825
export const routeMeta: RouteMeta = {
@@ -31,20 +38,25 @@ export const routeMeta: RouteMeta = {
3138
SectionIntro,
3239
SectionSubHeading,
3340
Tabs,
34-
41+
SectionSubSubHeading,
3542
CodePreview,
3643
PageNav,
3744
PageBottomNav,
3845
PageBottomNavLink,
46+
RtlHeader,
47+
CodeRtlPreview,
3948
AspectRatioPreview,
49+
AspectRatioSquare,
50+
AspectRatioPortrait,
51+
AspectRatioRtl,
4052
],
4153
template: `
4254
<section spartanMainSection>
4355
<spartan-section-intro name="Aspect Ratio" lead="Displays content within a desired ratio." />
4456
4557
<spartan-tabs firstTab="Preview" secondTab="Code">
4658
<div spartanCodePreview firstTab>
47-
<spartan-aspect-ratio-preview class="h-full w-full" />
59+
<spartan-aspect-ratio-preview />
4860
</div>
4961
<spartan-code secondTab [code]="_defaultCode()" />
5062
</spartan-tabs>
@@ -57,6 +69,41 @@ export const routeMeta: RouteMeta = {
5769
<spartan-code [code]="_defaultSkeleton" />
5870
</div>
5971
72+
<spartan-section-sub-heading id="examples">Examples</spartan-section-sub-heading>
73+
<h3 id="examples__square" spartanH4>Square</h3>
74+
<p class="${hlmP}">
75+
A square aspect ratio component using the
76+
<code class="${hlmCode}">[hlmAspectRatio]="1 / 1"</code>
77+
prop. This is useful for displaying images in a square format.
78+
</p>
79+
<spartan-tabs firstTab="Preview" secondTab="Code">
80+
<div spartanCodePreview firstTab>
81+
<spartan-aspect-ratio-square />
82+
</div>
83+
<spartan-code secondTab [code]="_squareCode()" />
84+
</spartan-tabs>
85+
86+
<h3 id="examples__portrait" spartanH4>Portrait</h3>
87+
<p class="${hlmP}">
88+
A portrait aspect ratio component using the
89+
<code class="${hlmCode}">[hlmAspectRatio]="9 / 16"</code>
90+
prop. This is useful for displaying images in a portrait format.
91+
</p>
92+
<spartan-tabs firstTab="Preview" secondTab="Code">
93+
<div spartanCodePreview firstTab>
94+
<spartan-aspect-ratio-portrait />
95+
</div>
96+
<spartan-code secondTab [code]="_portraitCode()" />
97+
</spartan-tabs>
98+
99+
<spartan-header-rtl />
100+
<spartan-tabs firstTab="Preview" secondTab="Code">
101+
<div spartanRtlCodePreview firstTab>
102+
<spartan-aspect-ratio-rtl />
103+
</div>
104+
<spartan-code secondTab [code]="_rtlCode()" />
105+
</spartan-tabs>
106+
60107
<spartan-section-sub-heading id="hlm-api">Helm API</spartan-section-sub-heading>
61108
<spartan-ui-api-docs docType="helm" />
62109
@@ -71,6 +118,9 @@ export const routeMeta: RouteMeta = {
71118
export default class AlertPage {
72119
private readonly _snippets = inject(PrimitiveSnippetsService).getSnippets('aspect-ratio');
73120
protected readonly _defaultCode = computed(() => this._snippets()['default']);
121+
protected readonly _squareCode = computed(() => this._snippets()['square']);
122+
protected readonly _portraitCode = computed(() => this._snippets()['portrait']);
123+
protected readonly _rtlCode = computed(() => this._snippets()['rtl']);
74124
protected readonly _defaultSkeleton = defaultSkeleton;
75125
protected readonly _defaultImports = defaultImports;
76126
}
Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1-
import { Component } from '@angular/core';
1+
import { NgOptimizedImage } from '@angular/common';
2+
import { ChangeDetectionStrategy, Component } from '@angular/core';
23
import { HlmAspectRatioImports } from '@spartan-ng/helm/aspect-ratio';
34

45
@Component({
56
selector: 'spartan-aspect-ratio-preview',
6-
imports: [HlmAspectRatioImports],
7+
imports: [HlmAspectRatioImports, NgOptimizedImage],
8+
changeDetection: ChangeDetectionStrategy.OnPush,
9+
host: {
10+
class: 'flex items-center justify-center h-72 w-full',
11+
},
712
template: `
8-
<div class="max-w-xl overflow-hidden rounded-xl drop-shadow">
9-
<div [hlmAspectRatio]="16 / 9">
10-
<img alt="Mountain views" src="/assets/mountains.jpg" />
11-
</div>
13+
<div [hlmAspectRatio]="16 / 9" class="w-full max-w-sm overflow-hidden">
14+
<img ngSrc="/assets/mountains.jpg" fill alt="Mountain views" class="rounded-lg object-cover" />
1215
</div>
1316
`,
1417
})
@@ -19,9 +22,7 @@ import { HlmAspectRatioImports } from '@spartan-ng/helm/aspect-ratio';
1922
`;
2023

2124
export const defaultSkeleton = `
22-
<div class="max-w-xl overflow-hidden rounded-xl drop-shadow">
23-
<div [hlmAspectRatio]="ratio">
24-
<img alt="Mountain views" src="/mountains.jpg" />
25+
<div [hlmAspectRatio]="16 / 9">
26+
<img src="..." alt="Image" class="rounded-md object-cover" />
2527
</div>
26-
</div>
2728
`;
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core';
2+
import { TranslateService, Translations } from '@spartan-ng/app/app/shared/translate.service';
3+
import { HlmAvatarImports } from '@spartan-ng/helm/avatar';
4+
5+
@Component({
6+
selector: 'spartan-avatar-rtl-preview',
7+
imports: [HlmAvatarImports],
8+
changeDetection: ChangeDetectionStrategy.OnPush,
9+
host: {
10+
'[dir]': '_dir()',
11+
},
12+
template: `
13+
<div class="flex flex-row flex-wrap items-center gap-6 md:gap-12">
14+
<hlm-avatar>
15+
<img
16+
hlmAvatarImage
17+
src="/assets/avatar.png"
18+
alt="spartan logo. Resembling a spartanic shield"
19+
class="grayscale"
20+
/>
21+
<span hlmAvatarFallback>RG</span>
22+
</hlm-avatar>
23+
<hlm-avatar>
24+
<img
25+
hlmAvatarImage
26+
src="/assets/avatar.png"
27+
alt="spartan logo. Resembling a spartanic shield"
28+
class="grayscale"
29+
/>
30+
<span hlmAvatarFallback>RG</span>
31+
<hlm-avatar-badge class="bg-red-600 dark:bg-red-800" />
32+
</hlm-avatar>
33+
<hlm-avatar-group class="grayscale">
34+
<hlm-avatar>
35+
<img hlmAvatarImage src="/assets/avatar.png" alt="spartan logo. Resembling a spartanic shield" />
36+
<span hlmAvatarFallback>RG</span>
37+
</hlm-avatar>
38+
<hlm-avatar>
39+
<img hlmAvatarImage src="/assets/avatar.png" alt="spartan logo. Resembling a spartanic shield" />
40+
<span hlmAvatarFallback>RG</span>
41+
</hlm-avatar>
42+
<hlm-avatar>
43+
<img hlmAvatarImage src="/assets/avatar.png" alt="spartan logo. Resembling a spartanic shield" />
44+
<span hlmAvatarFallback>RG</span>
45+
</hlm-avatar>
46+
<hlm-avatar-group-count>{{ _t()['moreUsers'] }}</hlm-avatar-group-count>
47+
</hlm-avatar-group>
48+
</div>
49+
`,
50+
})
51+
export class AvatarRtlPreview {
52+
private readonly _language = inject(TranslateService).language;
53+
54+
private readonly _translations: Translations = {
55+
en: {
56+
dir: 'ltr',
57+
values: {
58+
moreUsers: '+3',
59+
},
60+
},
61+
ar: {
62+
dir: 'rtl',
63+
values: {
64+
moreUsers: '+٣',
65+
},
66+
},
67+
he: {
68+
dir: 'rtl',
69+
values: {
70+
moreUsers: '+3',
71+
},
72+
},
73+
};
74+
75+
private readonly _translation = computed(() => this._translations[this._language()]);
76+
protected readonly _t = computed(() => this._translation().values);
77+
protected readonly _dir = computed(() => this._translation().dir);
78+
}

0 commit comments

Comments
 (0)