Skip to content

Commit

Permalink
Merge pull request #23 from buildo/3105850-implement_breadcrumbs
Browse files Browse the repository at this point in the history
#3105850: Implement Breadcrumbs
  • Loading branch information
veej authored Feb 14, 2022
2 parents 6d482da + 607bc0e commit c1a4682
Show file tree
Hide file tree
Showing 16 changed files with 419 additions and 11 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@
"homepage": "https://github.com/buildo/bento-design-system#readme",
"dependencies": {
"@dessert-box/react": "^0.2.0",
"@react-aria/breadcrumbs": "^3.1.5",
"@react-aria/button": "^3.3.4",
"@react-aria/link": "^3.2.0",
"@react-aria/separator": "^3.1.3",
"@react-aria/textfield": "^3.5.0",
"@vanilla-extract/recipes": "^0.2.3",
Expand Down
130 changes: 129 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

92 changes: 92 additions & 0 deletions src/Breadcrumb/createBreadcrumb.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { useBreadcrumbItem, useBreadcrumbs } from "@react-aria/breadcrumbs";
import { useRef, Fragment, FunctionComponent } from "react";
import { IconProps } from "src/Icons/IconProps";
import { IconChevronRight, Label, LinkProps, LocalizedString } from "../";
import { Box, Inline, BentoSprinkles } from "../internal";

type LastItem = {
label: LocalizedString;
};

type Item = LastItem & {
href: string;
};

export type BreadcrumbProps = {
items: [...Item[], LastItem];
};

type BreadcrumbItemProps = LastItem & Partial<Item> & { isCurrent: boolean };

type BreadcrumbConfig = {
separator: FunctionComponent<IconProps>;
separatorSize: IconProps["size"];
space: BentoSprinkles["gap"];
};

export function createBreadcrumb(
Link: FunctionComponent<LinkProps>,
config: BreadcrumbConfig = {
separator: IconChevronRight,
separatorSize: "8",
space: "16",
}
) {
const BreadcrumbItem = createBreadcrumbItem(Link);
const Separator = config.separator;
return function Breadcrumb(props: BreadcrumbProps) {
const children = (
<Box as="ol">
<Inline space={config.space} alignY="center">
{props.items.map((item, idx) => {
const isCurrent = idx === props.items.length - 1;
return (
<Fragment key={idx}>
<BreadcrumbItem isCurrent={isCurrent} {...item} />
{!isCurrent && (
<Box as="span" aria-hidden="true">
<Separator size={config.separatorSize} />
</Box>
)}
</Fragment>
);
})}
</Inline>
</Box>
);
const { navProps } = useBreadcrumbs({ children });
return (
<Box as="nav" {...navProps} color={undefined}>
{children}
</Box>
);
};
}

function createBreadcrumbItem(Link: FunctionComponent<LinkProps>) {
return function BreadcrumbItem({ isCurrent, label, href = "" }: BreadcrumbItemProps) {
const ref = useRef(null);
const { itemProps } = useBreadcrumbItem(
{ children: label, isCurrent, elementType: "div" },
ref
);

return (
<Box as="li" ref={ref}>
{isCurrent ? (
<Label size="large" {...itemProps} color={undefined}>
{label}
</Label>
) : (
<Link
label={label}
href={href}
title={label}
// NOTE(gabro): we need the cast due to a minor inconsistency in the callback type of FocusEventHandler
{...itemProps}
/>
)}
</Box>
);
};
}
10 changes: 10 additions & 0 deletions src/Icons/IconChevronRight.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { IconProps } from "./IconProps";
import { svgIconProps } from "./svgIconProps";

export function IconChevronRight(props: IconProps) {
return (
<svg {...svgIconProps(props)}>
<path d="M5.627 23.372a2.138 2.138 0 0 0 3.029 0l9.858-9.858a2.14 2.14 0 0 0 0-3.029L8.656.627a2.141 2.141 0 0 0-3.029 3.029l8.334 8.354-8.334 8.334a2.158 2.158 0 0 0 0 3.028Z" />
</svg>
);
}
1 change: 1 addition & 0 deletions src/Icons/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from "./IconCheckCircleSolid";
export * from "./IconChevronRight";
export * from "./IconClose";
export * from "./IconInformative";
export * from "./IconNegative";
Expand Down
9 changes: 9 additions & 0 deletions src/Link/Link.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { bentoSprinkles } from "../internal/sprinkles.css";

export const link = bentoSprinkles({
cursor: {
default: "pointer",
disabled: "notAllowed",
},
outline: "none",
});
Loading

0 comments on commit c1a4682

Please sign in to comment.