ai-design-system 0.1.18 → 0.1.23

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.
@@ -5,6 +5,7 @@ import {
5
5
  type FormReportsEntity,
6
6
  type FormReportsRowAction,
7
7
  type FormReportsTableHandlers,
8
+ type DashboardPaginationState,
8
9
  } from "@/components/composites/FormReports"
9
10
 
10
11
  export interface FormReportsSectionProps {
@@ -13,6 +14,7 @@ export interface FormReportsSectionProps {
13
14
  items: FormReportsEntity[]
14
15
  columns: FormReportsColumn[]
15
16
  rowActions?: FormReportsRowAction[]
17
+ pagination?: DashboardPaginationState
16
18
  tableHandlers?: FormReportsTableHandlers
17
19
  tableLeftActions?: React.ReactNode
18
20
  }
@@ -24,6 +26,7 @@ export const FormReportsSection = React.memo<FormReportsSectionProps>(
24
26
  items,
25
27
  columns,
26
28
  rowActions,
29
+ pagination,
27
30
  tableHandlers,
28
31
  tableLeftActions,
29
32
  }) => {
@@ -33,6 +36,7 @@ export const FormReportsSection = React.memo<FormReportsSectionProps>(
33
36
  items={items}
34
37
  columns={columns}
35
38
  rowActions={rowActions}
39
+ pagination={pagination}
36
40
  handlers={tableHandlers}
37
41
  leftActions={tableLeftActions}
38
42
  onCreateClick={onCreateClick}
@@ -37,6 +37,7 @@ import { DragHandleCell } from "./DragHandleCell"
37
37
  import { DraggableRow } from "./DraggableRow"
38
38
  import { createTableSelectColumn } from "./TableSelectColumn"
39
39
  import type {
40
+ DashboardPaginationState,
40
41
  DashboardRow,
41
42
  DashboardRowAction,
42
43
  DashboardTableActionHandlers,
@@ -46,6 +47,7 @@ import { useEnhancedDataTable } from "./useEnhancedDataTable"
46
47
  export interface EnhancedDataTableProps {
47
48
  data: DashboardRow[]
48
49
  tableSchema: DynamicTableSchema
50
+ pagination?: DashboardPaginationState
49
51
  className?: string
50
52
  handlers?: DashboardTableActionHandlers
51
53
  leftActions?: React.ReactNode
@@ -86,6 +88,7 @@ function toNumberValue(value: unknown): number {
86
88
  export function EnhancedDataTable({
87
89
  data: initialData,
88
90
  tableSchema,
91
+ pagination,
89
92
  className,
90
93
  handlers,
91
94
  leftActions,
@@ -384,8 +387,30 @@ export function EnhancedDataTable({
384
387
  data: filteredData,
385
388
  columns,
386
389
  onReorder: (rows) => handlers?.onRowReorder?.(rows),
390
+ serverPagination: pagination,
387
391
  })
388
392
 
393
+ const totalPages = React.useMemo(() => {
394
+ if (!pagination) {
395
+ return table.getPageCount()
396
+ }
397
+ const safePageSize = Math.max(1, pagination.pageSize)
398
+ return Math.max(1, Math.ceil(Math.max(0, pagination.totalItems) / safePageSize))
399
+ }, [pagination, table])
400
+
401
+ const currentPageIndex = pagination ? pagination.pageIndex : table.getState().pagination.pageIndex
402
+ const currentPageSize = pagination ? pagination.pageSize : table.getState().pagination.pageSize
403
+ const canPreviousPage = currentPageIndex > 0
404
+ const canNextPage = currentPageIndex < totalPages - 1
405
+
406
+ React.useEffect(() => {
407
+ if (!pagination) {
408
+ return
409
+ }
410
+ table.setPageIndex(pagination.pageIndex)
411
+ table.setPageSize(pagination.pageSize)
412
+ }, [pagination, table])
413
+
389
414
  React.useEffect(() => {
390
415
  if (version > 0) {
391
416
  table.resetRowSelection(false)
@@ -528,16 +553,16 @@ export function EnhancedDataTable({
528
553
  Rows per page
529
554
  </Label>
530
555
  <Select
531
- value={`${table.getState().pagination.pageSize}`}
556
+ value={`${currentPageSize}`}
532
557
  onValueChange={(value) => {
533
558
  const pageSize = Number(value)
534
559
  table.setPageSize(pageSize)
535
560
  handlers?.onPageSizeChange?.(pageSize)
536
- emitPaginationChange(table.getState().pagination.pageIndex, pageSize)
561
+ emitPaginationChange(0, pageSize)
537
562
  }}
538
563
  >
539
564
  <SelectTrigger className="w-20" id="rows-per-page">
540
- <SelectValue placeholder={table.getState().pagination.pageSize} />
565
+ <SelectValue placeholder={currentPageSize} />
541
566
  </SelectTrigger>
542
567
  <SelectContent side="top">
543
568
  {[10, 20, 30, 40, 50].map((pageSize) => (
@@ -549,7 +574,7 @@ export function EnhancedDataTable({
549
574
  </Select>
550
575
  </div>
551
576
  <div className="flex w-fit items-center justify-center text-sm font-medium">
552
- Page {table.getState().pagination.pageIndex + 1} of {table.getPageCount()}
577
+ Page {currentPageIndex + 1} of {totalPages}
553
578
  </div>
554
579
  <div className="ml-auto flex items-center gap-2 lg:ml-0">
555
580
  <Button
@@ -558,9 +583,9 @@ export function EnhancedDataTable({
558
583
  onClick={() => {
559
584
  table.setPageIndex(0)
560
585
  handlers?.onPageChange?.(0)
561
- emitPaginationChange(0, table.getState().pagination.pageSize)
586
+ emitPaginationChange(0, currentPageSize)
562
587
  }}
563
- disabled={!table.getCanPreviousPage()}
588
+ disabled={!canPreviousPage}
564
589
  >
565
590
  <span className="sr-only">Go to first page</span>
566
591
  <ChevronsLeft className="size-4" />
@@ -569,12 +594,12 @@ export function EnhancedDataTable({
569
594
  variant="outline"
570
595
  className="size-8 p-0"
571
596
  onClick={() => {
572
- table.previousPage()
573
- const nextIndex = Math.max(0, table.getState().pagination.pageIndex - 1)
597
+ const nextIndex = Math.max(0, currentPageIndex - 1)
598
+ table.setPageIndex(nextIndex)
574
599
  handlers?.onPageChange?.(nextIndex)
575
- emitPaginationChange(nextIndex, table.getState().pagination.pageSize)
600
+ emitPaginationChange(nextIndex, currentPageSize)
576
601
  }}
577
- disabled={!table.getCanPreviousPage()}
602
+ disabled={!canPreviousPage}
578
603
  >
579
604
  <span className="sr-only">Go to previous page</span>
580
605
  <ChevronLeft className="size-4" />
@@ -583,12 +608,12 @@ export function EnhancedDataTable({
583
608
  variant="outline"
584
609
  className="size-8 p-0"
585
610
  onClick={() => {
586
- table.nextPage()
587
- const nextIndex = Math.min(table.getPageCount() - 1, table.getState().pagination.pageIndex + 1)
611
+ const nextIndex = Math.min(totalPages - 1, currentPageIndex + 1)
612
+ table.setPageIndex(nextIndex)
588
613
  handlers?.onPageChange?.(nextIndex)
589
- emitPaginationChange(nextIndex, table.getState().pagination.pageSize)
614
+ emitPaginationChange(nextIndex, currentPageSize)
590
615
  }}
591
- disabled={!table.getCanNextPage()}
616
+ disabled={!canNextPage}
592
617
  >
593
618
  <span className="sr-only">Go to next page</span>
594
619
  <ChevronRight className="size-4" />
@@ -597,12 +622,12 @@ export function EnhancedDataTable({
597
622
  variant="outline"
598
623
  className="hidden size-8 p-0 lg:flex"
599
624
  onClick={() => {
600
- const lastPage = Math.max(0, table.getPageCount() - 1)
625
+ const lastPage = Math.max(0, totalPages - 1)
601
626
  table.setPageIndex(lastPage)
602
627
  handlers?.onPageChange?.(lastPage)
603
- emitPaginationChange(lastPage, table.getState().pagination.pageSize)
628
+ emitPaginationChange(lastPage, currentPageSize)
604
629
  }}
605
- disabled={!table.getCanNextPage()}
630
+ disabled={!canNextPage}
606
631
  >
607
632
  <span className="sr-only">Go to last page</span>
608
633
  <ChevronsRight className="size-4" />
@@ -20,6 +20,7 @@ export type { UseEnhancedDataTableOptions } from './useEnhancedDataTable'
20
20
  export { dashboardRowSchema } from './table-types'
21
21
  export type {
22
22
  DashboardInlineEditableField,
23
+ DashboardPaginationState,
23
24
  DashboardRow,
24
25
  DashboardRowAction,
25
26
  DashboardTableActionHandlers,
@@ -10,6 +10,12 @@ export type DashboardInlineEditableField = "target" | "limit"
10
10
 
11
11
  export type DashboardRowAction = "edit" | "copy" | "favorite" | "delete"
12
12
 
13
+ export interface DashboardPaginationState {
14
+ pageIndex: number
15
+ pageSize: number
16
+ totalItems: number
17
+ }
18
+
13
19
  export interface DashboardTableActionHandlers {
14
20
  onCreateClick?: () => void
15
21
  onAddSection?: () => void
@@ -16,27 +16,44 @@ import { arrayMove, type UniqueIdentifier } from "@dnd-kit/sortable"
16
16
 
17
17
  import type { DashboardRow } from "./table-types"
18
18
 
19
+ export interface ServerPaginationOptions {
20
+ pageIndex: number
21
+ pageSize: number
22
+ totalItems: number
23
+ }
24
+
19
25
  export interface UseEnhancedDataTableOptions {
20
26
  data: DashboardRow[]
21
27
  columns: ColumnDef<DashboardRow>[]
22
28
  onReorder?: (rows: DashboardRow[]) => void
29
+ serverPagination?: ServerPaginationOptions
23
30
  }
24
31
 
25
- export function useEnhancedDataTable({ data: initialData, columns, onReorder }: UseEnhancedDataTableOptions) {
32
+ export function useEnhancedDataTable({ data: initialData, columns, onReorder, serverPagination }: UseEnhancedDataTableOptions) {
26
33
  const [data, setData] = React.useState<DashboardRow[]>(() => initialData)
27
34
  const [rowSelection, setRowSelection] = React.useState({})
28
35
  const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>({})
29
36
  const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>([])
30
37
  const [sorting, setSorting] = React.useState<SortingState>([])
31
38
  const [pagination, setPagination] = React.useState({
32
- pageIndex: 0,
33
- pageSize: 10,
39
+ pageIndex: serverPagination?.pageIndex ?? 0,
40
+ pageSize: serverPagination?.pageSize ?? 10,
34
41
  })
35
42
 
36
43
  React.useEffect(() => {
37
44
  setData(initialData)
38
45
  }, [initialData])
39
46
 
47
+ React.useEffect(() => {
48
+ if (!serverPagination) {
49
+ return
50
+ }
51
+ setPagination({
52
+ pageIndex: serverPagination.pageIndex,
53
+ pageSize: serverPagination.pageSize,
54
+ })
55
+ }, [serverPagination])
56
+
40
57
  const dataIds = React.useMemo<UniqueIdentifier[]>(() => data.map((item) => item.id), [data])
41
58
 
42
59
  const table = useReactTable({
@@ -56,9 +73,13 @@ export function useEnhancedDataTable({ data: initialData, columns, onReorder }:
56
73
  onColumnFiltersChange: setColumnFilters,
57
74
  onColumnVisibilityChange: setColumnVisibility,
58
75
  onPaginationChange: setPagination,
76
+ manualPagination: Boolean(serverPagination),
77
+ pageCount: serverPagination
78
+ ? Math.max(1, Math.ceil(serverPagination.totalItems / Math.max(1, serverPagination.pageSize)))
79
+ : undefined,
59
80
  getCoreRowModel: getCoreRowModel(),
60
81
  getFilteredRowModel: getFilteredRowModel(),
61
- getPaginationRowModel: getPaginationRowModel(),
82
+ getPaginationRowModel: serverPagination ? undefined : getPaginationRowModel(),
62
83
  getSortedRowModel: getSortedRowModel(),
63
84
  getFacetedRowModel: getFacetedRowModel(),
64
85
  getFacetedUniqueValues: getFacetedUniqueValues(),
@@ -1,11 +1,12 @@
1
1
  import * as React from "react"
2
2
  import {
3
3
  EnhancedDataTable,
4
+ type DashboardPaginationState,
4
5
  type DashboardRow,
5
6
  type DashboardRowAction,
6
7
  type DashboardTableActionHandlers,
7
8
  } from "@/components/composites/DataTable"
8
- import { dynamicTableSchema, type DynamicTableSchema, type TableColumn } from "ui-schema-contracts"
9
+ import { DYNAMIC_TABLE_SCHEMA_VERSION, dynamicTableSchema, type DynamicTableSchema, type TableColumn } from "ui-schema-contracts"
9
10
 
10
11
  export interface FormReportsEntity {
11
12
  id: number | string
@@ -43,6 +44,7 @@ export interface FormReportsTableProps {
43
44
  items: FormReportsEntity[]
44
45
  columns: FormReportsColumn[]
45
46
  rowActions?: FormReportsRowAction[]
47
+ pagination?: DashboardPaginationState
46
48
  handlers?: FormReportsTableHandlers
47
49
  leftActions?: React.ReactNode
48
50
  rightActions?: React.ReactNode
@@ -57,8 +59,10 @@ const dashboardToFormReportsActionMap: Record<DashboardRowAction, string> = {
57
59
  delete: "delete",
58
60
  }
59
61
 
62
+ export type { DashboardPaginationState }
63
+
60
64
  export const FormReportsTable = React.memo<FormReportsTableProps>(
61
- ({ items, columns, handlers, leftActions, rightActions, onCreateClick, createButtonLabel }) => {
65
+ ({ items, columns, pagination, handlers, leftActions, rightActions, onCreateClick, createButtonLabel }) => {
62
66
  const { rows, originalById, tableSchema } = React.useMemo(() => {
63
67
  const byId = new Map<string, FormReportsEntity>()
64
68
  const tableColumns: DynamicTableSchema["columns"] = columns
@@ -78,7 +82,7 @@ export const FormReportsTable = React.memo<FormReportsTableProps>(
78
82
  rows: nextRows,
79
83
  originalById: byId,
80
84
  tableSchema: dynamicTableSchema.parse({
81
- schemaVersion: "1",
85
+ schemaVersion: DYNAMIC_TABLE_SCHEMA_VERSION,
82
86
  rowKey: "id",
83
87
  columns: tableColumns,
84
88
  enableFiltering: true,
@@ -168,6 +172,7 @@ export const FormReportsTable = React.memo<FormReportsTableProps>(
168
172
  <EnhancedDataTable
169
173
  data={rows}
170
174
  tableSchema={tableSchema}
175
+ pagination={pagination}
171
176
  handlers={adaptedHandlers}
172
177
  leftActions={leftActions}
173
178
  rightActions={rightActions}
@@ -16,6 +16,7 @@ export {
16
16
  } from "./FormReportsTable"
17
17
 
18
18
  export type {
19
+ DashboardPaginationState,
19
20
  FormReportsColumn,
20
21
  FormReportsEntity,
21
22
  FormReportsRowAction,
@@ -3,11 +3,16 @@ import {
3
3
  formSchema,
4
4
  type FormFieldDefinition,
5
5
  type FormSchema,
6
- } from "design-schema"
7
- import { dynamicTableSchema, type DynamicTableSchema } from "ui-schema-contracts"
6
+ } from "design-schema/schemas/form"
7
+ import {
8
+ DYNAMIC_TABLE_SCHEMA_VERSION,
9
+ FORM_SCHEMA_VERSION,
10
+ dynamicTableSchema,
11
+ type DynamicTableSchema,
12
+ } from "ui-schema-contracts"
8
13
 
9
14
  const dashboardTableSchemaInput = {
10
- schemaVersion: "1",
15
+ schemaVersion: DYNAMIC_TABLE_SCHEMA_VERSION,
11
16
  rowKey: "id",
12
17
  columns: [
13
18
  {
@@ -102,7 +107,7 @@ const dashboardTableSchemaInput = {
102
107
  export const dashboardTableSchema: DynamicTableSchema = dynamicTableSchema.parse(dashboardTableSchemaInput)
103
108
 
104
109
  const dashboardCreateFormSchemaInput = {
105
- schemaVersion: "1",
110
+ schemaVersion: FORM_SCHEMA_VERSION,
106
111
  fields: [
107
112
  {
108
113
  name: "slug",
@@ -7,13 +7,18 @@ import type {
7
7
  import {
8
8
  formSchema,
9
9
  type FormSchema,
10
- } from "design-schema"
11
- import { dynamicTableSchema, type DynamicTableSchema } from "ui-schema-contracts"
10
+ } from "design-schema/schemas/form"
11
+ import {
12
+ DYNAMIC_TABLE_SCHEMA_VERSION,
13
+ FORM_SCHEMA_VERSION,
14
+ dynamicTableSchema,
15
+ type DynamicTableSchema,
16
+ } from "ui-schema-contracts"
12
17
 
13
18
  export const formReportsEntityName = "Feature Flag"
14
19
 
15
20
  const formReportsFormSchemaInput = {
16
- schemaVersion: "1",
21
+ schemaVersion: FORM_SCHEMA_VERSION,
17
22
  fields: [
18
23
  {
19
24
  name: "slug",
@@ -65,7 +70,7 @@ const formReportsFormSchemaInput = {
65
70
  export const formReportsFields: FormReportsFieldDefinition[] = formSchema.parse(formReportsFormSchemaInput).fields
66
71
 
67
72
  const formReportsTableSchemaInput = {
68
- schemaVersion: "1",
73
+ schemaVersion: DYNAMIC_TABLE_SCHEMA_VERSION,
69
74
  rowKey: "id",
70
75
  columns: [
71
76
  {
@@ -2,6 +2,7 @@ import * as React from "react"
2
2
 
3
3
  import {
4
4
  FormReportsDrawerForm,
5
+ type DashboardPaginationState,
5
6
  type FormReportsColumn,
6
7
  type FormReportsEntity,
7
8
  type FormReportsFieldDefinition,
@@ -18,6 +19,7 @@ export interface FormReportsFeatureProps {
18
19
  fields: FormReportsFieldDefinition[]
19
20
  columns: FormReportsColumn[]
20
21
  items: FormReportsEntity[]
22
+ pagination?: DashboardPaginationState
21
23
  rowActions?: FormReportsRowAction[]
22
24
  actionHandlers?: FormReportsFeatureActionHandlers
23
25
  createButtonLabel?: string
@@ -39,6 +41,7 @@ export const FormReportsFeature = React.memo<FormReportsFeatureProps>(
39
41
  fields,
40
42
  columns,
41
43
  items,
44
+ pagination,
42
45
  rowActions,
43
46
  actionHandlers,
44
47
  createButtonLabel = "Create",
@@ -105,6 +108,7 @@ export const FormReportsFeature = React.memo<FormReportsFeatureProps>(
105
108
  createButtonLabel={createButtonLabel}
106
109
  items={items}
107
110
  columns={columns}
111
+ pagination={pagination}
108
112
  rowActions={rowActions}
109
113
  tableHandlers={actionHandlers?.table}
110
114
  />
@@ -1,4 +1,5 @@
1
1
  import type {
2
+ DashboardPaginationState,
2
3
  FormReportsColumn,
3
4
  FormReportsEntity,
4
5
  FormReportsFieldDefinition,
@@ -24,6 +25,7 @@ export interface UseFormReportsFeatureReturn {
24
25
  columns: FormReportsColumn[]
25
26
  rowActions?: FormReportsRowAction[]
26
27
  items: FormReportsEntity[]
28
+ pagination?: DashboardPaginationState
27
29
  actionHandlers?: FormReportsFeatureActionHandlers
28
30
  createButtonLabel?: string
29
31
  }