doo-boilerplate 0.2.12 → 0.2.14

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "doo-boilerplate",
3
- "version": "0.2.12",
3
+ "version": "0.2.14",
4
4
  "description": "CLI to scaffold Pila portal frontend projects",
5
5
  "type": "module",
6
6
  "bin": {
@@ -11,8 +11,9 @@ import {
11
11
  useSensors,
12
12
  } from '@dnd-kit/core'
13
13
  import { restrictToHorizontalAxis } from '@dnd-kit/modifiers'
14
- import { SortableContext, arrayMove, horizontalListSortingStrategy } from '@dnd-kit/sortable'
15
- import { type ColumnDef, type Table as TanstackTable, flexRender } from '@tanstack/react-table'
14
+ import { SortableContext, arrayMove, horizontalListSortingStrategy, useSortable } from '@dnd-kit/sortable'
15
+ import { CSS } from '@dnd-kit/utilities'
16
+ import { type Cell, type ColumnDef, type Table as TanstackTable, flexRender } from '@tanstack/react-table'
16
17
 
17
18
  import { Skeleton } from '@/components/ui/skeleton'
18
19
  import { Table, TableBody, TableCell, TableHeader, TableRow } from '@/components/ui/table'
@@ -26,6 +27,28 @@ interface DataTableProps<TData> {
26
27
  isLoading?: boolean
27
28
  }
28
29
 
30
+ /**
31
+ * Cell that participates in DnD column reordering.
32
+ * Uses useSortable to get CSS transform during drag so the cell visually
33
+ * moves with its column header — matching ndatrace-cms DragAlongCell pattern.
34
+ */
35
+ function DragAlongCell<TData>({ cell }: { cell: Cell<TData, unknown> }) {
36
+ const { isDragging, setNodeRef, transform } = useSortable({ id: cell.column.id })
37
+
38
+ const style: React.CSSProperties = {
39
+ opacity: isDragging ? 0.6 : 1,
40
+ transform: CSS.Translate.toString(transform),
41
+ transition: 'width transform 0.2s ease-in-out',
42
+ position: 'relative',
43
+ }
44
+
45
+ return (
46
+ <TableCell ref={setNodeRef} style={style}>
47
+ {flexRender(cell.column.columnDef.cell, cell.getContext())}
48
+ </TableCell>
49
+ )
50
+ }
51
+
29
52
  export function DataTable<TData>({ table, columns, isLoading }: DataTableProps<TData>) {
30
53
  const [columnOrder, setColumnOrder] = useState<string[]>(() =>
31
54
  table.getAllLeafColumns().map((col) => col.id)
@@ -46,10 +69,17 @@ export function DataTable<TData>({ table, columns, isLoading }: DataTableProps<T
46
69
  columnOrder.indexOf(String(over.id))
47
70
  )
48
71
  setColumnOrder(newOrder)
72
+ // Also sync to table instance if parent wired onColumnOrderChange
49
73
  table.setColumnOrder(newOrder)
50
74
  }
51
75
  }
52
76
 
77
+ // Sort by local columnOrder so DnD works self-contained (no parent config needed).
78
+ // After drag ends, re-renders headers/cells in the new order.
79
+ function sortById<T extends { id: string }>(items: T[]): T[] {
80
+ return [...items].sort((a, b) => columnOrder.indexOf(a.id) - columnOrder.indexOf(b.id))
81
+ }
82
+
53
83
  return (
54
84
  <DndContext
55
85
  sensors={sensors}
@@ -68,7 +98,7 @@ export function DataTable<TData>({ table, columns, isLoading }: DataTableProps<T
68
98
  strategy={horizontalListSortingStrategy}
69
99
  >
70
100
  <tr>
71
- {headerGroup.headers.map((header) => (
101
+ {sortById(headerGroup.headers).map((header) => (
72
102
  <SortableHeader key={header.id} header={header} />
73
103
  ))}
74
104
  </tr>
@@ -89,11 +119,11 @@ export function DataTable<TData>({ table, columns, isLoading }: DataTableProps<T
89
119
  ) : table.getRowModel().rows.length ? (
90
120
  table.getRowModel().rows.map((row) => (
91
121
  <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>
92
- {row.getVisibleCells().map((cell) => (
93
- <TableCell key={cell.id}>
94
- {flexRender(cell.column.columnDef.cell, cell.getContext())}
95
- </TableCell>
96
- ))}
122
+ <SortableContext items={columnOrder} strategy={horizontalListSortingStrategy}>
123
+ {sortById(row.getVisibleCells()).map((cell) => (
124
+ <DragAlongCell key={cell.id} cell={cell} />
125
+ ))}
126
+ </SortableContext>
97
127
  </TableRow>
98
128
  ))
99
129
  ) : (
@@ -5,6 +5,7 @@ import {
5
5
  getPaginationRowModel,
6
6
  getSortedRowModel,
7
7
  getFilteredRowModel,
8
+ type ColumnOrderState,
8
9
  type SortingState,
9
10
  type ColumnFiltersState,
10
11
  type VisibilityState,
@@ -39,6 +40,7 @@ export function TasksCrudTable() {
39
40
  const [sorting, setSorting] = useState<SortingState>([])
40
41
  const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])
41
42
  const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({})
43
+ const [columnOrder, setColumnOrder] = useState<ColumnOrderState>([])
42
44
  const [rowSelection, setRowSelection] = useState({})
43
45
  const [dialogOpen, setDialogOpen] = useState(false)
44
46
  const [editingTask, setEditingTask] = useState<Task | undefined>()
@@ -74,10 +76,11 @@ export function TasksCrudTable() {
74
76
  const table = useReactTable({
75
77
  data: tasks,
76
78
  columns,
77
- state: { sorting, columnFilters, columnVisibility, rowSelection },
79
+ state: { sorting, columnFilters, columnVisibility, columnOrder, rowSelection },
78
80
  onSortingChange: setSorting,
79
81
  onColumnFiltersChange: setColumnFilters,
80
82
  onColumnVisibilityChange: setColumnVisibility,
83
+ onColumnOrderChange: setColumnOrder,
81
84
  onRowSelectionChange: setRowSelection,
82
85
  getCoreRowModel: getCoreRowModel(),
83
86
  getPaginationRowModel: getPaginationRowModel(),
@@ -8,6 +8,7 @@ import {
8
8
  getSortedRowModel,
9
9
  useReactTable,
10
10
  type ColumnFiltersState,
11
+ type ColumnOrderState,
11
12
  type SortingState,
12
13
  type VisibilityState,
13
14
  } from '@tanstack/react-table'
@@ -45,6 +46,7 @@ export function UsersTable() {
45
46
  const [sorting, setSorting] = useState<SortingState>([])
46
47
  const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])
47
48
  const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({})
49
+ const [columnOrder, setColumnOrder] = useState<ColumnOrderState>([])
48
50
  const [rowSelection, setRowSelection] = useState({})
49
51
 
50
52
  // Dialog state
@@ -96,10 +98,11 @@ export function UsersTable() {
96
98
  const table = useReactTable({
97
99
  data,
98
100
  columns,
99
- state: { sorting, columnFilters, columnVisibility, rowSelection },
101
+ state: { sorting, columnFilters, columnVisibility, columnOrder, rowSelection },
100
102
  onSortingChange: setSorting,
101
103
  onColumnFiltersChange: setColumnFilters,
102
104
  onColumnVisibilityChange: setColumnVisibility,
105
+ onColumnOrderChange: setColumnOrder,
103
106
  onRowSelectionChange: setRowSelection,
104
107
  getCoreRowModel: getCoreRowModel(),
105
108
  getFilteredRowModel: getFilteredRowModel(),