Skip to content

Commit

Permalink
fix(nx-dev): breadcrumb casing (#29032)
Browse files Browse the repository at this point in the history
Fixes the breadcrumb component to show actual page titles instead of
just capitalizing the url segments
  • Loading branch information
isaacplmann authored Nov 21, 2024
1 parent c3d53a4 commit a1efb63
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 27 deletions.
21 changes: 21 additions & 0 deletions nx-dev/data-access-documents/src/lib/documents.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,27 @@ export class DocumentsApi {
name: document.name,
mediaImage: document.mediaImage || '',
relatedDocuments: this.getRelatedDocuments(document.tags),
parentDocuments: path.map((segment, index): RelatedDocument => {
const parentPath = path.slice(0, index + 1).join('/');
const parentDocument =
this.manifest[this.getManifestKey(parentPath)] || null;
if (!parentDocument) {
return {
id: segment,
name: '',
description: '',
file: '',
path: '/' + path.slice(0, index + 1).join('/'),
};
}
return {
id: parentDocument.id,
name: parentDocument.name,
description: parentDocument.description,
file: parentDocument.file,
path: parentDocument.path,
};
}),
tags: document.tags,
};
}
Expand Down
2 changes: 1 addition & 1 deletion nx-dev/feature-doc-viewer/src/lib/doc-viewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export function DocViewer({
<div className="mx-auto w-full grow items-stretch px-4 sm:px-6 lg:px-8 2xl:max-w-6xl">
<div id="content-wrapper" className="w-full flex-auto flex-col">
<div className="mb-6 pt-8">
<Breadcrumbs path={router.asPath} />
<Breadcrumbs document={document} />
</div>
<div className="min-w-0 flex-auto pb-24 lg:pb-16">
{/*MAIN CONTENT*/}
Expand Down
1 change: 1 addition & 0 deletions nx-dev/models-document/src/lib/documents.models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export interface ProcessedDocument {
id: string;
name: string;
relatedDocuments: Record<string, RelatedDocument[]>;
parentDocuments?: RelatedDocument[];
tags: string[];
}

Expand Down
98 changes: 72 additions & 26 deletions nx-dev/ui-common/src/lib/breadcrumbs.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,80 @@
import { ChevronRightIcon } from '@heroicons/react/24/solid';
import { ProcessedDocument } from '@nx/nx-dev/models-document';
import classNames from 'classnames';

export function Breadcrumbs({ path }: { path: string }): JSX.Element {
const cleanedPath = path.includes('?')
? path.slice(0, path.indexOf('?'))
: path;
const pages = [
...cleanedPath
.split('/')
.filter(Boolean)
.map((segment, index, segments) => ({
name: segment.includes('#')
? segment.slice(0, segment.indexOf('#'))
: segment,
// We do not have dedicated page view for executors & generators
href: '/' + segments.slice(0, index + 1).join('/'),
current: '/' + segments.slice(0, index + 1).join('/') === cleanedPath,
})),
];

if (pages.length === 1) {
interface Crumb {
id: string;
name: string;
href: string;
current: boolean;
}

const sectionNames: Record<string, string> = {
ci: 'CI',
'extending-nx': 'Extending Nx',
'nx-api': 'Nx API',
};

const capitalize = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);

export function Breadcrumbs({
document,
path,
}: {
document?: ProcessedDocument;
path?: string;
}): JSX.Element {
let crumbs: Crumb[] = [];

if (path) {
const cleanedPath = path.includes('?')
? path.slice(0, path.indexOf('?'))
: path;
crumbs = [
...cleanedPath
.split('/')
.filter(Boolean)
.map((segment, index, segments) => {
const strippedName = segment.includes('#')
? segment.slice(0, segment.indexOf('#'))
: segment;
const name =
sectionNames[strippedName] ||
strippedName.split('-').map(capitalize).join(' ');
return {
id: segment,
name,
// We do not have dedicated page view for executors & generators
href: '/' + segments.slice(0, index + 1).join('/'),
current:
'/' + segments.slice(0, index + 1).join('/') === cleanedPath,
};
}),
];
}

if (document && document.parentDocuments) {
crumbs = document.parentDocuments.map((parentDocument, index) => ({
id: parentDocument.id,
name:
parentDocument.name ||
sectionNames[parentDocument.id] ||
parentDocument.id.split('-').map(capitalize).join(' '),
href: parentDocument.path,
current: index + 1 === document.parentDocuments?.length,
}));
}

if (crumbs.length < 2) {
return <></>;
}

return (
<div>
<nav className="flex" aria-labelledby="breadcrumb">
<ol role="list" className="flex items-center space-x-4">
{pages.map((page, index) => (
<li key={page.name.concat('-', index.toString())}>
{crumbs.map((crumb, index) => (
<li key={crumb.id.concat('-', index.toString())}>
<div className="flex items-center">
{!!index && (
<ChevronRightIcon
Expand All @@ -37,15 +83,15 @@ export function Breadcrumbs({ path }: { path: string }): JSX.Element {
/>
)}
<a
href={page.href}
href={crumb.href}
className={classNames(
'text-sm font-medium capitalize hover:text-slate-600',
page.current ? 'text-slate-600' : 'text-slate-400',
'text-sm font-medium hover:text-slate-600',
crumb.current ? 'text-slate-600' : 'text-slate-400',
!!index ? 'ml-4' : ''
)}
aria-current={page.current ? 'page' : undefined}
aria-current={crumb.current ? 'page' : undefined}
>
{page.name.replace(/-/gi, ' ')}
{crumb.name}
</a>
</div>
</li>
Expand Down

0 comments on commit a1efb63

Please sign in to comment.