@dust-tt/sparkle 0.2.589-rc-2 → 0.2.590

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.
@@ -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 | boolean;
330
+ maxHeight?: string;
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 = "s-h-100",
347
347
  onLoadMore,
348
348
  isLoading = false,
349
349
  rowSelection,
@@ -480,95 +480,24 @@ export function ScrollableDataTable<TData extends TBaseData>({
480
480
  }, [onLoadMore, isLoading]);
481
481
 
482
482
  return (
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 (
483
+ <div className={cn("s-flex s-flex-col s-gap-2", className, widthClassName)}>
484
+ <div
485
+ className={cn(
486
+ "s-relative s-overflow-y-auto s-overflow-x-hidden",
487
+ maxHeight
488
+ )}
489
+ ref={tableContainerRef}
490
+ >
491
+ <div className="s-relative">
492
+ <DataTable.Root className="s-w-full s-table-fixed">
493
+ <DataTable.Header className="s-sticky s-top-0 s-z-20 s-bg-white s-shadow-sm dark:s-bg-background-night">
494
+ {table.getHeaderGroups().map((headerGroup) => (
555
495
  <DataTable.Row
556
- key={row.id}
557
- id={row.id}
496
+ key={headerGroup.id}
558
497
  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
- }}
569
498
  >
570
- {row.getVisibleCells().map((cell) => {
571
- const breakpoint = columnsBreakpoints[cell.column.id];
499
+ {headerGroup.headers.map((header) => {
500
+ const breakpoint = columnsBreakpoints[header.id];
572
501
  if (
573
502
  !windowSize.width ||
574
503
  !shouldRenderColumn(windowSize.width, breakpoint)
@@ -577,47 +506,114 @@ export function ScrollableDataTable<TData extends TBaseData>({
577
506
  }
578
507
 
579
508
  return (
580
- <DataTable.Cell
581
- column={cell.column}
582
- key={cell.id}
583
- id={cell.id}
509
+ <DataTable.Head
510
+ column={header.column}
511
+ key={header.id}
584
512
  className="s-max-w-0"
585
513
  style={{
586
- width: columnSizing[cell.column.id],
587
- minWidth: columnSizing[cell.column.id],
514
+ width: columnSizing[header.id],
515
+ minWidth: columnSizing[header.id],
588
516
  }}
589
517
  >
590
- <div className="s-flex s-items-center s-space-x-1">
518
+ <div className="s-flex s-w-full s-items-center s-space-x-1">
591
519
  <span className="s-truncate">
592
520
  {flexRender(
593
- cell.column.columnDef.cell,
594
- cell.getContext()
521
+ header.column.columnDef.header,
522
+ header.getContext()
595
523
  )}
596
524
  </span>
597
525
  </div>
598
- </DataTable.Cell>
526
+ </DataTable.Head>
599
527
  );
600
528
  })}
601
529
  </DataTable.Row>
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>
530
+ ))}
531
+ </DataTable.Header>
532
+ <DataTable.Body
533
+ className="s-relative s-w-full"
534
+ style={{
535
+ height: `${rowVirtualizer.getTotalSize()}px`,
536
+ }}
537
+ >
538
+ {rowVirtualizer.getVirtualItems().map((virtualRow) => {
539
+ const row = rows[virtualRow.index];
540
+ const handleRowClick = () => {
541
+ if (enableRowSelection && row.getCanSelect()) {
542
+ row.toggleSelected(
543
+ !enableMultiRowSelection ? true : undefined
544
+ );
545
+ }
546
+ row.original.onClick?.();
547
+ };
612
548
 
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>
618
- </div>
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
+ />
619
606
  </div>
620
- )}
607
+
608
+ {isLoading && (
609
+ <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">
610
+ <div className="s-flex s-items-center s-gap-2 s-text-sm s-text-muted-foreground">
611
+ <Spinner size="xs" />
612
+ <span>Loading more data...</span>
613
+ </div>
614
+ </div>
615
+ )}
616
+ </div>
621
617
  </div>
622
618
  );
623
619
  }
@@ -607,67 +607,6 @@ 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
-
671
610
  export const DataTableWithRowSelectionExample = () => {
672
611
  const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
673
612
  const [data] = useState<Data[]>(() => createData(0, 10));