Skip to content

Commit

Permalink
feat: align to Salt Vertical Navigation pattern
Browse files Browse the repository at this point in the history
- groups now expand and collapse and do not select a route
- sidebar group label can be defined through frontmatter `sidebar.groupLabel`
- breadcrumbs do not display the root page
- pagination now steps through all pages within the user journey
- paginator buttons show the group, as well as the page title
  • Loading branch information
mark-tate committed Jun 9, 2024
1 parent 0e104bb commit 33247d4
Show file tree
Hide file tree
Showing 28 changed files with 971 additions and 310 deletions.
13 changes: 13 additions & 0 deletions .changeset/large-worms-collect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
'@jpmorganchase/mosaic-plugins': patch
'@jpmorganchase/mosaic-site-components': patch
'@jpmorganchase/mosaic-store': patch
---

feat: align to Salt Vertical Navigation pattern

- groups now expand and collapse and do not select a route
- sidebar group label can be defined through frontmatter `sidebar.groupLabel`
- breadcrumbs do not display the root page
- pagination now steps through all pages within the user journey
- paginator buttons show the group, as well as the page title
19 changes: 19 additions & 0 deletions docs/author/sidebars.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,25 @@ A page can add a `sidebar` property to its [frontmatter](./frontmatter) to chang

To rearrange pages in the sidebar or to apply a different label to a page you can specify the following in the page frontmatter:

### Sidebar group label

A sidebar group when expanded will reveal the pages contained within the group.
Each group has a default page, `index.mdx`, which is the default for the group and any breadcrumb link.

The`index.mdx` can define a `groupLabel` which defines the name of the sidebar group.
If no _groupLabel_ is defined, sidebar group labels will be defined by either _label_ or _title_.

To specify the label of the default page, refer to [Sidebar label](./Sidebar label)

```yaml
---
title: Sidebar Configuration
layout: DetailTechnical
sidebar:
groupLabel: Group label
---
```

### Sidebar label

By default the _title_ of a page is used in the sidebar as the label but this can be changed to another label using page frontmatter.
Expand Down
2 changes: 1 addition & 1 deletion docs/configure/plugins/breadcrumbs-plugin.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ The `BreadcrumbsPlugin` is responsible for generating the data needed to show br

Should a page already have a `breadcrumbs` property in it's metadata then it is respected and not overwritten.

If a page has a `sidebar.label` property in it's metadata then this is used as the label for the breadcrumb, otherwise the page `tile` is used.
If a page has a `sidebar.groupLabel` property in it's metadata then this is used as the label for the breadcrumb, otherwise the page `tile` is used.

When the `BreadcrumbsPlugin` is traversing up directories, it needs to know what page in the directory represents the _breadcrumb_ for that directory. It is recommended to use the `index` page for this but the page to use is a configurable option of the breadcrumbs plugin.

Expand Down
54 changes: 29 additions & 25 deletions packages/plugins/src/BreadcrumbsPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,37 +26,41 @@ const BreadcrumbsPlugin: PluginType<BreadcrumbsPluginPage, BreadcrumbsPluginOpti
continue;
}
try {
const breadcrumbs: Array<Breadcrumb> = [];
let currentPage = page;
let parentDir = path.posix.normalize(path.posix.dirname(currentPage.fullPath));
const maxBreadcrumbCount = page.fullPath.split('/').length;

while (currentPage !== undefined && breadcrumbs.length < maxBreadcrumbCount) {
breadcrumbs.unshift({
label: currentPage.sidebar?.label || currentPage.title,
path: currentPage.route,
id: currentPage.fullPath
});

currentPage = pages.find(
// eslint-disable-next-line @typescript-eslint/no-loop-func
item => item.fullPath === path.posix.join(parentDir, options.indexPageName)
);
if (currentPage) {
parentDir = path.posix.dirname(path.posix.join(String(currentPage.fullPath), '..'));
}
}

const pathParts = page.fullPath.replace(/^[/]/, '').split('/');
const topAndTailedPath = pathParts.slice(1, -1);
const breadcrumbs = topAndTailedPath.reduce<Breadcrumb[]>(
(result, _pathPart, partIndex) => {
const breadcrumbRoot = `/${pathParts[0]}`;
const breadcrumbPath = path.join(
breadcrumbRoot,
...topAndTailedPath.slice(0, topAndTailedPath.length - partIndex),
options.indexPageName
);
const breadcrumbPage = pages.find(
// eslint-disable-next-line @typescript-eslint/no-loop-func
item => item.fullPath === breadcrumbPath
);
if (breadcrumbPage) {
result.unshift({
label:
breadcrumbPage.sidebar?.groupLabel ||
breadcrumbPage.sidebar?.label ||
breadcrumbPage.title,
path: breadcrumbPage.route,
id: breadcrumbPage.fullPath
});
}
return result;
},
[]
);
if (!page.breadcrumbs) {
// filter out any duplicate breadcrumbs
const map = new Map(breadcrumbs.map(crumb => [crumb.id, crumb]));
page.breadcrumbs = [...map.values()];
page.breadcrumbs = breadcrumbs;
}
} catch (e) {
throw new PluginError(e.message, page.fullPath);
}
}

return pages;
},
async afterNamespaceSourceUpdate(
Expand Down
Loading

0 comments on commit 33247d4

Please sign in to comment.