Skip to content

Commit

Permalink
fix(BreadCrumb): custom component
Browse files Browse the repository at this point in the history
- allow custom component to be passed
- improve sample
- allow other props to be passed
  • Loading branch information
zettca committed Jun 1, 2023
1 parent 552fb03 commit 9d8fc43
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 121 deletions.
26 changes: 22 additions & 4 deletions packages/core/src/components/BreadCrumb/BreadCrumb.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,21 +89,39 @@ export const WithURLLimited: StoryObj<HvBreadCrumbProps> = {
},
};

export const WithClickEvents: StoryObj<HvBreadCrumbProps> = {
export const WithCustomComponent: StoryObj<HvBreadCrumbProps> = {
parameters: {
docs: {
description: {
story: "Breadcrumb sample that has a onClick defined.",
story:
"Breadcrumb sample with a `CustomNavLink` component that has a custom `onClick` behavior.",
},
},
},
render: () => {
const CustomNavLink = ({ children, to, ariaLabel, ...others }) => (
<a
href={to}
aria-label={ariaLabel}
onClick={() => console.log("clicked", to)}
// make sure to forward other props
{...others}
>
{children}
</a>
);

return (
<HvBreadCrumb
listRoute={data}
listRoute={data.map(({ label, path }) => ({
label,
path: `#${path}`,
to: `#${path}`,
ariaLabel: label,
}))}
id="breadcrumb6"
aria-label="Breadcrumb"
onClick={(event, elem) => console.log(elem.path)}
component={CustomNavLink}
/>
);
},
Expand Down
14 changes: 5 additions & 9 deletions packages/core/src/components/BreadCrumb/BreadCrumb.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { clsx } from "clsx";
import isNil from "lodash/isNil";
import startCase from "lodash/startCase";
import { isValidElement, MouseEventHandler } from "react";
import { isValidElement, MouseEvent } from "react";
import { HvBaseProps } from "@core/types/generic";
import { HvDropDownMenuProps } from "@core/components";
import breadCrumbClasses, { HvBreadCrumbClasses } from "./breadCrumbClasses";
Expand All @@ -14,7 +14,7 @@ import {
} from "./BreadCrumb.styles";
import { pathWithSubMenu, removeExtension } from "./utils";

export interface HvBreadCrumbPathElement {
export interface HvBreadCrumbPathElement extends Record<string, any> {
label: string;
path: string;
}
Expand All @@ -30,10 +30,7 @@ export interface HvBreadCrumbProps
/** The component used for the link node. Either a string to use a DOM element or a component. */
component?: React.ElementType;
/** Function passed to the component. If defined the component prop is used as the link node. */
onClick?: (
event: MouseEventHandler<HTMLAnchorElement>,
data: any
) => void | undefined;
onClick?: (event: MouseEvent<HTMLElement>, data: any) => void;
/** Props passed down to the DropDownMenu sub-menu component. */
dropDownMenuProps?: HvDropDownMenuProps;
/** A Jss Object used to override or extend the styles applied to the component. */
Expand All @@ -51,7 +48,7 @@ export const HvBreadCrumb = ({
maxVisible,
url,
onClick,
component = "div",
component,
dropDownMenuProps,
...others
}: HvBreadCrumbProps) => {
Expand Down Expand Up @@ -130,13 +127,12 @@ export const HvBreadCrumb = ({
</StyledTypography>
)) || (
<HvPage
key={key}
elem={elem}
classes={{
a: clsx(breadCrumbClasses.a, classes?.a),
link: clsx(breadCrumbClasses.link, classes?.link),
}}
Component={onClick ? component : undefined}
component={component}
onClick={onClick}
/>
)}
Expand Down
36 changes: 11 additions & 25 deletions packages/core/src/components/BreadCrumb/Page/Page.styles.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,22 @@
import styled from "@emotion/styled";
import { CSSInterpolation } from "@emotion/css";
import { outlineStyles } from "@hitachivantara/uikit-react-core";
import { theme } from "@hitachivantara/uikit-styles";
import { forwardRef, Ref } from "react";
import {
HvLink,
HvLinkProps,
HvTypography,
HvTypographyProps,
} from "@core/components";

export const StyledLink = styled((props: HvLinkProps) => <HvLink {...props} />)(
{
export const styles = {
link: {
padding: `8px ${theme.space.xs}`,
textDecoration: "none",
borderRadius: theme.radii.base,
maxWidth: 170 + 16,
textTransform: "capitalize",
"&:hover": {
cursor: "pointer",
backgroundColor: theme.colors.atmo3,
},
"&:focus": {
backgroundColor: theme.colors.atmo3,
},
}
);

export const StyledTypography = styled(
forwardRef((props: HvTypographyProps, ref?: Ref<HTMLElement>) => {
return <HvTypography {...props} ref={ref} />;
})
)({
maxWidth: "170px",
textTransform: "capitalize",
"&:hover": {
cursor: "pointer",
backgroundColor: theme.colors.atmo3,
"&:focus-visible": {
...outlineStyles,
},
},
});
} satisfies Record<string, CSSInterpolation>;
82 changes: 41 additions & 41 deletions packages/core/src/components/BreadCrumb/Page/Page.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,51 @@
import { clsx } from "clsx";
import { HvOverflowTooltip } from "@core/components";
import { ClassNames } from "@emotion/react";
import {
HvBreadCrumbPathElement,
HvOverflowTooltip,
HvTypography,
} from "@core/components";
import startCase from "lodash/startCase";
import { MouseEventHandler } from "react";
import { MouseEvent } from "react";
import pageClasses, { HvPageClasses } from "./pageClasses";
import { StyledLink, StyledTypography } from "./Page.styles";

export interface HvPageElement {
path?: string;
label?: string;
}
import { styles } from "./Page.styles";

export interface HvPageProps {
Component?: React.ElementType;
onClick?: (
event: MouseEventHandler<HTMLAnchorElement>,
data: any
) => void | undefined;
elem: HvPageElement;
component?: React.ElementType;
onClick?: (event: MouseEvent<HTMLElement>, data: any) => void;
elem: HvBreadCrumbPathElement;
classes?: HvPageClasses;
}

export const HvPage = ({
/* Component, */ onClick,
elem,
classes,
}: HvPageProps) => {
export const HvPage = ({ component, onClick, elem, classes }: HvPageProps) => {
const { label, path, ...others } = elem;
const handleClick = (event: MouseEvent<HTMLElement>) => {
event.preventDefault();
onClick?.(event, elem);
};

return (
<StyledLink
route={elem.path}
// component={Component}
onClick={onClick}
data={elem}
classes={{ a: clsx(pageClasses.a, classes?.a) }}
>
<StyledTypography
noWrap
component="div"
variant="label"
className={clsx(
pageClasses.link,
classes?.link,
pageClasses.label,
classes?.label
)}
>
<HvOverflowTooltip data={startCase(elem.label)} />
</StyledTypography>
</StyledLink>
<ClassNames>
{({ css, cx }) => (
<HvTypography
noWrap
variant="label"
component={component || "a"}
href={elem.path}
onClick={onClick && handleClick}
className={cx(
css(styles.link),
pageClasses.link,
classes?.link,
pageClasses.label,
classes?.label,
pageClasses.a,
classes?.a
)}
{...others}
>
<HvOverflowTooltip data={startCase(elem.label)} />
</HvTypography>
)}
</ClassNames>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,13 @@ exports[`BreadCrumb > should render correctly 1`] = `
class="HvPathElement-centerContainer HvBreadCrumb-centerContainer css-1sm7i34-StyledLi e14mbcex0"
>
<a
class="e8ovoy91 HvLink-a HvPage-a HvBreadCrumb-a css-nuajcd-StyledA-StyledLink e18zed7a0"
class="HvPage-link HvBreadCrumb-link HvPage-label HvPage-a HvBreadCrumb-a HvTypography-root HvTypography-label HvTypography-noWrap css-fj6trr-getStyledComponent e1tnpalo0"
href="route1"
>
<div
class="HvPage-link HvBreadCrumb-link HvPage-label e8ovoy90 HvTypography-root HvTypography-label HvTypography-noWrap css-6cgeaq-getStyledComponent-StyledTypography e1tnpalo0"
class="HvOverflowTooltip-tooltipAnchor css-trvmb4-StyledDataContainer e199gfye0"
>
<div
class="HvOverflowTooltip-tooltipAnchor css-trvmb4-StyledDataContainer e199gfye0"
>
Label 1
</div>
Label 1
</div>
</a>
<div
Expand All @@ -48,17 +44,13 @@ exports[`BreadCrumb > should render correctly 1`] = `
class="HvPathElement-centerContainer HvBreadCrumb-centerContainer css-1sm7i34-StyledLi e14mbcex0"
>
<a
class="e8ovoy91 HvLink-a HvPage-a HvBreadCrumb-a css-nuajcd-StyledA-StyledLink e18zed7a0"
class="HvPage-link HvBreadCrumb-link HvPage-label HvPage-a HvBreadCrumb-a HvTypography-root HvTypography-label HvTypography-noWrap css-fj6trr-getStyledComponent e1tnpalo0"
href="route2"
>
<div
class="HvPage-link HvBreadCrumb-link HvPage-label e8ovoy90 HvTypography-root HvTypography-label HvTypography-noWrap css-6cgeaq-getStyledComponent-StyledTypography e1tnpalo0"
class="HvOverflowTooltip-tooltipAnchor css-trvmb4-StyledDataContainer e199gfye0"
>
<div
class="HvOverflowTooltip-tooltipAnchor css-trvmb4-StyledDataContainer e199gfye0"
>
Label 2
</div>
Label 2
</div>
</a>
<div
Expand All @@ -84,17 +76,13 @@ exports[`BreadCrumb > should render correctly 1`] = `
class="HvPathElement-centerContainer HvBreadCrumb-centerContainer css-1sm7i34-StyledLi e14mbcex0"
>
<a
class="e8ovoy91 HvLink-a HvPage-a HvBreadCrumb-a css-nuajcd-StyledA-StyledLink e18zed7a0"
class="HvPage-link HvBreadCrumb-link HvPage-label HvPage-a HvBreadCrumb-a HvTypography-root HvTypography-label HvTypography-noWrap css-fj6trr-getStyledComponent e1tnpalo0"
href="route3"
>
<div
class="HvPage-link HvBreadCrumb-link HvPage-label e8ovoy90 HvTypography-root HvTypography-label HvTypography-noWrap css-6cgeaq-getStyledComponent-StyledTypography e1tnpalo0"
class="HvOverflowTooltip-tooltipAnchor css-trvmb4-StyledDataContainer e199gfye0"
>
<div
class="HvOverflowTooltip-tooltipAnchor css-trvmb4-StyledDataContainer e199gfye0"
>
Label 3
</div>
Label 3
</div>
</a>
<div
Expand All @@ -120,17 +108,13 @@ exports[`BreadCrumb > should render correctly 1`] = `
class="HvPathElement-centerContainer HvBreadCrumb-centerContainer css-1sm7i34-StyledLi e14mbcex0"
>
<a
class="e8ovoy91 HvLink-a HvPage-a HvBreadCrumb-a css-nuajcd-StyledA-StyledLink e18zed7a0"
class="HvPage-link HvBreadCrumb-link HvPage-label HvPage-a HvBreadCrumb-a HvTypography-root HvTypography-label HvTypography-noWrap css-fj6trr-getStyledComponent e1tnpalo0"
href="route4"
>
<div
class="HvPage-link HvBreadCrumb-link HvPage-label e8ovoy90 HvTypography-root HvTypography-label HvTypography-noWrap css-6cgeaq-getStyledComponent-StyledTypography e1tnpalo0"
class="HvOverflowTooltip-tooltipAnchor css-trvmb4-StyledDataContainer e199gfye0"
>
<div
class="HvOverflowTooltip-tooltipAnchor css-trvmb4-StyledDataContainer e199gfye0"
>
Label 4
</div>
Label 4
</div>
</a>
<div
Expand All @@ -156,17 +140,13 @@ exports[`BreadCrumb > should render correctly 1`] = `
class="HvPathElement-centerContainer HvBreadCrumb-centerContainer css-1sm7i34-StyledLi e14mbcex0"
>
<a
class="e8ovoy91 HvLink-a HvPage-a HvBreadCrumb-a css-nuajcd-StyledA-StyledLink e18zed7a0"
class="HvPage-link HvBreadCrumb-link HvPage-label HvPage-a HvBreadCrumb-a HvTypography-root HvTypography-label HvTypography-noWrap css-fj6trr-getStyledComponent e1tnpalo0"
href="route5"
>
<div
class="HvPage-link HvBreadCrumb-link HvPage-label e8ovoy90 HvTypography-root HvTypography-label HvTypography-noWrap css-6cgeaq-getStyledComponent-StyledTypography e1tnpalo0"
class="HvOverflowTooltip-tooltipAnchor css-trvmb4-StyledDataContainer e199gfye0"
>
<div
class="HvOverflowTooltip-tooltipAnchor css-trvmb4-StyledDataContainer e199gfye0"
>
Label 5
</div>
Label 5
</div>
</a>
<div
Expand All @@ -192,17 +172,13 @@ exports[`BreadCrumb > should render correctly 1`] = `
class="HvPathElement-centerContainer HvBreadCrumb-centerContainer css-1sm7i34-StyledLi e14mbcex0"
>
<a
class="e8ovoy91 HvLink-a HvPage-a HvBreadCrumb-a css-nuajcd-StyledA-StyledLink e18zed7a0"
class="HvPage-link HvBreadCrumb-link HvPage-label HvPage-a HvBreadCrumb-a HvTypography-root HvTypography-label HvTypography-noWrap css-fj6trr-getStyledComponent e1tnpalo0"
href="route6"
>
<div
class="HvPage-link HvBreadCrumb-link HvPage-label e8ovoy90 HvTypography-root HvTypography-label HvTypography-noWrap css-6cgeaq-getStyledComponent-StyledTypography e1tnpalo0"
class="HvOverflowTooltip-tooltipAnchor css-trvmb4-StyledDataContainer e199gfye0"
>
<div
class="HvOverflowTooltip-tooltipAnchor css-trvmb4-StyledDataContainer e199gfye0"
>
Label 6
</div>
Label 6
</div>
</a>
<div
Expand Down

0 comments on commit 9d8fc43

Please sign in to comment.