@dust-tt/sparkle 0.2.589-rc-1 → 0.2.589-rc-2
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/ConversationMessage.js +2 -2
- package/dist/esm/components/ConversationMessage.js.map +1 -1
- package/dist/esm/components/DataTable.d.ts +1 -1
- package/dist/esm/components/DataTable.d.ts.map +1 -1
- package/dist/esm/components/DataTable.js +51 -48
- package/dist/esm/components/DataTable.js.map +1 -1
- package/dist/esm/icons/app/Bell.d.ts +5 -0
- package/dist/esm/icons/app/Bell.d.ts.map +1 -0
- package/dist/esm/icons/app/Bell.js +6 -0
- package/dist/esm/icons/app/Bell.js.map +1 -0
- package/dist/esm/icons/app/index.d.ts +1 -0
- package/dist/esm/icons/app/index.d.ts.map +1 -1
- package/dist/esm/icons/app/index.js +1 -0
- package/dist/esm/icons/app/index.js.map +1 -1
- package/dist/esm/icons/src/app/bell.svg +3 -0
- package/dist/esm/stories/DataTable.stories.d.ts +1 -0
- package/dist/esm/stories/DataTable.stories.d.ts.map +1 -1
- package/dist/esm/stories/DataTable.stories.js +28 -0
- package/dist/esm/stories/DataTable.stories.js.map +1 -1
- package/dist/sparkle.css +0 -4
- package/package.json +1 -1
- package/src/components/ConversationMessage.tsx +2 -2
- package/src/components/DataTable.tsx +115 -111
- package/src/icons/app/Bell.tsx +18 -0
- package/src/icons/app/index.ts +1 -0
- package/src/icons/src/app/bell.svg +3 -0
- package/src/stories/DataTable.stories.tsx +61 -0
|
@@ -327,7 +327,7 @@ export function DataTable<TData extends TBaseData>({
|
|
|
327
327
|
|
|
328
328
|
export interface ScrollableDataTableProps<TData extends TBaseData>
|
|
329
329
|
extends DataTableProps<TData> {
|
|
330
|
-
maxHeight?: string;
|
|
330
|
+
maxHeight?: string | boolean;
|
|
331
331
|
onLoadMore?: () => void;
|
|
332
332
|
isLoading?: boolean;
|
|
333
333
|
}
|
|
@@ -343,7 +343,7 @@ export function ScrollableDataTable<TData extends TBaseData>({
|
|
|
343
343
|
className,
|
|
344
344
|
widthClassName = "s-w-full",
|
|
345
345
|
columnsBreakpoints = {},
|
|
346
|
-
maxHeight
|
|
346
|
+
maxHeight,
|
|
347
347
|
onLoadMore,
|
|
348
348
|
isLoading = false,
|
|
349
349
|
rowSelection,
|
|
@@ -480,24 +480,95 @@ export function ScrollableDataTable<TData extends TBaseData>({
|
|
|
480
480
|
}, [onLoadMore, isLoading]);
|
|
481
481
|
|
|
482
482
|
return (
|
|
483
|
-
<div
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
483
|
+
<div
|
|
484
|
+
className={cn(
|
|
485
|
+
"s-relative s-overflow-y-auto s-overflow-x-hidden",
|
|
486
|
+
className,
|
|
487
|
+
widthClassName,
|
|
488
|
+
maxHeight === true
|
|
489
|
+
? "s-flex-1"
|
|
490
|
+
: typeof maxHeight === "string"
|
|
491
|
+
? maxHeight
|
|
492
|
+
: "s-max-h-100"
|
|
493
|
+
)}
|
|
494
|
+
ref={tableContainerRef}
|
|
495
|
+
>
|
|
496
|
+
<div className="s-relative">
|
|
497
|
+
<DataTable.Root className="s-w-full s-table-fixed">
|
|
498
|
+
<DataTable.Header className="s-sticky s-top-0 s-z-20 s-bg-white s-shadow-sm dark:s-bg-background-night">
|
|
499
|
+
{table.getHeaderGroups().map((headerGroup) => (
|
|
500
|
+
<DataTable.Row
|
|
501
|
+
key={headerGroup.id}
|
|
502
|
+
widthClassName={widthClassName}
|
|
503
|
+
>
|
|
504
|
+
{headerGroup.headers.map((header) => {
|
|
505
|
+
const breakpoint = columnsBreakpoints[header.id];
|
|
506
|
+
if (
|
|
507
|
+
!windowSize.width ||
|
|
508
|
+
!shouldRenderColumn(windowSize.width, breakpoint)
|
|
509
|
+
) {
|
|
510
|
+
return null;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
return (
|
|
514
|
+
<DataTable.Head
|
|
515
|
+
column={header.column}
|
|
516
|
+
key={header.id}
|
|
517
|
+
className="s-max-w-0"
|
|
518
|
+
style={{
|
|
519
|
+
width: columnSizing[header.id],
|
|
520
|
+
minWidth: columnSizing[header.id],
|
|
521
|
+
}}
|
|
522
|
+
>
|
|
523
|
+
<div className="s-flex s-w-full s-items-center s-space-x-1">
|
|
524
|
+
<span className="s-truncate">
|
|
525
|
+
{flexRender(
|
|
526
|
+
header.column.columnDef.header,
|
|
527
|
+
header.getContext()
|
|
528
|
+
)}
|
|
529
|
+
</span>
|
|
530
|
+
</div>
|
|
531
|
+
</DataTable.Head>
|
|
532
|
+
);
|
|
533
|
+
})}
|
|
534
|
+
</DataTable.Row>
|
|
535
|
+
))}
|
|
536
|
+
</DataTable.Header>
|
|
537
|
+
<DataTable.Body
|
|
538
|
+
className="s-relative s-w-full"
|
|
539
|
+
style={{
|
|
540
|
+
height: `${rowVirtualizer.getTotalSize()}px`,
|
|
541
|
+
}}
|
|
542
|
+
>
|
|
543
|
+
{rowVirtualizer.getVirtualItems().map((virtualRow) => {
|
|
544
|
+
const row = rows[virtualRow.index];
|
|
545
|
+
const handleRowClick = () => {
|
|
546
|
+
if (enableRowSelection && row.getCanSelect()) {
|
|
547
|
+
row.toggleSelected(
|
|
548
|
+
!enableMultiRowSelection ? true : undefined
|
|
549
|
+
);
|
|
550
|
+
}
|
|
551
|
+
row.original.onClick?.();
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
return (
|
|
495
555
|
<DataTable.Row
|
|
496
|
-
key={
|
|
556
|
+
key={row.id}
|
|
557
|
+
id={row.id}
|
|
497
558
|
widthClassName={widthClassName}
|
|
559
|
+
onClick={
|
|
560
|
+
enableRowSelection ? handleRowClick : row.original.onClick
|
|
561
|
+
}
|
|
562
|
+
className="s-absolute s-w-full"
|
|
563
|
+
{...(enableRowSelection && {
|
|
564
|
+
"data-selected": row.getIsSelected(),
|
|
565
|
+
})}
|
|
566
|
+
style={{
|
|
567
|
+
transform: `translateY(${virtualRow.start}px)`,
|
|
568
|
+
}}
|
|
498
569
|
>
|
|
499
|
-
{
|
|
500
|
-
const breakpoint = columnsBreakpoints[
|
|
570
|
+
{row.getVisibleCells().map((cell) => {
|
|
571
|
+
const breakpoint = columnsBreakpoints[cell.column.id];
|
|
501
572
|
if (
|
|
502
573
|
!windowSize.width ||
|
|
503
574
|
!shouldRenderColumn(windowSize.width, breakpoint)
|
|
@@ -506,114 +577,47 @@ export function ScrollableDataTable<TData extends TBaseData>({
|
|
|
506
577
|
}
|
|
507
578
|
|
|
508
579
|
return (
|
|
509
|
-
<DataTable.
|
|
510
|
-
column={
|
|
511
|
-
key={
|
|
580
|
+
<DataTable.Cell
|
|
581
|
+
column={cell.column}
|
|
582
|
+
key={cell.id}
|
|
583
|
+
id={cell.id}
|
|
512
584
|
className="s-max-w-0"
|
|
513
585
|
style={{
|
|
514
|
-
width: columnSizing[
|
|
515
|
-
minWidth: columnSizing[
|
|
586
|
+
width: columnSizing[cell.column.id],
|
|
587
|
+
minWidth: columnSizing[cell.column.id],
|
|
516
588
|
}}
|
|
517
589
|
>
|
|
518
|
-
<div className="s-flex s-
|
|
590
|
+
<div className="s-flex s-items-center s-space-x-1">
|
|
519
591
|
<span className="s-truncate">
|
|
520
592
|
{flexRender(
|
|
521
|
-
|
|
522
|
-
|
|
593
|
+
cell.column.columnDef.cell,
|
|
594
|
+
cell.getContext()
|
|
523
595
|
)}
|
|
524
596
|
</span>
|
|
525
597
|
</div>
|
|
526
|
-
</DataTable.
|
|
598
|
+
</DataTable.Cell>
|
|
527
599
|
);
|
|
528
600
|
})}
|
|
529
601
|
</DataTable.Row>
|
|
530
|
-
)
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
const handleRowClick = () => {
|
|
541
|
-
if (enableRowSelection && row.getCanSelect()) {
|
|
542
|
-
row.toggleSelected(
|
|
543
|
-
!enableMultiRowSelection ? true : undefined
|
|
544
|
-
);
|
|
545
|
-
}
|
|
546
|
-
row.original.onClick?.();
|
|
547
|
-
};
|
|
548
|
-
|
|
549
|
-
return (
|
|
550
|
-
<DataTable.Row
|
|
551
|
-
key={row.id}
|
|
552
|
-
id={row.id}
|
|
553
|
-
widthClassName={widthClassName}
|
|
554
|
-
onClick={
|
|
555
|
-
enableRowSelection ? handleRowClick : row.original.onClick
|
|
556
|
-
}
|
|
557
|
-
className="s-absolute s-w-full"
|
|
558
|
-
{...(enableRowSelection && {
|
|
559
|
-
"data-selected": row.getIsSelected(),
|
|
560
|
-
})}
|
|
561
|
-
style={{
|
|
562
|
-
transform: `translateY(${virtualRow.start}px)`,
|
|
563
|
-
}}
|
|
564
|
-
>
|
|
565
|
-
{row.getVisibleCells().map((cell) => {
|
|
566
|
-
const breakpoint = columnsBreakpoints[cell.column.id];
|
|
567
|
-
if (
|
|
568
|
-
!windowSize.width ||
|
|
569
|
-
!shouldRenderColumn(windowSize.width, breakpoint)
|
|
570
|
-
) {
|
|
571
|
-
return null;
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
return (
|
|
575
|
-
<DataTable.Cell
|
|
576
|
-
column={cell.column}
|
|
577
|
-
key={cell.id}
|
|
578
|
-
id={cell.id}
|
|
579
|
-
className="s-max-w-0"
|
|
580
|
-
style={{
|
|
581
|
-
width: columnSizing[cell.column.id],
|
|
582
|
-
minWidth: columnSizing[cell.column.id],
|
|
583
|
-
}}
|
|
584
|
-
>
|
|
585
|
-
<div className="s-flex s-items-center s-space-x-1">
|
|
586
|
-
<span className="s-truncate">
|
|
587
|
-
{flexRender(
|
|
588
|
-
cell.column.columnDef.cell,
|
|
589
|
-
cell.getContext()
|
|
590
|
-
)}
|
|
591
|
-
</span>
|
|
592
|
-
</div>
|
|
593
|
-
</DataTable.Cell>
|
|
594
|
-
);
|
|
595
|
-
})}
|
|
596
|
-
</DataTable.Row>
|
|
597
|
-
);
|
|
598
|
-
})}
|
|
599
|
-
</DataTable.Body>
|
|
600
|
-
</DataTable.Root>
|
|
601
|
-
{/*sentinel div used for the intersection observer*/}
|
|
602
|
-
<div
|
|
603
|
-
ref={loadMoreRef}
|
|
604
|
-
className="s-absolute s-bottom-0 s-h-1 s-w-full"
|
|
605
|
-
/>
|
|
606
|
-
</div>
|
|
602
|
+
);
|
|
603
|
+
})}
|
|
604
|
+
</DataTable.Body>
|
|
605
|
+
</DataTable.Root>
|
|
606
|
+
{/*sentinel div used for the intersection observer*/}
|
|
607
|
+
<div
|
|
608
|
+
ref={loadMoreRef}
|
|
609
|
+
className="s-absolute s-bottom-0 s-h-1 s-w-full"
|
|
610
|
+
/>
|
|
611
|
+
</div>
|
|
607
612
|
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
</div>
|
|
613
|
+
{isLoading && (
|
|
614
|
+
<div className="s-sticky s-bottom-0 s-left-0 s-right-0 s-flex s-justify-center s-bg-white/80 s-py-2 s-backdrop-blur-sm dark:s-bg-background-night/80">
|
|
615
|
+
<div className="s-flex s-items-center s-gap-2 s-text-sm s-text-muted-foreground">
|
|
616
|
+
<Spinner size="xs" />
|
|
617
|
+
<span>Loading more data...</span>
|
|
614
618
|
</div>
|
|
615
|
-
|
|
616
|
-
|
|
619
|
+
</div>
|
|
620
|
+
)}
|
|
617
621
|
</div>
|
|
618
622
|
);
|
|
619
623
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { SVGProps } from "react";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
const SvgBell = (props: SVGProps<SVGSVGElement>) => (
|
|
4
|
+
<svg
|
|
5
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
6
|
+
width="1em"
|
|
7
|
+
height="1em"
|
|
8
|
+
fill="none"
|
|
9
|
+
viewBox="0 0 24 24"
|
|
10
|
+
{...props}
|
|
11
|
+
>
|
|
12
|
+
<path
|
|
13
|
+
fill="currentColor"
|
|
14
|
+
d="M20 17h2v2H2v-2h2v-7a8 8 0 1 1 16 0v7ZM9 21h6v2H9v-2Z"
|
|
15
|
+
/>
|
|
16
|
+
</svg>
|
|
17
|
+
);
|
|
18
|
+
export default SvgBell;
|
package/src/icons/app/index.ts
CHANGED
|
@@ -13,6 +13,7 @@ export { default as ArrowUpOnSquareIcon } from "./ArrowUpOnSquare";
|
|
|
13
13
|
export { default as ArrowUpSIcon } from "./ArrowUpS";
|
|
14
14
|
export { default as AttachmentIcon } from "./Attachment";
|
|
15
15
|
export { default as BarChartIcon } from "./BarChart";
|
|
16
|
+
export { default as BellIcon } from "./Bell";
|
|
16
17
|
export { default as BoltIcon } from "./Bolt";
|
|
17
18
|
export { default as BookOpenIcon } from "./BookOpen";
|
|
18
19
|
export { default as BracesIcon } from "./Braces";
|
|
@@ -607,6 +607,67 @@ export const ScrollableDataTableExample = () => {
|
|
|
607
607
|
);
|
|
608
608
|
};
|
|
609
609
|
|
|
610
|
+
export const ScrollableDataTableFullHeightExample = () => {
|
|
611
|
+
const [filter, setFilter] = useState("");
|
|
612
|
+
const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
|
|
613
|
+
const [data, setData] = useState(() => createData(0, 50));
|
|
614
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
615
|
+
|
|
616
|
+
// Load more data when user scrolls to bottom
|
|
617
|
+
const loadMore = useCallback(() => {
|
|
618
|
+
setIsLoading(true);
|
|
619
|
+
|
|
620
|
+
// Simulate API call delay
|
|
621
|
+
setTimeout(() => {
|
|
622
|
+
setData((prevData) => [...prevData, ...createData(prevData.length, 50)]);
|
|
623
|
+
setIsLoading(false);
|
|
624
|
+
}, 1000);
|
|
625
|
+
}, []);
|
|
626
|
+
|
|
627
|
+
const columnsWithSize = columns.map((column, index) => {
|
|
628
|
+
return { ...column, meta: { sizeRatio: index % 2 === 0 ? 15 : 10 } };
|
|
629
|
+
});
|
|
630
|
+
|
|
631
|
+
const columnsWithSelection: ColumnDef<Data>[] = useMemo(
|
|
632
|
+
() => [createSelectionColumn<Data>(), ...columnsWithSize],
|
|
633
|
+
[]
|
|
634
|
+
);
|
|
635
|
+
return (
|
|
636
|
+
<div className="s-flex s-w-full s-max-w-4xl s-flex-col s-gap-6">
|
|
637
|
+
<h3 className="s-text-lg s-font-medium">
|
|
638
|
+
Virtualized ScrollableDataTable with Infinite Scrolling based on parent
|
|
639
|
+
height
|
|
640
|
+
</h3>
|
|
641
|
+
|
|
642
|
+
<div className="s-flex s-h-[400px] s-flex-col s-gap-4">
|
|
643
|
+
<Input
|
|
644
|
+
name="filter"
|
|
645
|
+
placeholder="Filter"
|
|
646
|
+
value={filter}
|
|
647
|
+
onChange={(e) => setFilter(e.target.value)}
|
|
648
|
+
/>
|
|
649
|
+
|
|
650
|
+
<ScrollableDataTable
|
|
651
|
+
data={data}
|
|
652
|
+
filter={filter}
|
|
653
|
+
filterColumn="name"
|
|
654
|
+
columns={columnsWithSelection}
|
|
655
|
+
onLoadMore={loadMore}
|
|
656
|
+
isLoading={isLoading}
|
|
657
|
+
maxHeight
|
|
658
|
+
rowSelection={rowSelection}
|
|
659
|
+
setRowSelection={setRowSelection}
|
|
660
|
+
enableRowSelection={true}
|
|
661
|
+
/>
|
|
662
|
+
|
|
663
|
+
<div className="s-text-sm s-text-muted-foreground">
|
|
664
|
+
Loaded {data.length} rows. Scroll to the bottom to load more.
|
|
665
|
+
</div>
|
|
666
|
+
</div>
|
|
667
|
+
</div>
|
|
668
|
+
);
|
|
669
|
+
};
|
|
670
|
+
|
|
610
671
|
export const DataTableWithRowSelectionExample = () => {
|
|
611
672
|
const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
|
|
612
673
|
const [data] = useState<Data[]>(() => createData(0, 10));
|