Skip to content

Commit

Permalink
Refactor Breadcrumbs to remove lab component usage (#630)
Browse files Browse the repository at this point in the history
  • Loading branch information
joshwooding authored Jul 23, 2024
1 parent 24551c8 commit 182a430
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 39 deletions.
5 changes: 5 additions & 0 deletions .changeset/fifty-peaches-change.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@jpmorganchase/mosaic-plugins': patch
---

Fixed BreadcrumbsPlugin not working on Windows.
6 changes: 6 additions & 0 deletions .changeset/pretty-socks-judge.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@jpmorganchase/mosaic-site-components': minor
---

Refactor Breadcrumbs to remove usage of lab components.
Fixed non-unique key error in AppHeaderControls.
2 changes: 1 addition & 1 deletion packages/plugins/src/BreadcrumbsPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const BreadcrumbsPlugin: PluginType<BreadcrumbsPluginPage, BreadcrumbsPluginOpti
const breadcrumbs = topAndTailedPath.reduce<Breadcrumb[]>(
(result, _pathPart, partIndex) => {
const breadcrumbRoot = `/${pathParts[0]}`;
const breadcrumbPath = path.join(
const breadcrumbPath = path.posix.join(
breadcrumbRoot,
...topAndTailedPath.slice(0, topAndTailedPath.length - partIndex),
options.indexPageName
Expand Down
4 changes: 3 additions & 1 deletion packages/site-components/src/AppHeaderControls/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@ export const AppHeaderControls: React.FC = () => {
</MenuTrigger>
<MenuPanel>
{actionMenuOptions.map(option => (
<MenuItem onClick={option.onSelect}>{option.title}</MenuItem>
<MenuItem key={option.title} onClick={option.onSelect}>
{option.title}
</MenuItem>
))}
</MenuPanel>
</Menu>
Expand Down
23 changes: 14 additions & 9 deletions packages/site-components/src/Breadcrumbs/Breadcrumb.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,33 @@
import React, { forwardRef, ReactNode } from 'react';
import { Link } from '@jpmorganchase/mosaic-components';
import { Icon, Link } from '@jpmorganchase/mosaic-components';

import styles from './styles.css';

export interface BreadcrumbProps {
children?: ReactNode;
href?: string;
isCurrentLevel?: boolean;
overflowLabel?: string;
hideSeparator?: boolean;
}

// TODO replace with Salt Breadcrumb when it supports an API that can customize Links
export const Breadcrumb = forwardRef<HTMLAnchorElement, BreadcrumbProps>(function Breadcrumb(
{ children, isCurrentLevel, ...props },
{ children, isCurrentLevel, href, hideSeparator },
ref
) {
return (
<li className={styles.wrapper}>
<li className={styles.breadcrumb}>
{isCurrentLevel ? (
<span>{children}</span>
<>
{!hideSeparator && <Icon name="chevronRight" aria-hidden />}
<span>{children}</span>
</>
) : (
<Link endIcon="none" ref={ref} variant="regular" {...props}>
{children}
</Link>
<>
<Link endIcon="none" ref={ref} variant="regular" href={href}>
{children}
</Link>
{!hideSeparator && <Icon name="chevronRight" aria-hidden />}
</>
)}
</li>
);
Expand Down
80 changes: 53 additions & 27 deletions packages/site-components/src/Breadcrumbs/Breadcrumbs.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React from 'react';
import { useRouter } from 'next/router';
import { Breadcrumbs as SaltBreadcrumbs } from '@salt-ds/lab';
import { Breadcrumb } from './Breadcrumb';
import { Menu, MenuItem, MenuPanel, MenuTrigger } from '@salt-ds/core';
import { Button, Icon } from '@jpmorganchase/mosaic-components';

import styles from './styles.css';
import { Breadcrumb } from './Breadcrumb';

export type BreadcrumbProps = {
id: string;
Expand All @@ -22,36 +23,61 @@ export const Breadcrumbs: React.FC<BreadcrumbsProps> = ({ breadcrumbs, enabled }
return null;
}

/**
* TODO - we need appropriate keyboard nav support as well
* The slat cascading menu keyboard nav does not seem to work
* so not much point adding support for enter key selection here
*/
const handleClick = (event: React.MouseEvent<HTMLDivElement>) => {
const target = event.target as HTMLDivElement;
if (target.classList.contains('saltMenuItem-menuItemText')) {
const breadcrumbIndex = breadcrumbs.findIndex(
breadcrumb => breadcrumb.label.toLowerCase() === target.textContent?.toLowerCase()
);

if (breadcrumbIndex > -1) {
router.push(breadcrumbs[breadcrumbIndex].path);
}
const path = event.currentTarget.getAttribute('data-path');
if (path) {
router.push(path);
}
};

const maxItems = 5;
const itemsBeforeCollapse = 1;

let visibleItemsBefore = breadcrumbs;
let hiddenItems: typeof breadcrumbs = [];
let visibleItemsAfter: typeof breadcrumbs = [];

if (breadcrumbs.length > maxItems) {
visibleItemsBefore = breadcrumbs.slice(0, itemsBeforeCollapse);
hiddenItems = breadcrumbs.slice(itemsBeforeCollapse, -1);
visibleItemsAfter = breadcrumbs.slice(visibleItemsBefore.length + hiddenItems.length);
}

return (
<div onClick={handleClick}>
<SaltBreadcrumbs className={styles.root} itemsBeforeCollapse={2} maxItems={5}>
{breadcrumbs.map(
value =>
value && (
<Breadcrumb href={value.path} key={`${value.id}`} overflowLabel={value.label}>
{value.label}
</Breadcrumb>
)
<nav className={styles.root} aria-label="Breadcrumbs">
<ol className={styles.ol}>
{visibleItemsBefore.map(({ id, label, path }, index) => (
<Breadcrumb
key={id}
href={path}
isCurrentLevel={index === breadcrumbs.length - 1}
hideSeparator={index === breadcrumbs.length - 1}
>
{label}
</Breadcrumb>
))}
{hiddenItems.length > 0 && (
<Menu>
<MenuTrigger>
<Button variant="secondary" aria-label="Open Menu">
<Icon name="overflowMenu" aria-hidden />
</Button>
</MenuTrigger>
<MenuPanel>
{hiddenItems.map(({ id, label, path }) => (
<MenuItem key={id} data-path={path} onClick={handleClick}>
{label}
</MenuItem>
))}
</MenuPanel>
</Menu>
)}
</SaltBreadcrumbs>
</div>
{visibleItemsAfter.map(({ id, label, path }) => (
<Breadcrumb key={id} href={path} isCurrentLevel>
{label}
</Breadcrumb>
))}
</ol>
</nav>
);
};
24 changes: 23 additions & 1 deletion packages/site-components/src/Breadcrumbs/styles.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,27 @@ export default {
paddingBottom: ['x4', 'x4', 'x4', 'x4']
})
]),
wrapper: unorderedListItem({ variant: 'blank', size: 'small' })
ol: style([
{
display: 'flex',
padding: 0,
listStyle: 'none',
alignItems: 'center',
justifyContent: 'flex-start'
},
responsiveSprinkles({
gap: ['x2', 'x2', 'x2', 'x2']
})
]),
breadcrumb: style([
{
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-start'
},
responsiveSprinkles({
gap: ['x2', 'x2', 'x2', 'x2']
}),
unorderedListItem({ variant: 'blank', size: 'small' })
])
};

0 comments on commit 182a430

Please sign in to comment.