@@ -10,10 +10,12 @@ import {
1010 getComponentApi ,
1111 getGuidanceForComponent ,
1212 getExamplesForComponent ,
13+ getRelatedComponents ,
1314 getSubcomponents ,
1415 categorizeGuidance ,
1516} from ' ../../lib/content-queries' ;
1617import { getComponentConfigurations } from ' ../../data/configurations' ;
18+ import { getThumbnailPath } from ' ../../lib/component-thumbnails' ;
1719
1820// Generate static paths for all components
1921export async function getStaticPaths() {
@@ -47,6 +49,9 @@ const componentExamples = await getExamplesForComponent(slug);
4749// 5. Get component configurations (if available)
4850const configurations = getComponentConfigurations (slug );
4951
52+ // 6. Get visible related components (peers, not subcomponents)
53+ const relatedComponents = await getRelatedComponents (component .data .relatedComponents ?? []);
54+
5055// GitHub issues URL for this component
5156const githubIssuesUrl = ` https://github.com/GovAlta/ui-components/issues?q=is%3Aissue+is%3Aopen+label%3A%22${encodeURIComponent (component .data .name )}%22 ` ;
5257
@@ -174,6 +179,39 @@ const v1DocsUrl = `https://v1.design.alberta.ca/components/${slug}`;
174179 </TabContentWrapper >
175180 </goa-tab>
176181 </goa-tabs>
182+
183+ { relatedComponents .length > 0 && (
184+ <section class = " related-components" >
185+ <h2 class = " related-heading" >Related components</h2 >
186+ <div class = " related-cards" >
187+ { relatedComponents .map ((comp ) => {
188+ const compSlug = comp .data .slug || comp .slug ;
189+ return (
190+ <a href = { ` /components/${compSlug } ` } class = " related-card" >
191+ <div class = " related-card-thumbnail" aria-hidden = " true" >
192+ <img src = { getThumbnailPath (compSlug )} alt = " " loading = " lazy"
193+ onerror = " this.style.display='none';this.nextElementSibling.style.display='flex'" />
194+ <span class = " related-card-thumbnail-fallback" >{ comp .data .name } </span >
195+ </div >
196+ <div class = " related-card-info" >
197+ <span class = " related-card-name" >{ comp .data .name } </span >
198+ { comp .data .description && (
199+ <p class = " related-card-description" >{ comp .data .description } </p >
200+ )}
201+ <div class = " related-card-badge" >
202+ <goa-badge version = " 2" type = " default" emphasis = " subtle" icon = " false" content = { comp .data .category .replace (/ -/ g , ' ' )} />
203+ </div >
204+ </div >
205+ </a >
206+ );
207+ })}
208+ </div >
209+ </section >
210+ )}
211+
212+ <goa-spacer version =" 2" vspacing =" xl" ></goa-spacer>
213+ <goa-divider version =" 2" ></goa-divider>
214+ <goa-spacer version =" 2" vspacing =" m" ></goa-spacer>
177215 </div >
178216 <goa-link size =" small" trailingicon =" open" >
179217 <a href ={ v1DocsUrl } target =" _blank" rel =" noopener noreferrer"
@@ -296,5 +334,95 @@ const v1DocsUrl = `https://v1.design.alberta.ca/components/${slug}`;
296334 padding-left: var(--goa-space-l);
297335 max-width: 65ch;
298336 }
337+
338+ /* Related Components */
339+ .related-components {
340+ margin-top: var(--goa-space-2xl);
341+ padding-top: var(--goa-space-xl);
342+ border-top: 1px solid var(--goa-color-greyscale-200);
343+ }
344+
345+ .related-heading {
346+ font: var(--goa-typography-heading-s);
347+ color: var(--goa-color-text-default);
348+ margin: 0 0 var(--goa-space-m);
349+ }
350+
351+ .related-cards {
352+ display: grid;
353+ grid-template-columns: repeat(auto-fill, minmax(12rem, 15rem));
354+ gap: var(--goa-space-m);
355+ }
356+
357+ .related-card {
358+ display: flex;
359+ flex-direction: column;
360+ text-decoration: none;
361+ color: inherit;
362+ }
363+
364+ .related-card:focus-visible {
365+ outline: 2px solid var(--goa-color-interactive-focus);
366+ outline-offset: 2px;
367+ border-radius: var(--goa-border-radius-m);
368+ }
369+
370+ .related-card-thumbnail {
371+ aspect-ratio: 386 / 256;
372+ background: var(--goa-color-greyscale-200);
373+ border-radius: var(--goa-border-radius-m);
374+ overflow: hidden;
375+ }
376+
377+ .related-card-thumbnail img {
378+ width: 100%;
379+ height: 100%;
380+ object-fit: cover;
381+ display: block;
382+ }
383+
384+ .related-card-thumbnail-fallback {
385+ display: none;
386+ width: 100%;
387+ height: 100%;
388+ align-items: center;
389+ justify-content: center;
390+ font: var(--goa-typography-heading-xs);
391+ color: var(--goa-color-text-secondary);
392+ text-align: center;
393+ padding: var(--goa-space-s);
394+ }
395+
396+ .related-card-info {
397+ display: flex;
398+ flex-direction: column;
399+ gap: var(--goa-space-2xs);
400+ padding-top: var(--goa-space-xs);
401+ }
402+
403+ .related-card-name {
404+ font: var(--goa-typography-heading-xs);
405+ color: var(--goa-color-interactive-default);
406+ text-decoration: none;
407+ }
408+
409+ .related-card:hover .related-card-name {
410+ text-decoration: underline;
411+ }
412+
413+ .related-card-description {
414+ margin: 0;
415+ font: var(--goa-typography-body-s);
416+ color: var(--goa-color-text-secondary);
417+ line-height: 1.5;
418+ display: -webkit-box;
419+ -webkit-line-clamp: 2;
420+ -webkit-box-orient: vertical;
421+ overflow: hidden;
422+ }
423+
424+ .related-card-badge {
425+ margin-top: var(--goa-space-3xs);
426+ }
299427</style >
300428
0 commit comments