@dust-tt/sparkle 0.2.487 → 0.2.488-rc-1
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/index.js +1 -1
- package/dist/esm/components/Breadcrumbs.d.ts +15 -3
- package/dist/esm/components/Breadcrumbs.d.ts.map +1 -1
- package/dist/esm/components/Breadcrumbs.js +22 -11
- package/dist/esm/components/Breadcrumbs.js.map +1 -1
- package/dist/esm/components/DataTable.d.ts +3 -2
- package/dist/esm/components/DataTable.d.ts.map +1 -1
- package/dist/esm/components/DataTable.js +4 -4
- package/dist/esm/components/DataTable.js.map +1 -1
- package/dist/esm/components/index.d.ts +1 -0
- package/dist/esm/components/index.d.ts.map +1 -1
- package/dist/esm/components/index.js.map +1 -1
- package/dist/esm/stories/Breadcrumbs.stories.js +1 -1
- package/dist/esm/stories/Breadcrumbs.stories.js.map +1 -1
- package/dist/esm/stories/DataTable.stories.d.ts.map +1 -1
- package/dist/esm/stories/DataTable.stories.js +1 -1
- package/dist/esm/stories/DataTable.stories.js.map +1 -1
- package/dist/sparkle.css +0 -10
- package/package.json +1 -1
- package/src/components/Breadcrumbs.tsx +86 -28
- package/src/components/DataTable.tsx +10 -0
- package/src/components/index.ts +1 -0
- package/src/stories/Breadcrumbs.stories.tsx +1 -1
- package/src/stories/DataTable.stories.tsx +1 -0
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
} from "@sparkle/components/Dropdown";
|
|
12
12
|
import { Icon } from "@sparkle/components/Icon";
|
|
13
13
|
import { Tooltip } from "@sparkle/components/Tooltip";
|
|
14
|
-
import { SparkleContext, SparkleContextLinkType } from "@sparkle/context";
|
|
15
14
|
import { ChevronRightIcon } from "@sparkle/icons/app";
|
|
16
15
|
import { cn } from "@sparkle/lib";
|
|
17
16
|
|
|
@@ -19,11 +18,30 @@ const LABEL_TRUNCATE_LENGTH_MIDDLE = 15;
|
|
|
19
18
|
const LABEL_TRUNCATE_LENGTH_END = 30;
|
|
20
19
|
const ELLIPSIS_STRING = "...";
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
type BaseBreadcrumbItem = {
|
|
23
22
|
icon?: ComponentType<{ className?: string }>;
|
|
24
23
|
label: string;
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
type LinkBreadcrumbItem = BaseBreadcrumbItem & {
|
|
27
|
+
href: string;
|
|
28
|
+
onClick?: never;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
type ButtonBreadcrumbItem = BaseBreadcrumbItem & {
|
|
32
|
+
href?: never;
|
|
33
|
+
onClick: () => void;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
type LabelBreadcrumbItem = BaseBreadcrumbItem & {
|
|
37
|
+
href?: never;
|
|
38
|
+
onClick?: never;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export type BreadcrumbItem =
|
|
42
|
+
| LinkBreadcrumbItem
|
|
43
|
+
| ButtonBreadcrumbItem
|
|
44
|
+
| LabelBreadcrumbItem;
|
|
27
45
|
|
|
28
46
|
interface BreadcrumbProps {
|
|
29
47
|
items: BreadcrumbItem[];
|
|
@@ -35,11 +53,17 @@ interface BreadcrumbsAccumulator {
|
|
|
35
53
|
itemsHidden: BreadcrumbItem[];
|
|
36
54
|
}
|
|
37
55
|
|
|
38
|
-
|
|
39
|
-
|
|
56
|
+
const isLinkItem = (
|
|
57
|
+
item: BreadcrumbItem | { label: string }
|
|
58
|
+
): item is LinkBreadcrumbItem =>
|
|
59
|
+
"href" in item && typeof item.href === "string";
|
|
40
60
|
|
|
41
|
-
|
|
61
|
+
const isButtonItem = (
|
|
62
|
+
item: BreadcrumbItem | { label: string }
|
|
63
|
+
): item is ButtonBreadcrumbItem =>
|
|
64
|
+
"onClick" in item && typeof item.onClick === "function";
|
|
42
65
|
|
|
66
|
+
export function Breadcrumbs({ items, className }: BreadcrumbProps) {
|
|
43
67
|
const { itemsShown, itemsHidden } = items.reduce(
|
|
44
68
|
(acc: BreadcrumbsAccumulator, item, index) => {
|
|
45
69
|
if (items.length <= 5 || index < 2 || index >= items.length - 2) {
|
|
@@ -63,14 +87,14 @@ export function Breadcrumbs({ items, className }: BreadcrumbProps) {
|
|
|
63
87
|
key={`breadcrumbs-${index}`}
|
|
64
88
|
className="s-flex s-flex-row s-items-center s-gap-1"
|
|
65
89
|
>
|
|
66
|
-
<Icon
|
|
67
|
-
visual={item.icon}
|
|
68
|
-
className="s-text-muted-foreground dark:s-text-muted-foreground-night"
|
|
69
|
-
/>
|
|
70
90
|
{item.label === ELLIPSIS_STRING ? (
|
|
71
91
|
<DropdownMenu>
|
|
72
92
|
<DropdownMenuTrigger asChild>
|
|
73
|
-
<Button
|
|
93
|
+
<Button
|
|
94
|
+
variant="ghost"
|
|
95
|
+
label={ELLIPSIS_STRING}
|
|
96
|
+
icon={item.icon}
|
|
97
|
+
/>
|
|
74
98
|
</DropdownMenuTrigger>
|
|
75
99
|
|
|
76
100
|
<DropdownMenuContent align="start">
|
|
@@ -78,7 +102,8 @@ export function Breadcrumbs({ items, className }: BreadcrumbProps) {
|
|
|
78
102
|
{itemsHidden.map((item, index) => (
|
|
79
103
|
<DropdownMenuItem
|
|
80
104
|
key={`breadcrumbs-hidden-${index}`}
|
|
81
|
-
href={item.href}
|
|
105
|
+
href={isLinkItem(item) ? item.href : undefined}
|
|
106
|
+
onClick={isButtonItem(item) ? item.onClick : undefined}
|
|
82
107
|
icon={item.icon}
|
|
83
108
|
label={item.label}
|
|
84
109
|
/>
|
|
@@ -86,22 +111,52 @@ export function Breadcrumbs({ items, className }: BreadcrumbProps) {
|
|
|
86
111
|
</DropdownMenuGroup>
|
|
87
112
|
</DropdownMenuContent>
|
|
88
113
|
</DropdownMenu>
|
|
89
|
-
) : item
|
|
90
|
-
<
|
|
114
|
+
) : isLinkItem(item) ? (
|
|
115
|
+
<Button
|
|
91
116
|
href={item.href}
|
|
117
|
+
icon={item.icon}
|
|
92
118
|
className={
|
|
93
119
|
index === itemsShown.length - 1
|
|
94
120
|
? "s-font-medium s-text-foreground dark:s-text-foreground-night"
|
|
95
121
|
: "s-text-muted-foreground dark:s-text-muted-foreground-night"
|
|
96
122
|
}
|
|
97
|
-
|
|
98
|
-
{
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
123
|
+
variant="ghost"
|
|
124
|
+
label={
|
|
125
|
+
index === itemsShown.length - 1
|
|
126
|
+
? truncateTextToLength(
|
|
127
|
+
item.label,
|
|
128
|
+
LABEL_TRUNCATE_LENGTH_END
|
|
129
|
+
)
|
|
130
|
+
: truncateTextToLength(
|
|
131
|
+
item.label,
|
|
132
|
+
LABEL_TRUNCATE_LENGTH_MIDDLE
|
|
133
|
+
)
|
|
134
|
+
}
|
|
135
|
+
tooltip={item.label}
|
|
136
|
+
/>
|
|
137
|
+
) : isButtonItem(item) ? (
|
|
138
|
+
<Button
|
|
139
|
+
variant="ghost"
|
|
140
|
+
onClick={item.onClick}
|
|
141
|
+
icon={item.icon}
|
|
142
|
+
className={
|
|
143
|
+
index === itemsShown.length - 1
|
|
144
|
+
? "s-font-medium s-text-foreground dark:s-text-foreground-night"
|
|
145
|
+
: "s-text-muted-foreground dark:s-text-muted-foreground-night"
|
|
146
|
+
}
|
|
147
|
+
label={
|
|
148
|
+
index === itemsShown.length - 1
|
|
149
|
+
? truncateTextToLength(
|
|
150
|
+
item.label,
|
|
151
|
+
LABEL_TRUNCATE_LENGTH_END
|
|
152
|
+
)
|
|
153
|
+
: truncateTextToLength(
|
|
154
|
+
item.label,
|
|
155
|
+
LABEL_TRUNCATE_LENGTH_MIDDLE
|
|
156
|
+
)
|
|
157
|
+
}
|
|
158
|
+
tooltip={item.label}
|
|
159
|
+
/>
|
|
105
160
|
) : (
|
|
106
161
|
<div
|
|
107
162
|
className={
|
|
@@ -119,7 +174,7 @@ export function Breadcrumbs({ items, className }: BreadcrumbProps) {
|
|
|
119
174
|
</div>
|
|
120
175
|
)}
|
|
121
176
|
{index === itemsShown.length - 1 ? null : (
|
|
122
|
-
<
|
|
177
|
+
<Icon visual={ChevronRightIcon} />
|
|
123
178
|
)}
|
|
124
179
|
</div>
|
|
125
180
|
);
|
|
@@ -130,11 +185,14 @@ export function Breadcrumbs({ items, className }: BreadcrumbProps) {
|
|
|
130
185
|
|
|
131
186
|
function truncateWithTooltip(text: string, length: number) {
|
|
132
187
|
return text.length > length ? (
|
|
133
|
-
<Tooltip
|
|
134
|
-
trigger={`${text.substring(0, length - 1)}${ELLIPSIS_STRING}`}
|
|
135
|
-
label={text}
|
|
136
|
-
/>
|
|
188
|
+
<Tooltip trigger={truncateTextToLength(text, length)} label={text} />
|
|
137
189
|
) : (
|
|
138
190
|
text
|
|
139
191
|
);
|
|
140
192
|
}
|
|
193
|
+
|
|
194
|
+
function truncateTextToLength(text: string, length: number) {
|
|
195
|
+
return text.length > length
|
|
196
|
+
? `${text.substring(0, length - 1)}${ELLIPSIS_STRING}`
|
|
197
|
+
: text;
|
|
198
|
+
}
|
|
@@ -98,6 +98,12 @@ interface DataTableProps<TData extends TBaseData> {
|
|
|
98
98
|
setSorting?: (sorting: SortingState) => void;
|
|
99
99
|
isServerSideSorting?: boolean;
|
|
100
100
|
disablePaginationNumbers?: boolean;
|
|
101
|
+
getRowId?: (
|
|
102
|
+
originalRow: TData,
|
|
103
|
+
index: number,
|
|
104
|
+
parent?: Row<TData> | undefined
|
|
105
|
+
) => string;
|
|
106
|
+
// row selection props
|
|
101
107
|
rowSelection?: RowSelectionState;
|
|
102
108
|
setRowSelection?: (rowSelection: RowSelectionState) => void;
|
|
103
109
|
enableRowSelection?: boolean | ((row: Row<TData>) => boolean);
|
|
@@ -122,6 +128,7 @@ export function DataTable<TData extends TBaseData>({
|
|
|
122
128
|
rowSelection,
|
|
123
129
|
setRowSelection,
|
|
124
130
|
enableRowSelection = false,
|
|
131
|
+
getRowId,
|
|
125
132
|
}: DataTableProps<TData>) {
|
|
126
133
|
const windowSize = useWindowSize();
|
|
127
134
|
|
|
@@ -191,6 +198,7 @@ export function DataTable<TData extends TBaseData>({
|
|
|
191
198
|
},
|
|
192
199
|
onPaginationChange,
|
|
193
200
|
enableRowSelection,
|
|
201
|
+
getRowId,
|
|
194
202
|
});
|
|
195
203
|
|
|
196
204
|
useEffect(() => {
|
|
@@ -320,6 +328,7 @@ export function ScrollableDataTable<TData extends TBaseData>({
|
|
|
320
328
|
rowSelection,
|
|
321
329
|
setRowSelection,
|
|
322
330
|
enableRowSelection,
|
|
331
|
+
getRowId,
|
|
323
332
|
}: ScrollableDataTableProps<TData>) {
|
|
324
333
|
const windowSize = useWindowSize();
|
|
325
334
|
const tableContainerRef = useRef<HTMLDivElement>(null);
|
|
@@ -368,6 +377,7 @@ export function ScrollableDataTable<TData extends TBaseData>({
|
|
|
368
377
|
...(enableRowSelection && { rowSelection }),
|
|
369
378
|
},
|
|
370
379
|
enableRowSelection,
|
|
380
|
+
getRowId,
|
|
371
381
|
});
|
|
372
382
|
|
|
373
383
|
useEffect(() => {
|
package/src/components/index.ts
CHANGED
|
@@ -8,6 +8,7 @@ export {
|
|
|
8
8
|
export { AttachmentChip } from "./AttachmentChip";
|
|
9
9
|
export { Avatar } from "./Avatar";
|
|
10
10
|
export { BarHeader } from "./BarHeader";
|
|
11
|
+
export type { BreadcrumbItem } from "./Breadcrumbs";
|
|
11
12
|
export { Breadcrumbs } from "./Breadcrumbs";
|
|
12
13
|
export type {
|
|
13
14
|
ButtonProps,
|
|
@@ -18,7 +18,7 @@ export default meta;
|
|
|
18
18
|
export const BreadcrumbsExample = () => {
|
|
19
19
|
const items1 = [
|
|
20
20
|
{ label: "Home", href: "#", icon: HomeIcon },
|
|
21
|
-
{ label: "Spaces",
|
|
21
|
+
{ label: "Spaces", onClick: () => alert("Spaces clicked!") },
|
|
22
22
|
{ label: "My Space" },
|
|
23
23
|
];
|
|
24
24
|
const items2 = [
|
|
@@ -633,6 +633,7 @@ export const DataTableWithRowSelectionExample = () => {
|
|
|
633
633
|
rowSelection={rowSelection}
|
|
634
634
|
setRowSelection={setRowSelection}
|
|
635
635
|
enableRowSelection={true}
|
|
636
|
+
getRowId={(row) => row.name}
|
|
636
637
|
/>
|
|
637
638
|
|
|
638
639
|
<div className="s-rounded-md s-border s-bg-muted/50 s-p-2">
|