ai-design-system 0.1.78 → 0.1.80

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.
@@ -55,6 +55,7 @@ export interface EnhancedDataTableProps {
55
55
  rightActions?: React.ReactNode
56
56
  onCreateClick?: () => void
57
57
  createButtonLabel?: string
58
+ rowActions?: Array<{ key: string; label: string; icon?: string }>
58
59
  }
59
60
 
60
61
  function toRowId(row: DashboardRow, schema: DynamicTableSchema): number | string {
@@ -96,6 +97,7 @@ export function EnhancedDataTable({
96
97
  rightActions,
97
98
  onCreateClick,
98
99
  createButtonLabel = "Create",
100
+ rowActions,
99
101
  }: EnhancedDataTableProps) {
100
102
  const [searchQuery, setSearchQuery] = React.useState("")
101
103
 
@@ -341,45 +343,100 @@ export function EnhancedDataTable({
341
343
  }))
342
344
  )
343
345
 
344
- dynamicColumns.push({
345
- id: "actions",
346
- cell: ({ row }) => (
347
- <DropdownMenu>
348
- <DropdownMenuTrigger asChild>
349
- <Button variant="ghost" className="flex size-8 text-muted-foreground data-[state=open]:bg-muted" size="icon">
350
- <Icon name="more-vertical" size="sm" />
351
- <span className="sr-only">Open menu</span>
352
- </Button>
353
- </DropdownMenuTrigger>
354
- <DropdownMenuContent align="end" className="w-40">
355
- <DropdownMenuItem
356
- onClick={() => {
357
- setEditingRowId(String(toRowId(row.original, tableSchema)))
358
- emitRowAction("edit", row.original)
359
- }}
360
- >
361
- Edit
362
- </DropdownMenuItem>
363
- <DropdownMenuItem onClick={() => emitRowAction("copy", row.original)}>Make a copy</DropdownMenuItem>
364
- <DropdownMenuItem onClick={() => emitRowAction("favorite", row.original)}>Favorite</DropdownMenuItem>
365
- <DropdownMenuSeparator />
366
- <DropdownMenuItem
367
- onClick={() => {
368
- if (editingRowId === String(toRowId(row.original, tableSchema))) {
369
- setEditingRowId(null)
370
- }
371
- emitRowAction("delete", row.original)
372
- }}
373
- >
374
- Delete
375
- </DropdownMenuItem>
376
- </DropdownMenuContent>
377
- </DropdownMenu>
378
- ),
379
- })
346
+ if (rowActions && rowActions.length === 0) {
347
+ // No actions column if rowActions is explicitly empty
348
+ } else if (rowActions && rowActions.length === 1) {
349
+ const singleAction = rowActions[0]
350
+ const iconName = singleAction.icon || (singleAction.key === "retry" ? "refresh-cw" : "more-vertical")
351
+ dynamicColumns.push({
352
+ id: "actions",
353
+ cell: ({ row }) => (
354
+ <Button
355
+ variant="ghost"
356
+ size="icon"
357
+ className="flex size-8 cursor-pointer text-muted-foreground hover:text-foreground"
358
+ onClick={(e) => {
359
+ e.stopPropagation()
360
+ emitRowAction(singleAction.key, row.original)
361
+ }}
362
+ title={singleAction.label}
363
+ aria-label={singleAction.label}
364
+ >
365
+ <Icon name={iconName} size="sm" />
366
+ </Button>
367
+ ),
368
+ })
369
+ } else if (rowActions && rowActions.length > 1) {
370
+ dynamicColumns.push({
371
+ id: "actions",
372
+ cell: ({ row }) => (
373
+ <DropdownMenu>
374
+ <DropdownMenuTrigger asChild>
375
+ <Button variant="ghost" className="flex size-8 cursor-pointer text-muted-foreground data-[state=open]:bg-muted" size="icon">
376
+ <Icon name="more-vertical" size="sm" />
377
+ <span className="sr-only">Open menu</span>
378
+ </Button>
379
+ </DropdownMenuTrigger>
380
+ <DropdownMenuContent align="end" className="w-40">
381
+ {rowActions.map((action) => (
382
+ <DropdownMenuItem
383
+ key={action.key}
384
+ onClick={() => {
385
+ if (action.key === "edit") {
386
+ setEditingRowId(String(toRowId(row.original, tableSchema)))
387
+ }
388
+ emitRowAction(action.key, row.original)
389
+ }}
390
+ >
391
+ {action.icon && <Icon name={action.icon} size="xs" className="mr-2 inline" />}
392
+ {action.label}
393
+ </DropdownMenuItem>
394
+ ))}
395
+ </DropdownMenuContent>
396
+ </DropdownMenu>
397
+ ),
398
+ })
399
+ } else {
400
+ dynamicColumns.push({
401
+ id: "actions",
402
+ cell: ({ row }) => (
403
+ <DropdownMenu>
404
+ <DropdownMenuTrigger asChild>
405
+ <Button variant="ghost" className="flex size-8 text-muted-foreground data-[state=open]:bg-muted" size="icon">
406
+ <Icon name="more-vertical" size="sm" />
407
+ <span className="sr-only">Open menu</span>
408
+ </Button>
409
+ </DropdownMenuTrigger>
410
+ <DropdownMenuContent align="end" className="w-40">
411
+ <DropdownMenuItem
412
+ onClick={() => {
413
+ setEditingRowId(String(toRowId(row.original, tableSchema)))
414
+ emitRowAction("edit", row.original)
415
+ }}
416
+ >
417
+ Edit
418
+ </DropdownMenuItem>
419
+ <DropdownMenuItem onClick={() => emitRowAction("copy", row.original)}>Make a copy</DropdownMenuItem>
420
+ <DropdownMenuItem onClick={() => emitRowAction("favorite", row.original)}>Favorite</DropdownMenuItem>
421
+ <DropdownMenuSeparator />
422
+ <DropdownMenuItem
423
+ onClick={() => {
424
+ if (editingRowId === String(toRowId(row.original, tableSchema))) {
425
+ setEditingRowId(null)
426
+ }
427
+ emitRowAction("delete", row.original)
428
+ }}
429
+ >
430
+ Delete
431
+ </DropdownMenuItem>
432
+ </DropdownMenuContent>
433
+ </DropdownMenu>
434
+ ),
435
+ })
436
+ }
380
437
 
381
438
  return dynamicColumns
382
- }, [editingRowId, emitRowAction, renderEditableCell, renderReadonlyCell, tableSchema])
439
+ }, [editingRowId, emitRowAction, renderEditableCell, renderReadonlyCell, rowActions, tableSchema])
383
440
 
384
441
  const filterKeys = React.useMemo(() => tableSchema.columns.map((column) => column.key), [tableSchema.columns])
385
442
 
@@ -8,7 +8,7 @@ export type DashboardRow = z.infer<typeof dashboardRowSchema>
8
8
 
9
9
  export type DashboardInlineEditableField = "target" | "limit"
10
10
 
11
- export type DashboardRowAction = "edit" | "copy" | "favorite" | "delete"
11
+ export type DashboardRowAction = "edit" | "copy" | "favorite" | "delete" | string
12
12
 
13
13
  export interface DashboardPaginationState {
14
14
  pageIndex: number
@@ -18,6 +18,7 @@ export type FormReportsColumn = TableColumn
18
18
  export interface FormReportsRowAction {
19
19
  key: string
20
20
  label: string
21
+ icon?: string
21
22
  }
22
23
 
23
24
  export interface FormReportsTableHandlers {
@@ -64,7 +65,7 @@ const dashboardToFormReportsActionMap: Record<DashboardRowAction, string> = {
64
65
  export type { DashboardPaginationState }
65
66
 
66
67
  export const FormReportsTable = React.memo<FormReportsTableProps>(
67
- ({ items, columns, pagination, handlers, leftActions, rightActions, onCreateClick, createButtonLabel, enableRowSelection }) => {
68
+ ({ items, columns, rowActions, pagination, handlers, leftActions, rightActions, onCreateClick, createButtonLabel, enableRowSelection }) => {
68
69
  const { rows, originalById, tableSchema } = React.useMemo(() => {
69
70
  const byId = new Map<string, FormReportsEntity>()
70
71
  const tableColumns: DynamicTableSchema["columns"] = columns
@@ -185,6 +186,7 @@ export const FormReportsTable = React.memo<FormReportsTableProps>(
185
186
  rightActions={rightActions}
186
187
  onCreateClick={onCreateClick}
187
188
  createButtonLabel={createButtonLabel}
189
+ rowActions={rowActions}
188
190
  />
189
191
  )
190
192
  }
@@ -5,7 +5,7 @@ import { cva, type VariantProps } from "class-variance-authority"
5
5
  import { cn } from "@/lib/utils"
6
6
 
7
7
  const buttonVariants = cva(
8
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
8
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all cursor-pointer disabled:cursor-not-allowed disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
9
9
  {
10
10
  variants: {
11
11
  variant: {
package/dist/index.cjs CHANGED
@@ -132,7 +132,7 @@ function cn(...inputs) {
132
132
  return tailwindMerge.twMerge(clsx.clsx(inputs));
133
133
  }
134
134
  var buttonVariants = classVarianceAuthority.cva(
135
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
135
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all cursor-pointer disabled:cursor-not-allowed disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
136
136
  {
137
137
  variants: {
138
138
  variant: {
@@ -9830,7 +9830,8 @@ function EnhancedDataTable({
9830
9830
  leftActions,
9831
9831
  rightActions,
9832
9832
  onCreateClick,
9833
- createButtonLabel = "Create"
9833
+ createButtonLabel = "Create",
9834
+ rowActions
9834
9835
  }) {
9835
9836
  var _a, _b;
9836
9837
  const [searchQuery, setSearchQuery] = React3__namespace.useState("");
@@ -10041,44 +10042,93 @@ function EnhancedDataTable({
10041
10042
  };
10042
10043
  })
10043
10044
  );
10044
- dynamicColumns.push({
10045
- id: "actions",
10046
- cell: ({ row }) => /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu2, { children: [
10047
- /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(Button2, { variant: "ghost", className: "flex size-8 text-muted-foreground data-[state=open]:bg-muted", size: "icon", children: [
10048
- /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "more-vertical", size: "sm" }),
10049
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Open menu" })
10050
- ] }) }),
10051
- /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuContent, { align: "end", className: "w-40", children: [
10052
- /* @__PURE__ */ jsxRuntime.jsx(
10053
- DropdownMenuItem,
10054
- {
10055
- onClick: () => {
10056
- setEditingRowId(String(toRowId(row.original, tableSchema)));
10057
- emitRowAction("edit", row.original);
10058
- },
10059
- children: "Edit"
10060
- }
10061
- ),
10062
- /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuItem, { onClick: () => emitRowAction("copy", row.original), children: "Make a copy" }),
10063
- /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuItem, { onClick: () => emitRowAction("favorite", row.original), children: "Favorite" }),
10064
- /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}),
10065
- /* @__PURE__ */ jsxRuntime.jsx(
10045
+ if (rowActions && rowActions.length === 0) ; else if (rowActions && rowActions.length === 1) {
10046
+ const singleAction = rowActions[0];
10047
+ const iconName = singleAction.icon || (singleAction.key === "retry" ? "refresh-cw" : "more-vertical");
10048
+ dynamicColumns.push({
10049
+ id: "actions",
10050
+ cell: ({ row }) => /* @__PURE__ */ jsxRuntime.jsx(
10051
+ Button2,
10052
+ {
10053
+ variant: "ghost",
10054
+ size: "icon",
10055
+ className: "flex size-8 cursor-pointer text-muted-foreground hover:text-foreground",
10056
+ onClick: (e) => {
10057
+ e.stopPropagation();
10058
+ emitRowAction(singleAction.key, row.original);
10059
+ },
10060
+ title: singleAction.label,
10061
+ "aria-label": singleAction.label,
10062
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: iconName, size: "sm" })
10063
+ }
10064
+ )
10065
+ });
10066
+ } else if (rowActions && rowActions.length > 1) {
10067
+ dynamicColumns.push({
10068
+ id: "actions",
10069
+ cell: ({ row }) => /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu2, { children: [
10070
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(Button2, { variant: "ghost", className: "flex size-8 cursor-pointer text-muted-foreground data-[state=open]:bg-muted", size: "icon", children: [
10071
+ /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "more-vertical", size: "sm" }),
10072
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Open menu" })
10073
+ ] }) }),
10074
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuContent, { align: "end", className: "w-40", children: rowActions.map((action) => /* @__PURE__ */ jsxRuntime.jsxs(
10066
10075
  DropdownMenuItem,
10067
10076
  {
10068
10077
  onClick: () => {
10069
- if (editingRowId === String(toRowId(row.original, tableSchema))) {
10070
- setEditingRowId(null);
10078
+ if (action.key === "edit") {
10079
+ setEditingRowId(String(toRowId(row.original, tableSchema)));
10071
10080
  }
10072
- emitRowAction("delete", row.original);
10081
+ emitRowAction(action.key, row.original);
10073
10082
  },
10074
- children: "Delete"
10075
- }
10076
- )
10083
+ children: [
10084
+ action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon, size: "xs", className: "mr-2 inline" }),
10085
+ action.label
10086
+ ]
10087
+ },
10088
+ action.key
10089
+ )) })
10077
10090
  ] })
10078
- ] })
10079
- });
10091
+ });
10092
+ } else {
10093
+ dynamicColumns.push({
10094
+ id: "actions",
10095
+ cell: ({ row }) => /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu2, { children: [
10096
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(Button2, { variant: "ghost", className: "flex size-8 text-muted-foreground data-[state=open]:bg-muted", size: "icon", children: [
10097
+ /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "more-vertical", size: "sm" }),
10098
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Open menu" })
10099
+ ] }) }),
10100
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuContent, { align: "end", className: "w-40", children: [
10101
+ /* @__PURE__ */ jsxRuntime.jsx(
10102
+ DropdownMenuItem,
10103
+ {
10104
+ onClick: () => {
10105
+ setEditingRowId(String(toRowId(row.original, tableSchema)));
10106
+ emitRowAction("edit", row.original);
10107
+ },
10108
+ children: "Edit"
10109
+ }
10110
+ ),
10111
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuItem, { onClick: () => emitRowAction("copy", row.original), children: "Make a copy" }),
10112
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuItem, { onClick: () => emitRowAction("favorite", row.original), children: "Favorite" }),
10113
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}),
10114
+ /* @__PURE__ */ jsxRuntime.jsx(
10115
+ DropdownMenuItem,
10116
+ {
10117
+ onClick: () => {
10118
+ if (editingRowId === String(toRowId(row.original, tableSchema))) {
10119
+ setEditingRowId(null);
10120
+ }
10121
+ emitRowAction("delete", row.original);
10122
+ },
10123
+ children: "Delete"
10124
+ }
10125
+ )
10126
+ ] })
10127
+ ] })
10128
+ });
10129
+ }
10080
10130
  return dynamicColumns;
10081
- }, [editingRowId, emitRowAction, renderEditableCell, renderReadonlyCell, tableSchema]);
10131
+ }, [editingRowId, emitRowAction, renderEditableCell, renderReadonlyCell, rowActions, tableSchema]);
10082
10132
  const filterKeys = React3__namespace.useMemo(() => tableSchema.columns.map((column) => column.key), [tableSchema.columns]);
10083
10133
  const filteredData = React3__namespace.useMemo(() => {
10084
10134
  const query = searchQuery.trim().toLowerCase();
@@ -10483,7 +10533,7 @@ var dashboardToFormReportsActionMap = {
10483
10533
  delete: "delete"
10484
10534
  };
10485
10535
  var FormReportsTable = React3__namespace.memo(
10486
- ({ items, columns, pagination, handlers, leftActions, rightActions, onCreateClick, createButtonLabel, enableRowSelection }) => {
10536
+ ({ items, columns, rowActions, pagination, handlers, leftActions, rightActions, onCreateClick, createButtonLabel, enableRowSelection }) => {
10487
10537
  const { rows, originalById, tableSchema } = React3__namespace.useMemo(() => {
10488
10538
  const byId = /* @__PURE__ */ new Map();
10489
10539
  const tableColumns = columns;
@@ -10625,7 +10675,8 @@ var FormReportsTable = React3__namespace.memo(
10625
10675
  leftActions,
10626
10676
  rightActions,
10627
10677
  onCreateClick,
10628
- createButtonLabel
10678
+ createButtonLabel,
10679
+ rowActions
10629
10680
  }
10630
10681
  );
10631
10682
  }