@dust-tt/sparkle 0.2.561 → 0.2.563-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.
@@ -39,6 +39,10 @@ import {
39
39
  Spinner,
40
40
  Tooltip,
41
41
  } from "@sparkle/components";
42
+ import {
43
+ radioIndicatorStyles,
44
+ radioStyles,
45
+ } from "@sparkle/components/RadioGroup";
42
46
  import { useCopyToClipboard } from "@sparkle/hooks";
43
47
  import {
44
48
  ArrowDownIcon,
@@ -107,6 +111,7 @@ interface DataTableProps<TData extends TBaseData> {
107
111
  rowSelection?: RowSelectionState;
108
112
  setRowSelection?: (rowSelection: RowSelectionState) => void;
109
113
  enableRowSelection?: boolean | ((row: Row<TData>) => boolean);
114
+ enableMultiRowSelection?: boolean;
110
115
  }
111
116
 
112
117
  export function DataTable<TData extends TBaseData>({
@@ -128,6 +133,7 @@ export function DataTable<TData extends TBaseData>({
128
133
  rowSelection,
129
134
  setRowSelection,
130
135
  enableRowSelection = false,
136
+ enableMultiRowSelection = true,
131
137
  getRowId,
132
138
  }: DataTableProps<TData>) {
133
139
  const windowSize = useWindowSize();
@@ -198,6 +204,7 @@ export function DataTable<TData extends TBaseData>({
198
204
  },
199
205
  onPaginationChange,
200
206
  enableRowSelection,
207
+ enableMultiRowSelection,
201
208
  getRowId,
202
209
  });
203
210
 
@@ -328,6 +335,7 @@ export function ScrollableDataTable<TData extends TBaseData>({
328
335
  rowSelection,
329
336
  setRowSelection,
330
337
  enableRowSelection,
338
+ enableMultiRowSelection = true,
331
339
  getRowId,
332
340
  }: ScrollableDataTableProps<TData>) {
333
341
  const windowSize = useWindowSize();
@@ -369,7 +377,6 @@ export function ScrollableDataTable<TData extends TBaseData>({
369
377
  rowCount: totalRowCount,
370
378
  getCoreRowModel: getCoreRowModel(),
371
379
  enableColumnResizing: true,
372
- onRowSelectionChange,
373
380
  ...(enableRowSelection && {
374
381
  onRowSelectionChange,
375
382
  }),
@@ -377,6 +384,7 @@ export function ScrollableDataTable<TData extends TBaseData>({
377
384
  ...(enableRowSelection && { rowSelection }),
378
385
  },
379
386
  enableRowSelection,
387
+ enableMultiRowSelection,
380
388
  getRowId,
381
389
  });
382
390
 
@@ -693,8 +701,7 @@ DataTable.Row = function Row({
693
701
  onClick
694
702
  ? "s-cursor-pointer hover:s-bg-muted dark:hover:s-bg-muted-night"
695
703
  : "",
696
- props["data-selected"] &&
697
- "s-bg-highlight-50 dark:s-bg-highlight-900/10",
704
+ props["data-selected"] && "s-bg-muted/50 dark:s-bg-muted/50",
698
705
  widthClassName,
699
706
  className
700
707
  )}
@@ -1119,3 +1126,37 @@ export function createSelectionColumn<TData>(): ColumnDef<TData> {
1119
1126
  },
1120
1127
  };
1121
1128
  }
1129
+
1130
+ export function createRadioSelectionColumn<TData>(): ColumnDef<TData> {
1131
+ return {
1132
+ id: "radio-select",
1133
+ enableSorting: false,
1134
+ enableHiding: false,
1135
+ header: () => null,
1136
+ cell: ({ row }) => (
1137
+ <div className="s-flex s-h-full s-w-full s-items-center">
1138
+ <button
1139
+ type="button"
1140
+ className={cn(
1141
+ radioStyles({ size: "xs" }),
1142
+ row.getIsSelected() && "s-bg-muted/50 dark:s-bg-muted/50",
1143
+ row.getCanSelect() && "s-cursor-pointer"
1144
+ )}
1145
+ onClick={() =>
1146
+ row.getCanSelect() && row.toggleSelected(!row.getIsSelected())
1147
+ }
1148
+ disabled={!row.getCanSelect()}
1149
+ aria-checked={row.getIsSelected()}
1150
+ role="radio"
1151
+ >
1152
+ {row.getIsSelected() && (
1153
+ <div className={radioIndicatorStyles({ size: "xs" })} />
1154
+ )}
1155
+ </button>
1156
+ </div>
1157
+ ),
1158
+ meta: {
1159
+ className: "s-w-10",
1160
+ },
1161
+ };
1162
+ }
@@ -7,7 +7,7 @@ import { Label } from "@sparkle/components/Label";
7
7
  import { Tooltip } from "@sparkle/components/Tooltip";
8
8
  import { cn } from "@sparkle/lib/utils";
9
9
 
10
- const radioStyles = cva(
10
+ export const radioStyles = cva(
11
11
  cn(
12
12
  "s-aspect-square s-rounded-full s-border",
13
13
  "s-s-border-border-dark dark:s-border-primary-500",
@@ -32,7 +32,7 @@ const radioStyles = cva(
32
32
  }
33
33
  );
34
34
 
35
- const radioIndicatorStyles = cva(
35
+ export const radioIndicatorStyles = cva(
36
36
  "s-bg-primary dark:s-bg-primary-night s-flex s-items-center s-justify-center s-rounded-full",
37
37
  {
38
38
  variants: {
@@ -45,7 +45,12 @@ export {
45
45
  } from "./ConversationMessage";
46
46
  export { Counter } from "./Counter";
47
47
  export type { DataTableMoreButtonProps, MenuItem } from "./DataTable";
48
- export { DataTable, ScrollableDataTable } from "./DataTable";
48
+ export {
49
+ createRadioSelectionColumn,
50
+ createSelectionColumn,
51
+ DataTable,
52
+ ScrollableDataTable,
53
+ } from "./DataTable";
49
54
  export {
50
55
  Dialog,
51
56
  DialogClose,
@@ -20,7 +20,11 @@ import {
20
20
  Input,
21
21
  ScrollableDataTable,
22
22
  } from "@sparkle/components/";
23
- import { createSelectionColumn, MenuItem } from "@sparkle/components/DataTable";
23
+ import {
24
+ createRadioSelectionColumn,
25
+ createSelectionColumn,
26
+ MenuItem,
27
+ } from "@sparkle/components/DataTable";
24
28
  import { FolderIcon } from "@sparkle/icons/app";
25
29
 
26
30
  const meta = {
@@ -649,3 +653,59 @@ export const DataTableWithRowSelectionExample = () => {
649
653
  </div>
650
654
  );
651
655
  };
656
+
657
+ export const DataTableWithRadioSelectionExample = () => {
658
+ const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
659
+ const [data] = useState<Data[]>(() => createData(0, 10));
660
+ const [filter, setFilter] = useState("");
661
+
662
+ const columnsWithRadioSelection: ColumnDef<Data>[] = useMemo(
663
+ () => [createRadioSelectionColumn<Data>(), ...columns],
664
+ []
665
+ );
666
+
667
+ // Get the selected row ID from rowSelection state
668
+ const selectedRowId = Object.keys(rowSelection).find(
669
+ (id) => rowSelection[id]
670
+ );
671
+
672
+ return (
673
+ <div className="s-flex s-w-full s-max-w-4xl s-flex-col s-gap-6">
674
+ <h3 className="s-text-lg s-font-medium">
675
+ DataTable with Radio Selection (Single Row)
676
+ </h3>
677
+
678
+ <div className="s-flex s-flex-col s-gap-4">
679
+ <Input
680
+ name="filter"
681
+ placeholder="Filter"
682
+ value={filter}
683
+ onChange={(e) => setFilter(e.target.value)}
684
+ />
685
+
686
+ <DataTable
687
+ data={data}
688
+ filter={filter}
689
+ filterColumn="name"
690
+ columns={columnsWithRadioSelection}
691
+ rowSelection={rowSelection}
692
+ setRowSelection={setRowSelection}
693
+ enableRowSelection={true}
694
+ enableMultiRowSelection={false}
695
+ getRowId={(row) => row.name}
696
+ />
697
+
698
+ <div className="s-rounded-md s-border s-bg-muted/50 s-p-2">
699
+ <h4 className="s-mb-2 s-font-medium">Radio Selection State:</h4>
700
+ <pre className="s-overflow-auto s-text-xs">
701
+ {JSON.stringify(rowSelection, null, 2)}
702
+ </pre>
703
+ <p className="s-mt-2 s-text-sm">
704
+ {selectedRowId ? `Selected: ${selectedRowId}` : "No row selected"}{" "}
705
+ (only one row can be selected at a time)
706
+ </p>
707
+ </div>
708
+ </div>
709
+ </div>
710
+ );
711
+ };