@sproutsocial/seeds-react-breadcrumb 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +6 -0
- package/.eslintrc.js +4 -0
- package/.turbo/turbo-build.log +21 -0
- package/CHANGELOG.md +8 -0
- package/dist/esm/index.js +90 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/index.d.mts +26 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.js +127 -0
- package/dist/index.js.map +1 -0
- package/jest.config.js +9 -0
- package/package.json +45 -0
- package/src/Breadcrumb.stories.tsx +94 -0
- package/src/Breadcrumb.tsx +56 -0
- package/src/BreadcrumbTypes.ts +22 -0
- package/src/__tests__/Breadcrumb.typetest.tsx +54 -0
- package/src/__tests__/breadcrumb.test.tsx +71 -0
- package/src/index.ts +5 -0
- package/src/styled.d.ts +7 -0
- package/src/styles.ts +44 -0
- package/tsconfig.json +9 -0
- package/tsup.config.ts +12 -0
package/.eslintignore
ADDED
package/.eslintrc.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
yarn run v1.22.22
|
|
2
|
+
$ tsup --dts
|
|
3
|
+
CLI Building entry: src/index.ts
|
|
4
|
+
CLI Using tsconfig: tsconfig.json
|
|
5
|
+
CLI tsup v8.0.2
|
|
6
|
+
CLI Using tsup config: /home/runner/work/seeds/seeds/seeds-react/seeds-react-breadcrumb/tsup.config.ts
|
|
7
|
+
CLI Target: es2022
|
|
8
|
+
CLI Cleaning output folder
|
|
9
|
+
CJS Build start
|
|
10
|
+
ESM Build start
|
|
11
|
+
CJS dist/index.js 4.13 KB
|
|
12
|
+
CJS dist/index.js.map 4.71 KB
|
|
13
|
+
CJS ⚡️ Build success in 84ms
|
|
14
|
+
ESM dist/esm/index.js 2.28 KB
|
|
15
|
+
ESM dist/esm/index.js.map 4.64 KB
|
|
16
|
+
ESM ⚡️ Build success in 86ms
|
|
17
|
+
DTS Build start
|
|
18
|
+
DTS ⚡️ Build success in 12429ms
|
|
19
|
+
DTS dist/index.d.ts 1.09 KB
|
|
20
|
+
DTS dist/index.d.mts 1.09 KB
|
|
21
|
+
Done in 16.96s.
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// src/Breadcrumb.tsx
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import Link from "@sproutsocial/seeds-react-link";
|
|
4
|
+
|
|
5
|
+
// src/styles.ts
|
|
6
|
+
import styled from "styled-components";
|
|
7
|
+
var Nav = styled.nav`
|
|
8
|
+
ol {
|
|
9
|
+
${(props) => props.theme.typography[200]};
|
|
10
|
+
margin: 0;
|
|
11
|
+
font-family: ${(props) => props.theme.fontFamily};
|
|
12
|
+
padding: 0;
|
|
13
|
+
display: flex;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
li {
|
|
17
|
+
margin-right: ${(props) => props.theme.space[200]};
|
|
18
|
+
display: flex;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
a,
|
|
22
|
+
button {
|
|
23
|
+
${(props) => props.theme.typography[200]};
|
|
24
|
+
max-width: 200px;
|
|
25
|
+
overflow: hidden;
|
|
26
|
+
text-overflow: ellipsis;
|
|
27
|
+
white-space: nowrap;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
ol > div + li::before {
|
|
31
|
+
content: "/";
|
|
32
|
+
margin-right: ${(props) => props.theme.space[200]};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
li:last-child a,
|
|
36
|
+
li:last-child button {
|
|
37
|
+
color: ${(props) => props.theme.colors.text.body};
|
|
38
|
+
font-weight: bold;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
li:not(:last-child)::after {
|
|
42
|
+
content: "/";
|
|
43
|
+
color: ${(props) => props.theme.colors.text.body};
|
|
44
|
+
margin-left: ${(props) => props.theme.space[200]};
|
|
45
|
+
}
|
|
46
|
+
`;
|
|
47
|
+
var styles_default = Nav;
|
|
48
|
+
|
|
49
|
+
// src/Breadcrumb.tsx
|
|
50
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
51
|
+
var BreadcrumbItem = ({
|
|
52
|
+
children,
|
|
53
|
+
href,
|
|
54
|
+
...rest
|
|
55
|
+
}) => {
|
|
56
|
+
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(Link, { href, ...rest, children }) });
|
|
57
|
+
};
|
|
58
|
+
var Breadcrumb = ({
|
|
59
|
+
ariaLabel,
|
|
60
|
+
overflow,
|
|
61
|
+
children,
|
|
62
|
+
...rest
|
|
63
|
+
}) => {
|
|
64
|
+
const listItems = React.Children.toArray(children);
|
|
65
|
+
const lastItem = listItems[listItems.length - 1];
|
|
66
|
+
return /* @__PURE__ */ jsx(styles_default, { "aria-label": ariaLabel, "data-qa-breadcrumb": ariaLabel, ...rest, children: /* @__PURE__ */ jsxs("ol", { children: [
|
|
67
|
+
overflow && /* @__PURE__ */ jsx("li", { children: overflow.menu }),
|
|
68
|
+
listItems.map((item, i) => {
|
|
69
|
+
const itemElem = typeof item === "object" && "props" in item ? item : /* @__PURE__ */ jsx("span", { children: "item" });
|
|
70
|
+
return React.cloneElement(itemElem, {
|
|
71
|
+
...itemElem.props,
|
|
72
|
+
"aria-current": listItems[i] === lastItem ? "page" : void 0
|
|
73
|
+
});
|
|
74
|
+
})
|
|
75
|
+
] }) });
|
|
76
|
+
};
|
|
77
|
+
BreadcrumbItem.displayName = "Breadcrumb.Item";
|
|
78
|
+
Breadcrumb.Item = BreadcrumbItem;
|
|
79
|
+
var Breadcrumb_default = Breadcrumb;
|
|
80
|
+
|
|
81
|
+
// src/BreadcrumbTypes.ts
|
|
82
|
+
import "react";
|
|
83
|
+
|
|
84
|
+
// src/index.ts
|
|
85
|
+
var src_default = Breadcrumb_default;
|
|
86
|
+
export {
|
|
87
|
+
Breadcrumb_default as Breadcrumb,
|
|
88
|
+
src_default as default
|
|
89
|
+
};
|
|
90
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/Breadcrumb.tsx","../../src/styles.ts","../../src/BreadcrumbTypes.ts","../../src/index.ts"],"sourcesContent":["import * as React from \"react\";\nimport Link from \"@sproutsocial/seeds-react-link\";\nimport Nav from \"./styles\";\nimport type {\n TypeBreadcrumbProps,\n TypeBreadcrumbItemProps,\n} from \"./BreadcrumbTypes\";\n\nconst BreadcrumbItem = ({\n children,\n href,\n ...rest\n}: TypeBreadcrumbItemProps) => {\n return (\n <li>\n <Link href={href} {...rest}>\n {children}\n </Link>\n </li>\n );\n};\n\nconst Breadcrumb = ({\n ariaLabel,\n overflow,\n children,\n ...rest\n}: TypeBreadcrumbProps) => {\n const listItems = React.Children.toArray(children);\n const lastItem = listItems[listItems.length - 1];\n return (\n <Nav aria-label={ariaLabel} data-qa-breadcrumb={ariaLabel} {...rest}>\n <ol>\n {overflow && <li>{overflow.menu}</li>}\n {listItems.map((item, i) => {\n // @ts-notes - item is a childNode which can be a string or number but `cloneElement` requires props\n const itemElem =\n typeof item === \"object\" && \"props\" in item ? (\n item\n ) : (\n <span>item</span>\n );\n return React.cloneElement(itemElem, {\n ...itemElem.props,\n \"aria-current\": listItems[i] === lastItem ? \"page\" : undefined,\n });\n })}\n </ol>\n </Nav>\n );\n};\n\nBreadcrumbItem.displayName = \"Breadcrumb.Item\";\nBreadcrumb.Item = BreadcrumbItem;\n\nexport default Breadcrumb;\n","import styled from \"styled-components\";\n\nconst Nav = styled.nav`\n ol {\n ${(props) => props.theme.typography[200]};\n margin: 0;\n font-family: ${(props) => props.theme.fontFamily};\n padding: 0;\n display: flex;\n }\n\n li {\n margin-right: ${(props) => props.theme.space[200]};\n display: flex;\n }\n\n a,\n button {\n ${(props) => props.theme.typography[200]};\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n ol > div + li::before {\n content: \"/\";\n margin-right: ${(props) => props.theme.space[200]};\n }\n\n li:last-child a,\n li:last-child button {\n color: ${(props) => props.theme.colors.text.body};\n font-weight: bold;\n }\n\n li:not(:last-child)::after {\n content: \"/\";\n color: ${(props) => props.theme.colors.text.body};\n margin-left: ${(props) => props.theme.space[200]};\n }\n`;\n\nexport default Nav;\n","import * as React from \"react\";\nimport type {\n TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nexport type { TypeLinkProps as TypeBreadcrumbItemProps } from \"@sproutsocial/seeds-react-link\";\n\nexport interface TypeBreadcrumbProps\n extends TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n Omit<React.ComponentPropsWithoutRef<\"nav\">, \"color\"> {\n children: React.ReactNode;\n\n /** Description of the type of navigation being provided by the breadcrumb (i.e. \"Asset library breadcrumb\") */\n ariaLabel: string;\n\n /** optional */\n overflow?: {\n label: string;\n menu: React.ReactNode;\n };\n}\n","import Breadcrumb from \"./Breadcrumb\";\n\nexport default Breadcrumb;\nexport { Breadcrumb };\nexport * from \"./BreadcrumbTypes\";\n"],"mappings":";AAAA,YAAY,WAAW;AACvB,OAAO,UAAU;;;ACDjB,OAAO,YAAY;AAEnB,IAAM,MAAM,OAAO;AAAA;AAAA,MAEb,CAAC,UAAU,MAAM,MAAM,WAAW,GAAG,CAAC;AAAA;AAAA,mBAEzB,CAAC,UAAU,MAAM,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAMhC,CAAC,UAAU,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAM/C,CAAC,UAAU,MAAM,MAAM,WAAW,GAAG,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBASxB,CAAC,UAAU,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,aAKxC,CAAC,UAAU,MAAM,MAAM,OAAO,KAAK,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAMvC,CAAC,UAAU,MAAM,MAAM,OAAO,KAAK,IAAI;AAAA,mBACjC,CAAC,UAAU,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA;AAAA;AAIpD,IAAO,iBAAQ;;;AD5BT,cAiBA,YAjBA;AAPN,IAAM,iBAAiB,CAAC;AAAA,EACtB;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAA+B;AAC7B,SACE,oBAAC,QACC,8BAAC,QAAK,MAAa,GAAG,MACnB,UACH,GACF;AAEJ;AAEA,IAAM,aAAa,CAAC;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAA2B;AACzB,QAAM,YAAkB,eAAS,QAAQ,QAAQ;AACjD,QAAM,WAAW,UAAU,UAAU,SAAS,CAAC;AAC/C,SACE,oBAAC,kBAAI,cAAY,WAAW,sBAAoB,WAAY,GAAG,MAC7D,+BAAC,QACE;AAAA,gBAAY,oBAAC,QAAI,mBAAS,MAAK;AAAA,IAC/B,UAAU,IAAI,CAAC,MAAM,MAAM;AAE1B,YAAM,WACJ,OAAO,SAAS,YAAY,WAAW,OACrC,OAEA,oBAAC,UAAK,kBAAI;AAEd,aAAa,mBAAa,UAAU;AAAA,QAClC,GAAG,SAAS;AAAA,QACZ,gBAAgB,UAAU,CAAC,MAAM,WAAW,SAAS;AAAA,MACvD,CAAC;AAAA,IACH,CAAC;AAAA,KACH,GACF;AAEJ;AAEA,eAAe,cAAc;AAC7B,WAAW,OAAO;AAElB,IAAO,qBAAQ;;;AEvDf,OAAuB;;;ACEvB,IAAO,cAAQ;","names":[]}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { TypeStyledComponentsCommonProps, TypeSystemCommonProps } from '@sproutsocial/seeds-react-system-props';
|
|
4
|
+
import { TypeLinkProps } from '@sproutsocial/seeds-react-link';
|
|
5
|
+
export { TypeLinkProps as TypeBreadcrumbItemProps } from '@sproutsocial/seeds-react-link';
|
|
6
|
+
|
|
7
|
+
interface TypeBreadcrumbProps extends TypeStyledComponentsCommonProps, TypeSystemCommonProps, Omit<React.ComponentPropsWithoutRef<"nav">, "color"> {
|
|
8
|
+
children: React.ReactNode;
|
|
9
|
+
/** Description of the type of navigation being provided by the breadcrumb (i.e. "Asset library breadcrumb") */
|
|
10
|
+
ariaLabel: string;
|
|
11
|
+
/** optional */
|
|
12
|
+
overflow?: {
|
|
13
|
+
label: string;
|
|
14
|
+
menu: React.ReactNode;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
declare const Breadcrumb: {
|
|
19
|
+
({ ariaLabel, overflow, children, ...rest }: TypeBreadcrumbProps): react_jsx_runtime.JSX.Element;
|
|
20
|
+
Item: {
|
|
21
|
+
({ children, href, ...rest }: TypeLinkProps): react_jsx_runtime.JSX.Element;
|
|
22
|
+
displayName: string;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export { Breadcrumb, type TypeBreadcrumbProps, Breadcrumb as default };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { TypeStyledComponentsCommonProps, TypeSystemCommonProps } from '@sproutsocial/seeds-react-system-props';
|
|
4
|
+
import { TypeLinkProps } from '@sproutsocial/seeds-react-link';
|
|
5
|
+
export { TypeLinkProps as TypeBreadcrumbItemProps } from '@sproutsocial/seeds-react-link';
|
|
6
|
+
|
|
7
|
+
interface TypeBreadcrumbProps extends TypeStyledComponentsCommonProps, TypeSystemCommonProps, Omit<React.ComponentPropsWithoutRef<"nav">, "color"> {
|
|
8
|
+
children: React.ReactNode;
|
|
9
|
+
/** Description of the type of navigation being provided by the breadcrumb (i.e. "Asset library breadcrumb") */
|
|
10
|
+
ariaLabel: string;
|
|
11
|
+
/** optional */
|
|
12
|
+
overflow?: {
|
|
13
|
+
label: string;
|
|
14
|
+
menu: React.ReactNode;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
declare const Breadcrumb: {
|
|
19
|
+
({ ariaLabel, overflow, children, ...rest }: TypeBreadcrumbProps): react_jsx_runtime.JSX.Element;
|
|
20
|
+
Item: {
|
|
21
|
+
({ children, href, ...rest }: TypeLinkProps): react_jsx_runtime.JSX.Element;
|
|
22
|
+
displayName: string;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export { Breadcrumb, type TypeBreadcrumbProps, Breadcrumb as default };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var src_exports = {};
|
|
32
|
+
__export(src_exports, {
|
|
33
|
+
Breadcrumb: () => Breadcrumb_default,
|
|
34
|
+
default: () => src_default
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(src_exports);
|
|
37
|
+
|
|
38
|
+
// src/Breadcrumb.tsx
|
|
39
|
+
var React = __toESM(require("react"));
|
|
40
|
+
var import_seeds_react_link = __toESM(require("@sproutsocial/seeds-react-link"));
|
|
41
|
+
|
|
42
|
+
// src/styles.ts
|
|
43
|
+
var import_styled_components = __toESM(require("styled-components"));
|
|
44
|
+
var Nav = import_styled_components.default.nav`
|
|
45
|
+
ol {
|
|
46
|
+
${(props) => props.theme.typography[200]};
|
|
47
|
+
margin: 0;
|
|
48
|
+
font-family: ${(props) => props.theme.fontFamily};
|
|
49
|
+
padding: 0;
|
|
50
|
+
display: flex;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
li {
|
|
54
|
+
margin-right: ${(props) => props.theme.space[200]};
|
|
55
|
+
display: flex;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
a,
|
|
59
|
+
button {
|
|
60
|
+
${(props) => props.theme.typography[200]};
|
|
61
|
+
max-width: 200px;
|
|
62
|
+
overflow: hidden;
|
|
63
|
+
text-overflow: ellipsis;
|
|
64
|
+
white-space: nowrap;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
ol > div + li::before {
|
|
68
|
+
content: "/";
|
|
69
|
+
margin-right: ${(props) => props.theme.space[200]};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
li:last-child a,
|
|
73
|
+
li:last-child button {
|
|
74
|
+
color: ${(props) => props.theme.colors.text.body};
|
|
75
|
+
font-weight: bold;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
li:not(:last-child)::after {
|
|
79
|
+
content: "/";
|
|
80
|
+
color: ${(props) => props.theme.colors.text.body};
|
|
81
|
+
margin-left: ${(props) => props.theme.space[200]};
|
|
82
|
+
}
|
|
83
|
+
`;
|
|
84
|
+
var styles_default = Nav;
|
|
85
|
+
|
|
86
|
+
// src/Breadcrumb.tsx
|
|
87
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
88
|
+
var BreadcrumbItem = ({
|
|
89
|
+
children,
|
|
90
|
+
href,
|
|
91
|
+
...rest
|
|
92
|
+
}) => {
|
|
93
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_seeds_react_link.default, { href, ...rest, children }) });
|
|
94
|
+
};
|
|
95
|
+
var Breadcrumb = ({
|
|
96
|
+
ariaLabel,
|
|
97
|
+
overflow,
|
|
98
|
+
children,
|
|
99
|
+
...rest
|
|
100
|
+
}) => {
|
|
101
|
+
const listItems = React.Children.toArray(children);
|
|
102
|
+
const lastItem = listItems[listItems.length - 1];
|
|
103
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(styles_default, { "aria-label": ariaLabel, "data-qa-breadcrumb": ariaLabel, ...rest, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("ol", { children: [
|
|
104
|
+
overflow && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", { children: overflow.menu }),
|
|
105
|
+
listItems.map((item, i) => {
|
|
106
|
+
const itemElem = typeof item === "object" && "props" in item ? item : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "item" });
|
|
107
|
+
return React.cloneElement(itemElem, {
|
|
108
|
+
...itemElem.props,
|
|
109
|
+
"aria-current": listItems[i] === lastItem ? "page" : void 0
|
|
110
|
+
});
|
|
111
|
+
})
|
|
112
|
+
] }) });
|
|
113
|
+
};
|
|
114
|
+
BreadcrumbItem.displayName = "Breadcrumb.Item";
|
|
115
|
+
Breadcrumb.Item = BreadcrumbItem;
|
|
116
|
+
var Breadcrumb_default = Breadcrumb;
|
|
117
|
+
|
|
118
|
+
// src/BreadcrumbTypes.ts
|
|
119
|
+
var React2 = require("react");
|
|
120
|
+
|
|
121
|
+
// src/index.ts
|
|
122
|
+
var src_default = Breadcrumb_default;
|
|
123
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
124
|
+
0 && (module.exports = {
|
|
125
|
+
Breadcrumb
|
|
126
|
+
});
|
|
127
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/Breadcrumb.tsx","../src/styles.ts","../src/BreadcrumbTypes.ts"],"sourcesContent":["import Breadcrumb from \"./Breadcrumb\";\n\nexport default Breadcrumb;\nexport { Breadcrumb };\nexport * from \"./BreadcrumbTypes\";\n","import * as React from \"react\";\nimport Link from \"@sproutsocial/seeds-react-link\";\nimport Nav from \"./styles\";\nimport type {\n TypeBreadcrumbProps,\n TypeBreadcrumbItemProps,\n} from \"./BreadcrumbTypes\";\n\nconst BreadcrumbItem = ({\n children,\n href,\n ...rest\n}: TypeBreadcrumbItemProps) => {\n return (\n <li>\n <Link href={href} {...rest}>\n {children}\n </Link>\n </li>\n );\n};\n\nconst Breadcrumb = ({\n ariaLabel,\n overflow,\n children,\n ...rest\n}: TypeBreadcrumbProps) => {\n const listItems = React.Children.toArray(children);\n const lastItem = listItems[listItems.length - 1];\n return (\n <Nav aria-label={ariaLabel} data-qa-breadcrumb={ariaLabel} {...rest}>\n <ol>\n {overflow && <li>{overflow.menu}</li>}\n {listItems.map((item, i) => {\n // @ts-notes - item is a childNode which can be a string or number but `cloneElement` requires props\n const itemElem =\n typeof item === \"object\" && \"props\" in item ? (\n item\n ) : (\n <span>item</span>\n );\n return React.cloneElement(itemElem, {\n ...itemElem.props,\n \"aria-current\": listItems[i] === lastItem ? \"page\" : undefined,\n });\n })}\n </ol>\n </Nav>\n );\n};\n\nBreadcrumbItem.displayName = \"Breadcrumb.Item\";\nBreadcrumb.Item = BreadcrumbItem;\n\nexport default Breadcrumb;\n","import styled from \"styled-components\";\n\nconst Nav = styled.nav`\n ol {\n ${(props) => props.theme.typography[200]};\n margin: 0;\n font-family: ${(props) => props.theme.fontFamily};\n padding: 0;\n display: flex;\n }\n\n li {\n margin-right: ${(props) => props.theme.space[200]};\n display: flex;\n }\n\n a,\n button {\n ${(props) => props.theme.typography[200]};\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n ol > div + li::before {\n content: \"/\";\n margin-right: ${(props) => props.theme.space[200]};\n }\n\n li:last-child a,\n li:last-child button {\n color: ${(props) => props.theme.colors.text.body};\n font-weight: bold;\n }\n\n li:not(:last-child)::after {\n content: \"/\";\n color: ${(props) => props.theme.colors.text.body};\n margin-left: ${(props) => props.theme.space[200]};\n }\n`;\n\nexport default Nav;\n","import * as React from \"react\";\nimport type {\n TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nexport type { TypeLinkProps as TypeBreadcrumbItemProps } from \"@sproutsocial/seeds-react-link\";\n\nexport interface TypeBreadcrumbProps\n extends TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n Omit<React.ComponentPropsWithoutRef<\"nav\">, \"color\"> {\n children: React.ReactNode;\n\n /** Description of the type of navigation being provided by the breadcrumb (i.e. \"Asset library breadcrumb\") */\n ariaLabel: string;\n\n /** optional */\n overflow?: {\n label: string;\n menu: React.ReactNode;\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,YAAuB;AACvB,8BAAiB;;;ACDjB,+BAAmB;AAEnB,IAAM,MAAM,yBAAAA,QAAO;AAAA;AAAA,MAEb,CAAC,UAAU,MAAM,MAAM,WAAW,GAAG,CAAC;AAAA;AAAA,mBAEzB,CAAC,UAAU,MAAM,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAMhC,CAAC,UAAU,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAM/C,CAAC,UAAU,MAAM,MAAM,WAAW,GAAG,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBASxB,CAAC,UAAU,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,aAKxC,CAAC,UAAU,MAAM,MAAM,OAAO,KAAK,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAMvC,CAAC,UAAU,MAAM,MAAM,OAAO,KAAK,IAAI;AAAA,mBACjC,CAAC,UAAU,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA;AAAA;AAIpD,IAAO,iBAAQ;;;AD5BT;AAPN,IAAM,iBAAiB,CAAC;AAAA,EACtB;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAA+B;AAC7B,SACE,4CAAC,QACC,sDAAC,wBAAAC,SAAA,EAAK,MAAa,GAAG,MACnB,UACH,GACF;AAEJ;AAEA,IAAM,aAAa,CAAC;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAA2B;AACzB,QAAM,YAAkB,eAAS,QAAQ,QAAQ;AACjD,QAAM,WAAW,UAAU,UAAU,SAAS,CAAC;AAC/C,SACE,4CAAC,kBAAI,cAAY,WAAW,sBAAoB,WAAY,GAAG,MAC7D,uDAAC,QACE;AAAA,gBAAY,4CAAC,QAAI,mBAAS,MAAK;AAAA,IAC/B,UAAU,IAAI,CAAC,MAAM,MAAM;AAE1B,YAAM,WACJ,OAAO,SAAS,YAAY,WAAW,OACrC,OAEA,4CAAC,UAAK,kBAAI;AAEd,aAAa,mBAAa,UAAU;AAAA,QAClC,GAAG,SAAS;AAAA,QACZ,gBAAgB,UAAU,CAAC,MAAM,WAAW,SAAS;AAAA,MACvD,CAAC;AAAA,IACH,CAAC;AAAA,KACH,GACF;AAEJ;AAEA,eAAe,cAAc;AAC7B,WAAW,OAAO;AAElB,IAAO,qBAAQ;;;AEvDf,IAAAC,SAAuB;;;AHEvB,IAAO,cAAQ;","names":["styled","Link","React"]}
|
package/jest.config.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sproutsocial/seeds-react-breadcrumb",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Seeds React Breadcrumb",
|
|
5
|
+
"author": "Sprout Social, Inc.",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"module": "dist/esm/index.js",
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsup --dts",
|
|
12
|
+
"build:debug": "tsup --dts --metafile",
|
|
13
|
+
"dev": "tsup --watch --dts",
|
|
14
|
+
"clean": "rm -rf .turbo dist",
|
|
15
|
+
"clean:modules": "rm -rf node_modules",
|
|
16
|
+
"typecheck": "tsc --noEmit",
|
|
17
|
+
"test": "jest",
|
|
18
|
+
"test:watch": "jest --watch --coverage=false"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@sproutsocial/seeds-react-theme": "*",
|
|
22
|
+
"@sproutsocial/seeds-react-system-props": "*",
|
|
23
|
+
"@sproutsocial/seeds-react-icon": "*",
|
|
24
|
+
"@sproutsocial/seeds-react-link": "*",
|
|
25
|
+
"@sproutsocial/seeds-react-menu": "*"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/react": "^18.0.0",
|
|
29
|
+
"@types/styled-components": "^5.1.26",
|
|
30
|
+
"@sproutsocial/eslint-config-seeds": "*",
|
|
31
|
+
"react": "^18.0.0",
|
|
32
|
+
"styled-components": "^5.2.3",
|
|
33
|
+
"tsup": "^8.0.2",
|
|
34
|
+
"typescript": "^5.6.2",
|
|
35
|
+
"@sproutsocial/seeds-tsconfig": "*",
|
|
36
|
+
"@sproutsocial/seeds-testing": "*",
|
|
37
|
+
"@sproutsocial/seeds-react-testing-library": "*"
|
|
38
|
+
},
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"styled-components": "^5.2.3"
|
|
41
|
+
},
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=18"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { Breadcrumb } from "./";
|
|
4
|
+
import {
|
|
5
|
+
ActionMenu,
|
|
6
|
+
MenuContent,
|
|
7
|
+
MenuItem,
|
|
8
|
+
MenuToggleButton,
|
|
9
|
+
} from "@sproutsocial/seeds-react-menu";
|
|
10
|
+
import { Icon } from "@sproutsocial/seeds-react-icon";
|
|
11
|
+
|
|
12
|
+
export default {
|
|
13
|
+
title: "Components/Breadcrumb",
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const path = [
|
|
17
|
+
"Asset Library",
|
|
18
|
+
"Coffee Shops",
|
|
19
|
+
"Midwest",
|
|
20
|
+
"Chicago",
|
|
21
|
+
"Humboldt Park",
|
|
22
|
+
"A really really really really really long coffee shop name",
|
|
23
|
+
"Dark Roast",
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
const pathMiddle = Math.round((path.length - 1) / 2);
|
|
27
|
+
|
|
28
|
+
export const defaultStory = () => (
|
|
29
|
+
<Breadcrumb ariaLabel="breadcrumb">
|
|
30
|
+
{path.slice(0, 3).map((item) => (
|
|
31
|
+
<Breadcrumb.Item href="#">{item}</Breadcrumb.Item>
|
|
32
|
+
))}
|
|
33
|
+
</Breadcrumb>
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
export const buttonStory = () => (
|
|
37
|
+
<Breadcrumb ariaLabel="breadcrumb">
|
|
38
|
+
{path.slice(0, 3).map((item) => (
|
|
39
|
+
<Breadcrumb.Item onClick={() => {}}>{item}</Breadcrumb.Item>
|
|
40
|
+
))}
|
|
41
|
+
</Breadcrumb>
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const BreadcrumbMenu = () => (
|
|
45
|
+
<ActionMenu
|
|
46
|
+
menuToggleElement={
|
|
47
|
+
<MenuToggleButton appearance="secondary" py={0} px={200}>
|
|
48
|
+
<Icon name="ellipsis-horizontal-solid" aria-hidden />
|
|
49
|
+
</MenuToggleButton>
|
|
50
|
+
}
|
|
51
|
+
>
|
|
52
|
+
<MenuContent>
|
|
53
|
+
{path.length > 4
|
|
54
|
+
? path.slice(0, pathMiddle).map((item) => (
|
|
55
|
+
<MenuItem id={item} onClick={() => {}}>
|
|
56
|
+
{item}
|
|
57
|
+
</MenuItem>
|
|
58
|
+
))
|
|
59
|
+
: path.map((item) => (
|
|
60
|
+
<MenuItem id={item} onClick={() => {}}>
|
|
61
|
+
{item}
|
|
62
|
+
</MenuItem>
|
|
63
|
+
))}
|
|
64
|
+
</MenuContent>
|
|
65
|
+
</ActionMenu>
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
export const overflowMenu = () => (
|
|
69
|
+
<Breadcrumb
|
|
70
|
+
overflow={{
|
|
71
|
+
label: "Asset Library's Breadcrumbs Overflow Menu",
|
|
72
|
+
menu: <BreadcrumbMenu />,
|
|
73
|
+
}}
|
|
74
|
+
ariaLabel="breadcrumb"
|
|
75
|
+
>
|
|
76
|
+
{path.length > 4
|
|
77
|
+
? path
|
|
78
|
+
.slice(pathMiddle, path.length)
|
|
79
|
+
.map((item) => <Breadcrumb.Item href="#">{item}</Breadcrumb.Item>)
|
|
80
|
+
: path.map((item) => <Breadcrumb.Item href="#">{item}</Breadcrumb.Item>)}
|
|
81
|
+
</Breadcrumb>
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
defaultStory.story = {
|
|
85
|
+
name: "Default",
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
buttonStory.story = {
|
|
89
|
+
name: "With Button",
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
overflowMenu.story = {
|
|
93
|
+
name: "With Overflow",
|
|
94
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import Link from "@sproutsocial/seeds-react-link";
|
|
3
|
+
import Nav from "./styles";
|
|
4
|
+
import type {
|
|
5
|
+
TypeBreadcrumbProps,
|
|
6
|
+
TypeBreadcrumbItemProps,
|
|
7
|
+
} from "./BreadcrumbTypes";
|
|
8
|
+
|
|
9
|
+
const BreadcrumbItem = ({
|
|
10
|
+
children,
|
|
11
|
+
href,
|
|
12
|
+
...rest
|
|
13
|
+
}: TypeBreadcrumbItemProps) => {
|
|
14
|
+
return (
|
|
15
|
+
<li>
|
|
16
|
+
<Link href={href} {...rest}>
|
|
17
|
+
{children}
|
|
18
|
+
</Link>
|
|
19
|
+
</li>
|
|
20
|
+
);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const Breadcrumb = ({
|
|
24
|
+
ariaLabel,
|
|
25
|
+
overflow,
|
|
26
|
+
children,
|
|
27
|
+
...rest
|
|
28
|
+
}: TypeBreadcrumbProps) => {
|
|
29
|
+
const listItems = React.Children.toArray(children);
|
|
30
|
+
const lastItem = listItems[listItems.length - 1];
|
|
31
|
+
return (
|
|
32
|
+
<Nav aria-label={ariaLabel} data-qa-breadcrumb={ariaLabel} {...rest}>
|
|
33
|
+
<ol>
|
|
34
|
+
{overflow && <li>{overflow.menu}</li>}
|
|
35
|
+
{listItems.map((item, i) => {
|
|
36
|
+
// @ts-notes - item is a childNode which can be a string or number but `cloneElement` requires props
|
|
37
|
+
const itemElem =
|
|
38
|
+
typeof item === "object" && "props" in item ? (
|
|
39
|
+
item
|
|
40
|
+
) : (
|
|
41
|
+
<span>item</span>
|
|
42
|
+
);
|
|
43
|
+
return React.cloneElement(itemElem, {
|
|
44
|
+
...itemElem.props,
|
|
45
|
+
"aria-current": listItems[i] === lastItem ? "page" : undefined,
|
|
46
|
+
});
|
|
47
|
+
})}
|
|
48
|
+
</ol>
|
|
49
|
+
</Nav>
|
|
50
|
+
);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
BreadcrumbItem.displayName = "Breadcrumb.Item";
|
|
54
|
+
Breadcrumb.Item = BreadcrumbItem;
|
|
55
|
+
|
|
56
|
+
export default Breadcrumb;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type {
|
|
3
|
+
TypeStyledComponentsCommonProps,
|
|
4
|
+
TypeSystemCommonProps,
|
|
5
|
+
} from "@sproutsocial/seeds-react-system-props";
|
|
6
|
+
export type { TypeLinkProps as TypeBreadcrumbItemProps } from "@sproutsocial/seeds-react-link";
|
|
7
|
+
|
|
8
|
+
export interface TypeBreadcrumbProps
|
|
9
|
+
extends TypeStyledComponentsCommonProps,
|
|
10
|
+
TypeSystemCommonProps,
|
|
11
|
+
Omit<React.ComponentPropsWithoutRef<"nav">, "color"> {
|
|
12
|
+
children: React.ReactNode;
|
|
13
|
+
|
|
14
|
+
/** Description of the type of navigation being provided by the breadcrumb (i.e. "Asset library breadcrumb") */
|
|
15
|
+
ariaLabel: string;
|
|
16
|
+
|
|
17
|
+
/** optional */
|
|
18
|
+
overflow?: {
|
|
19
|
+
label: string;
|
|
20
|
+
menu: React.ReactNode;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import Breadcrumb from "../";
|
|
3
|
+
|
|
4
|
+
const path = [
|
|
5
|
+
"Asset Library",
|
|
6
|
+
"Coffee Shops",
|
|
7
|
+
"Midwest",
|
|
8
|
+
"Chicago",
|
|
9
|
+
"Humboldt Park",
|
|
10
|
+
"A really really really really really long coffee shop name",
|
|
11
|
+
"Dark Roast",
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
const pathMiddle = Math.round((path.length - 1) / 2);
|
|
15
|
+
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
17
|
+
function BreadcrumbTypes() {
|
|
18
|
+
return (
|
|
19
|
+
<>
|
|
20
|
+
<Breadcrumb ariaLabel="breadcrumb">
|
|
21
|
+
<Breadcrumb.Item href="/">Level One</Breadcrumb.Item>
|
|
22
|
+
<Breadcrumb.Item href="/level-two">Level Two</Breadcrumb.Item>
|
|
23
|
+
<Breadcrumb.Item href="/level-three">Level Three</Breadcrumb.Item>
|
|
24
|
+
</Breadcrumb>
|
|
25
|
+
<Breadcrumb ariaLabel="breadcrumb">
|
|
26
|
+
{path.slice(0, 3).map((item) => (
|
|
27
|
+
<Breadcrumb.Item href="#">{item}</Breadcrumb.Item>
|
|
28
|
+
))}
|
|
29
|
+
</Breadcrumb>
|
|
30
|
+
<Breadcrumb ariaLabel="breadcrumb">
|
|
31
|
+
{path.slice(0, 3).map((item) => (
|
|
32
|
+
<Breadcrumb.Item onClick={() => {}}>{item}</Breadcrumb.Item>
|
|
33
|
+
))}
|
|
34
|
+
</Breadcrumb>
|
|
35
|
+
<Breadcrumb
|
|
36
|
+
overflow={{
|
|
37
|
+
label: "Asset Library's Breadcrumbs Overflow Menu",
|
|
38
|
+
menu: <div />,
|
|
39
|
+
}}
|
|
40
|
+
ariaLabel="breadcrumb"
|
|
41
|
+
>
|
|
42
|
+
{path.length > 4
|
|
43
|
+
? path
|
|
44
|
+
.slice(pathMiddle, path.length)
|
|
45
|
+
.map((item) => <Breadcrumb.Item href="#">{item}</Breadcrumb.Item>)
|
|
46
|
+
: path.map((item) => (
|
|
47
|
+
<Breadcrumb.Item href="#">{item}</Breadcrumb.Item>
|
|
48
|
+
))}
|
|
49
|
+
</Breadcrumb>
|
|
50
|
+
{/* @ts-expect-error - test that missing children rejected */}
|
|
51
|
+
<Breadcrumb />
|
|
52
|
+
</>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render, screen } from "@sproutsocial/seeds-react-testing-library";
|
|
3
|
+
import Breadcrumb from "../";
|
|
4
|
+
|
|
5
|
+
describe("Breadcrumb", () => {
|
|
6
|
+
it("should render breadcrumb items", async () => {
|
|
7
|
+
render(
|
|
8
|
+
<Breadcrumb ariaLabel="breadcrumb">
|
|
9
|
+
<Breadcrumb.Item href="/">Level One</Breadcrumb.Item>
|
|
10
|
+
<Breadcrumb.Item href="/level-two">Level Two</Breadcrumb.Item>
|
|
11
|
+
<Breadcrumb.Item href="/level-three">Level Three</Breadcrumb.Item>
|
|
12
|
+
</Breadcrumb>
|
|
13
|
+
);
|
|
14
|
+
expect(
|
|
15
|
+
screen.queryAllByText("Level", {
|
|
16
|
+
exact: false,
|
|
17
|
+
}).length
|
|
18
|
+
).toEqual(3);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it("should render breadcrumb items with a name", async () => {
|
|
22
|
+
render(
|
|
23
|
+
<Breadcrumb ariaLabel="breadcrumb">
|
|
24
|
+
<Breadcrumb.Item href="/">Home</Breadcrumb.Item>
|
|
25
|
+
<Breadcrumb.Item href="/level-two">Level Two</Breadcrumb.Item>
|
|
26
|
+
<Breadcrumb.Item href="/level-three">Level Three</Breadcrumb.Item>
|
|
27
|
+
</Breadcrumb>
|
|
28
|
+
);
|
|
29
|
+
expect(screen.getByText("Home")).toBeInTheDocument();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it("should have an aria-label prop", async () => {
|
|
33
|
+
render(
|
|
34
|
+
<Breadcrumb ariaLabel="breadcrumb">
|
|
35
|
+
<Breadcrumb.Item href="/">Home</Breadcrumb.Item>
|
|
36
|
+
<Breadcrumb.Item href="/level-two">Level Two</Breadcrumb.Item>
|
|
37
|
+
<Breadcrumb.Item href="/level-three">Level Three</Breadcrumb.Item>
|
|
38
|
+
</Breadcrumb>
|
|
39
|
+
);
|
|
40
|
+
expect(
|
|
41
|
+
screen.getByDataQaLabel({
|
|
42
|
+
breadcrumb: "breadcrumb",
|
|
43
|
+
})
|
|
44
|
+
).toBeTruthy();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("should render breadcrumb items with an href", async () => {
|
|
48
|
+
render(
|
|
49
|
+
<Breadcrumb ariaLabel="breadcrumb">
|
|
50
|
+
<Breadcrumb.Item href="/">Home</Breadcrumb.Item>
|
|
51
|
+
<Breadcrumb.Item href="/level-two">Level Two</Breadcrumb.Item>
|
|
52
|
+
<Breadcrumb.Item href="/level-three">Level Three</Breadcrumb.Item>
|
|
53
|
+
</Breadcrumb>
|
|
54
|
+
);
|
|
55
|
+
expect(screen.getByText("Level Two")).toHaveAttribute("href", "/level-two");
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("should render the last breadcrumb item with an aria-current prop", async () => {
|
|
59
|
+
render(
|
|
60
|
+
<Breadcrumb ariaLabel="breadcrumb">
|
|
61
|
+
<Breadcrumb.Item href="/">Home</Breadcrumb.Item>
|
|
62
|
+
<Breadcrumb.Item href="/level-two">Level Two</Breadcrumb.Item>
|
|
63
|
+
<Breadcrumb.Item href="/level-three">Level Three</Breadcrumb.Item>
|
|
64
|
+
</Breadcrumb>
|
|
65
|
+
);
|
|
66
|
+
expect(screen.getByText("Level Three")).toHaveAttribute(
|
|
67
|
+
"aria-current",
|
|
68
|
+
"page"
|
|
69
|
+
);
|
|
70
|
+
});
|
|
71
|
+
});
|
package/src/index.ts
ADDED
package/src/styled.d.ts
ADDED
package/src/styles.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import styled from "styled-components";
|
|
2
|
+
|
|
3
|
+
const Nav = styled.nav`
|
|
4
|
+
ol {
|
|
5
|
+
${(props) => props.theme.typography[200]};
|
|
6
|
+
margin: 0;
|
|
7
|
+
font-family: ${(props) => props.theme.fontFamily};
|
|
8
|
+
padding: 0;
|
|
9
|
+
display: flex;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
li {
|
|
13
|
+
margin-right: ${(props) => props.theme.space[200]};
|
|
14
|
+
display: flex;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
a,
|
|
18
|
+
button {
|
|
19
|
+
${(props) => props.theme.typography[200]};
|
|
20
|
+
max-width: 200px;
|
|
21
|
+
overflow: hidden;
|
|
22
|
+
text-overflow: ellipsis;
|
|
23
|
+
white-space: nowrap;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
ol > div + li::before {
|
|
27
|
+
content: "/";
|
|
28
|
+
margin-right: ${(props) => props.theme.space[200]};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
li:last-child a,
|
|
32
|
+
li:last-child button {
|
|
33
|
+
color: ${(props) => props.theme.colors.text.body};
|
|
34
|
+
font-weight: bold;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
li:not(:last-child)::after {
|
|
38
|
+
content: "/";
|
|
39
|
+
color: ${(props) => props.theme.colors.text.body};
|
|
40
|
+
margin-left: ${(props) => props.theme.space[200]};
|
|
41
|
+
}
|
|
42
|
+
`;
|
|
43
|
+
|
|
44
|
+
export default Nav;
|
package/tsconfig.json
ADDED
package/tsup.config.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { defineConfig } from "tsup";
|
|
2
|
+
|
|
3
|
+
export default defineConfig((options) => ({
|
|
4
|
+
entry: ["src/index.ts"],
|
|
5
|
+
format: ["cjs", "esm"],
|
|
6
|
+
clean: true,
|
|
7
|
+
legacyOutput: true,
|
|
8
|
+
dts: options.dts,
|
|
9
|
+
external: ["react"],
|
|
10
|
+
sourcemap: true,
|
|
11
|
+
metafile: options.metafile,
|
|
12
|
+
}));
|