@dust-tt/sparkle 0.2.214 → 0.2.215
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/dist/cjs/components/Breadcrumbs.d.ts +8 -7
- package/dist/cjs/index.js +34 -9
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/components/Breadcrumbs.d.ts +8 -7
- package/dist/esm/index.js +34 -9
- package/dist/esm/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/components/Breadcrumbs.tsx +98 -37
- package/src/stories/Breadcrumbs.stories.tsx +50 -2
package/package.json
CHANGED
|
@@ -1,56 +1,117 @@
|
|
|
1
1
|
import type { ComponentType } from "react";
|
|
2
2
|
import React from "react";
|
|
3
3
|
|
|
4
|
-
import { SparkleContextLinkType } from "@sparkle/context";
|
|
5
|
-
import {
|
|
4
|
+
import { noHrefLink, SparkleContextLinkType } from "@sparkle/context";
|
|
5
|
+
import {
|
|
6
|
+
ChevronRightIcon,
|
|
7
|
+
DropdownMenu,
|
|
8
|
+
Icon,
|
|
9
|
+
SparkleContext,
|
|
10
|
+
Tooltip,
|
|
11
|
+
} from "@sparkle/index";
|
|
12
|
+
|
|
13
|
+
const LABEL_TRUNCATE_LENGTH_MIDDLE = 15;
|
|
14
|
+
const LABEL_TRUNCATE_LENGTH_END = 30;
|
|
15
|
+
const ELLIPSIS_STRING = "...";
|
|
16
|
+
|
|
17
|
+
type BreadcrumbItem = {
|
|
18
|
+
label: string;
|
|
19
|
+
icon?: ComponentType<{ className?: string }>;
|
|
20
|
+
href?: string;
|
|
21
|
+
};
|
|
6
22
|
|
|
7
23
|
type BreadcrumbProps = {
|
|
8
|
-
items:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
24
|
+
items: BreadcrumbItem[];
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
type BreadcrumbsAccumulator = {
|
|
28
|
+
itemsShown: BreadcrumbItem[];
|
|
29
|
+
itemsHidden: BreadcrumbItem[];
|
|
13
30
|
};
|
|
14
31
|
|
|
15
32
|
export function Breadcrumbs({ items }: BreadcrumbProps) {
|
|
16
33
|
const { components } = React.useContext(SparkleContext);
|
|
17
34
|
|
|
18
|
-
const
|
|
35
|
+
const { itemsShown, itemsHidden } = items.reduce(
|
|
36
|
+
(acc: BreadcrumbsAccumulator, item, index) => {
|
|
37
|
+
if (items.length <= 5 || index < 2 || index >= items.length - 2) {
|
|
38
|
+
acc.itemsShown.push(item);
|
|
39
|
+
} else if (index === 2) {
|
|
40
|
+
acc.itemsShown.push({ label: ELLIPSIS_STRING });
|
|
41
|
+
} else {
|
|
42
|
+
acc.itemsHidden.push(item);
|
|
43
|
+
}
|
|
44
|
+
return acc;
|
|
45
|
+
},
|
|
46
|
+
{ itemsShown: [], itemsHidden: [] }
|
|
47
|
+
);
|
|
19
48
|
|
|
20
49
|
return (
|
|
21
50
|
<div className="gap-2 s-flex s-flex-row s-items-center">
|
|
22
|
-
{
|
|
23
|
-
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
51
|
+
{itemsShown.map((item, index) => {
|
|
52
|
+
return (
|
|
53
|
+
<div
|
|
54
|
+
key={`breadcrumbs-${index}`}
|
|
55
|
+
className="s-flex s-flex-row s-items-center s-gap-1"
|
|
56
|
+
>
|
|
57
|
+
<Icon visual={item.icon} className="s-text-brand" />
|
|
58
|
+
{item.label === ELLIPSIS_STRING ? (
|
|
59
|
+
<DropdownMenu>
|
|
60
|
+
<DropdownMenu.Button>${ELLIPSIS_STRING}</DropdownMenu.Button>
|
|
61
|
+
<DropdownMenu.Items origin="topLeft">
|
|
62
|
+
{itemsHidden.map((item, index) => (
|
|
63
|
+
<DropdownMenu.Item
|
|
64
|
+
key={`breadcrumbs-hidden-${index}`}
|
|
65
|
+
icon={item.icon}
|
|
66
|
+
label={item.label}
|
|
67
|
+
>
|
|
68
|
+
{getLinkForItem(item, false, components.link)}
|
|
69
|
+
</DropdownMenu.Item>
|
|
70
|
+
))}
|
|
71
|
+
</DropdownMenu.Items>
|
|
72
|
+
</DropdownMenu>
|
|
37
73
|
) : (
|
|
38
|
-
<
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
>
|
|
45
|
-
|
|
46
|
-
|
|
74
|
+
<div>
|
|
75
|
+
{getLinkForItem(
|
|
76
|
+
item,
|
|
77
|
+
index === itemsShown.length - 1,
|
|
78
|
+
components.link
|
|
79
|
+
)}
|
|
80
|
+
</div>
|
|
81
|
+
)}
|
|
82
|
+
{index === itemsShown.length - 1 ? null : (
|
|
83
|
+
<ChevronRightIcon className="s-text-element-500" />
|
|
47
84
|
)}
|
|
48
85
|
</div>
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
)}
|
|
52
|
-
</div>
|
|
53
|
-
))}
|
|
86
|
+
);
|
|
87
|
+
})}
|
|
54
88
|
</div>
|
|
55
89
|
);
|
|
56
90
|
}
|
|
91
|
+
|
|
92
|
+
function getLinkForItem(
|
|
93
|
+
item: BreadcrumbItem,
|
|
94
|
+
isLast: boolean,
|
|
95
|
+
link: SparkleContextLinkType
|
|
96
|
+
) {
|
|
97
|
+
const Link: SparkleContextLinkType = item.href ? link : noHrefLink;
|
|
98
|
+
|
|
99
|
+
return (
|
|
100
|
+
<Link
|
|
101
|
+
href={item.href || "#"}
|
|
102
|
+
className={isLast ? "s-text-element-900" : "s-text-element-700"}
|
|
103
|
+
>
|
|
104
|
+
{isLast
|
|
105
|
+
? truncateWithTooltip(item.label, LABEL_TRUNCATE_LENGTH_END)
|
|
106
|
+
: truncateWithTooltip(item.label, LABEL_TRUNCATE_LENGTH_MIDDLE)}
|
|
107
|
+
</Link>
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function truncateWithTooltip(text: string, length: number) {
|
|
112
|
+
return text.length > length ? (
|
|
113
|
+
<Tooltip label={text}>{`${text.substring(0, length - 1)}…`}</Tooltip>
|
|
114
|
+
) : (
|
|
115
|
+
text
|
|
116
|
+
);
|
|
117
|
+
}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import type { Meta } from "@storybook/react";
|
|
2
2
|
import React from "react";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
Breadcrumbs,
|
|
6
|
+
CompanyIcon,
|
|
7
|
+
FolderIcon,
|
|
8
|
+
HomeIcon,
|
|
9
|
+
} from "../index_with_tw_base";
|
|
5
10
|
|
|
6
11
|
const meta = {
|
|
7
12
|
title: "Components/Breadcrumbs",
|
|
@@ -20,12 +25,55 @@ export const BreadcrumbsExample = () => {
|
|
|
20
25
|
{ label: "Home", href: "#", icon: HomeIcon },
|
|
21
26
|
{ label: "Vaults", href: "#", icon: CompanyIcon },
|
|
22
27
|
{ label: "My Vault", href: "#" },
|
|
28
|
+
{ label: "loooong name in the end, like very very long long" },
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
const items3 = [
|
|
32
|
+
{ label: "Home", href: "#", icon: HomeIcon },
|
|
33
|
+
{
|
|
34
|
+
label: "Middle long name, oh very looong folder name in the middle",
|
|
35
|
+
href: "#",
|
|
36
|
+
icon: CompanyIcon,
|
|
37
|
+
},
|
|
38
|
+
{ label: "My Vault", href: "#" },
|
|
23
39
|
{ label: "Data Sources" },
|
|
40
|
+
{ label: "Folder1", href: "#", icon: FolderIcon },
|
|
41
|
+
{ label: "With ellipsis", href: "#" },
|
|
24
42
|
];
|
|
43
|
+
|
|
44
|
+
const items4 = [
|
|
45
|
+
{ label: "Home", href: "#", icon: HomeIcon },
|
|
46
|
+
{
|
|
47
|
+
label: "Middle long name, oh very looong folder name in the middle",
|
|
48
|
+
href: "#",
|
|
49
|
+
icon: CompanyIcon,
|
|
50
|
+
},
|
|
51
|
+
{ label: "My Vault", href: "#" },
|
|
52
|
+
{ label: "Data Sources" },
|
|
53
|
+
{ label: "Folder1", href: "#", icon: FolderIcon },
|
|
54
|
+
{ label: "Folder2", href: "#", icon: FolderIcon },
|
|
55
|
+
{ label: "Folder3", href: "#", icon: FolderIcon },
|
|
56
|
+
{ label: "With ellipsis", href: "#" },
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
const items5 = [
|
|
60
|
+
{ label: "Home", href: "#", icon: HomeIcon },
|
|
61
|
+
{
|
|
62
|
+
label: "Long, oh very looong folder name in the middle",
|
|
63
|
+
href: "#",
|
|
64
|
+
icon: CompanyIcon,
|
|
65
|
+
},
|
|
66
|
+
{ label: "My Vault", href: "#" },
|
|
67
|
+
{ label: "Data Sources" },
|
|
68
|
+
];
|
|
69
|
+
|
|
25
70
|
return (
|
|
26
|
-
<div className="s-flex s-flex-col s-gap-4">
|
|
71
|
+
<div className="s-flex s-flex-col s-gap-4 s-pb-8">
|
|
27
72
|
<Breadcrumbs items={items1} />
|
|
28
73
|
<Breadcrumbs items={items2} />
|
|
74
|
+
<Breadcrumbs items={items4} />
|
|
75
|
+
<Breadcrumbs items={items3} />
|
|
76
|
+
<Breadcrumbs items={items5} />
|
|
29
77
|
</div>
|
|
30
78
|
);
|
|
31
79
|
};
|