@rowakit/table 0.2.0 → 0.2.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.
package/README.md CHANGED
@@ -644,6 +644,33 @@ type Filters = Record<string, FilterValue>;
644
644
  3. **No client filtering**: All filtering must be handled by your backend
645
645
  4. **Actions/Custom columns**: Not filterable (no filter input rendered)
646
646
 
647
+ **⚠️ Number Filter Behavior:**
648
+
649
+ Number filters use **exact match** semantics (`op: 'equals'`). The filter value is sent as a string, and your backend must handle the comparison:
650
+
651
+ ```typescript
652
+ // If user types "15" in a number filter input
653
+ filters: { discount: { op: 'equals', value: '15' } }
654
+
655
+ // Your backend must convert and compare appropriately:
656
+ // If your data has discount as a fraction (0.15), you must convert:
657
+ // parseInt('15') / 100 === 0.15 OR parseFloat('15') / 100 === 0.15
658
+ ```
659
+
660
+ **Common Pattern:**
661
+
662
+ If your data uses decimals or percentages, ensure your backend coerces the filter value correctly:
663
+
664
+ ```typescript
665
+ // Example: Number filter for percentage discount
666
+ if (filters?.discount) {
667
+ const filterValue = parseFloat(filters.discount.value);
668
+ // If data is stored as fraction (0.15):
669
+ const compareValue = filterValue / 100; // Convert "15" → 0.15
670
+ // Filter records where discount === compareValue
671
+ }
672
+ ```
673
+
647
674
  **Clear Filters:**
648
675
 
649
676
  A "Clear all filters" button appears automatically when filters are active:
@@ -1292,6 +1319,41 @@ Full TypeScript support. Your data model drives type checking throughout.
1292
1319
  - Column resizing
1293
1320
  - Saved views
1294
1321
 
1322
+ ## Changelog
1323
+
1324
+ See the detailed changelog for release history and migration notes:
1325
+
1326
+ - [CHANGELOG.md](./CHANGELOG.md) — highlights and details for v0.2.1 and future releases.
1327
+
1328
+ ### v0.2.1 - Production Release (2026-01-02)
1329
+ - ✅ **Fixed**: Number filter type coercion for accurate field matching
1330
+ - ✅ **Production Ready**: All 193 tests passing, dependencies hardened
1331
+ - ✅ **Backwards Compatible**: No breaking changes from v0.2.0
1332
+
1333
+ ### v0.2.0 - Stage B Features (2026-01-02)
1334
+ - Added `col.badge` and `col.number` column types
1335
+ - Column modifiers: `width`, `align`, `truncate`
1336
+ - Server-side header filter UI with type-specific inputs
1337
+ - Fixed numeric-filter value coercion bug (filter inputs now send numbers)
1338
+
1339
+ ## Release Notes — v0.2.0 (2026-01-02)
1340
+
1341
+ This release introduces Stage B features and several hardening fixes to make `@rowakit/table` production-ready for internal apps.
1342
+
1343
+ - Release: `v0.2.0`
1344
+ - Date: 2026-01-02
1345
+ - Key additions:
1346
+ - `col.badge` — visual badge mapping for enum/status values with tone support
1347
+ - `col.number` — number column with Intl formatting and percentage/currency helpers
1348
+ - Column modifiers (`width`, `align`, `truncate`) supported across column types
1349
+ - Server-side filters: auto-generated, type-specific inputs in the header row
1350
+ - Fixes & hardening:
1351
+ - Removed direct React dependencies (now peerDependencies only)
1352
+ - Resolved numeric filter coercion and clarified backend contract in README
1353
+ - Deduplicated release checklist and improved demo documentation
1354
+
1355
+ See the full changelog for migration notes and detailed descriptions: [CHANGELOG.md](./CHANGELOG.md)
1356
+
1295
1357
  ## License
1296
1358
 
1297
1359
  MIT
package/dist/index.cjs CHANGED
@@ -484,7 +484,7 @@ function RowaKitTable({
484
484
  } else if (isNumberColumn) {
485
485
  const numValue = Number(rawValue);
486
486
  if (!isNaN(numValue)) {
487
- handleFilterChange(field, { op: "equals", value: numValue });
487
+ handleFilterChange(field, { op: "equals", value: rawValue });
488
488
  } else {
489
489
  handleClearFilter(field);
490
490
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/column-helpers.ts","../src/components/SmartTable.tsx","../src/index.ts"],"names":["actions","jsx","jsxs","useState","useRef","useEffect","totalPages"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\r\n * Column helper factory functions\r\n *\r\n * These helpers provide a clean, type-safe API for defining table columns.\r\n * They reduce boilerplate and enforce conventions while maintaining flexibility\r\n * through the `col.custom` escape hatch.\r\n *\r\n * @packageDocumentation\r\n */\r\n\r\nimport type { ReactNode } from 'react';\r\nimport type {\r\n TextColumnDef,\r\n DateColumnDef,\r\n BooleanColumnDef,\r\n BadgeColumnDef,\r\n NumberColumnDef,\r\n ActionsColumnDef,\r\n CustomColumnDef,\r\n ActionDef,\r\n BadgeTone,\r\n} from './types';\r\n\r\n// ============================================================================\r\n// HELPER OPTIONS\r\n// ============================================================================\r\n\r\ninterface TextOptions {\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Enable sorting for this column */\r\n sortable?: boolean;\r\n /** Optional formatter function */\r\n format?: (value: unknown) => string;\r\n /** Column width in pixels */\r\n width?: number;\r\n /** Text alignment */\r\n align?: 'left' | 'center' | 'right';\r\n /** Enable text truncation with ellipsis */\r\n truncate?: boolean;\r\n}\r\n\r\ninterface DateOptions {\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Enable sorting for this column */\r\n sortable?: boolean;\r\n /** Optional date formatter function */\r\n format?: (value: Date | string | number) => string;\r\n /** Column width in pixels */\r\n width?: number;\r\n /** Text alignment */\r\n align?: 'left' | 'center' | 'right';\r\n /** Enable text truncation with ellipsis */\r\n truncate?: boolean;\r\n}\r\n\r\ninterface BooleanOptions {\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Enable sorting for this column */\r\n sortable?: boolean;\r\n /** Optional boolean formatter function */\r\n format?: (value: boolean) => string;\r\n /** Column width in pixels */\r\n width?: number;\r\n /** Text alignment */\r\n align?: 'left' | 'center' | 'right';\r\n /** Enable text truncation with ellipsis */\r\n truncate?: boolean;\r\n}\r\n\r\ninterface BadgeOptions {\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Enable sorting for this column */\r\n sortable?: boolean;\r\n /** Value-to-badge mapping */\r\n map?: Record<string, { label: string; tone: BadgeTone }>;\r\n /** Column width in pixels */\r\n width?: number;\r\n /** Text alignment */\r\n align?: 'left' | 'center' | 'right';\r\n /** Enable text truncation with ellipsis */\r\n truncate?: boolean;\r\n}\r\n\r\ninterface NumberOptions<T = unknown> {\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Enable sorting for this column */\r\n sortable?: boolean;\r\n /** Formatting options: Intl.NumberFormatOptions or custom formatter */\r\n format?: Intl.NumberFormatOptions | ((value: number, row: T) => string);\r\n /** Column width in pixels */\r\n width?: number;\r\n /** Text alignment */\r\n align?: 'left' | 'center' | 'right';\r\n /** Enable text truncation with ellipsis */\r\n truncate?: boolean;\r\n}\r\n\r\n// ============================================================================\r\n// COLUMN HELPER FUNCTIONS\r\n// ============================================================================\r\n\r\n/**\r\n * Create a text column definition.\r\n *\r\n * @example\r\n * ```ts\r\n * col.text('name')\r\n * col.text('email', { header: 'Email Address', sortable: true })\r\n * col.text('status', { format: (val) => val.toUpperCase() })\r\n * ```\r\n */\r\nfunction text<T>(\r\n field: keyof T & string,\r\n options?: TextOptions\r\n): TextColumnDef<T> {\r\n return {\r\n id: field,\r\n kind: 'text',\r\n field,\r\n header: options?.header,\r\n sortable: options?.sortable ?? false,\r\n format: options?.format,\r\n width: options?.width,\r\n align: options?.align,\r\n truncate: options?.truncate,\r\n };\r\n}\r\n\r\n/**\r\n * Create a date column definition.\r\n *\r\n * @example\r\n * ```ts\r\n * col.date('createdAt')\r\n * col.date('updatedAt', { header: 'Last Modified', sortable: true })\r\n * col.date('birthday', {\r\n * format: (date) => new Date(date).toLocaleDateString()\r\n * })\r\n * ```\r\n */\r\nfunction date<T>(\r\n field: keyof T & string,\r\n options?: DateOptions\r\n): DateColumnDef<T> {\r\n return {\r\n id: field,\r\n kind: 'date',\r\n field,\r\n header: options?.header,\r\n sortable: options?.sortable ?? false,\r\n format: options?.format,\r\n width: options?.width,\r\n align: options?.align,\r\n truncate: options?.truncate,\r\n };\r\n}\r\n\r\n/**\r\n * Create a boolean column definition.\r\n *\r\n * @example\r\n * ```ts\r\n * col.boolean('active')\r\n * col.boolean('isPublished', { header: 'Published', sortable: true })\r\n * col.boolean('enabled', {\r\n * format: (val) => val ? 'Yes' : 'No'\r\n * })\r\n * ```\r\n */\r\nfunction boolean<T>(\r\n field: keyof T & string,\r\n options?: BooleanOptions\r\n): BooleanColumnDef<T> {\r\n return {\r\n id: field,\r\n kind: 'boolean',\r\n field,\r\n header: options?.header,\r\n sortable: options?.sortable ?? false,\r\n format: options?.format,\r\n width: options?.width,\r\n align: options?.align,\r\n truncate: options?.truncate,\r\n };\r\n}\r\n\r\n/**\r\n * Create a badge column definition for status/enum fields.\r\n *\r\n * @example\r\n * ```ts\r\n * col.badge('status')\r\n * col.badge('status', {\r\n * map: {\r\n * active: { label: 'Active', tone: 'success' },\r\n * paused: { label: 'Paused', tone: 'warning' },\r\n * disabled: { label: 'Disabled', tone: 'danger' }\r\n * }\r\n * })\r\n * ```\r\n */\r\nfunction badge<T>(\r\n field: keyof T & string,\r\n options?: BadgeOptions\r\n): BadgeColumnDef<T> {\r\n return {\r\n id: field,\r\n kind: 'badge',\r\n field,\r\n header: options?.header,\r\n sortable: options?.sortable ?? false,\r\n map: options?.map,\r\n width: options?.width,\r\n align: options?.align,\r\n truncate: options?.truncate,\r\n };\r\n}\r\n\r\n/**\r\n * Create a number column definition.\r\n *\r\n * @example\r\n * ```ts\r\n * col.number('amount')\r\n * col.number('price', {\r\n * format: { style: 'currency', currency: 'USD' }\r\n * })\r\n * col.number('count', {\r\n * format: (val, row) => `${val} items`\r\n * })\r\n * ```\r\n */\r\nfunction number<T>(\r\n field: keyof T & string,\r\n options?: NumberOptions<T>\r\n): NumberColumnDef<T> {\r\n return {\r\n id: field,\r\n kind: 'number',\r\n field,\r\n header: options?.header,\r\n sortable: options?.sortable ?? false,\r\n format: options?.format,\r\n width: options?.width,\r\n align: options?.align,\r\n truncate: options?.truncate,\r\n };\r\n}\r\n\r\n/**\r\n * Create an actions column definition.\r\n *\r\n * The actions column displays a set of actions (buttons/links) that can be\r\n * performed on each row.\r\n *\r\n * @example\r\n * ```ts\r\n * col.actions([\r\n * { id: 'edit', label: 'Edit', onClick: (row) => editUser(row) },\r\n * { id: 'delete', label: 'Delete', confirm: true, onClick: (row) => deleteUser(row) }\r\n * ])\r\n * ```\r\n */\r\nfunction actions<T>(actions: ActionDef<T>[]): ActionsColumnDef<T> {\r\n return {\r\n id: 'actions',\r\n kind: 'actions',\r\n actions,\r\n };\r\n}\r\n\r\n/**\r\n * Create a custom column definition with full rendering control.\r\n *\r\n * This is the escape hatch for any column that doesn't fit the standard types.\r\n * Use this for badges, avatars, complex formatting, or any custom UI.\r\n *\r\n * @example\r\n * ```ts\r\n * col.custom({\r\n * id: 'avatar',\r\n * header: 'User',\r\n * render: (row) => <img src={row.avatar} alt={row.name} />\r\n * })\r\n *\r\n * col.custom({\r\n * id: 'price',\r\n * field: 'price',\r\n * render: (row) => <Money amount={row.price} currency={row.currency} />\r\n * })\r\n *\r\n * col.custom({\r\n * id: 'status',\r\n * render: (row) => (\r\n * <Badge color={row.status === 'active' ? 'green' : 'gray'}>\r\n * {row.status}\r\n * </Badge>\r\n * )\r\n * })\r\n * ```\r\n */\r\nfunction custom<T>(\r\n field: keyof T & string,\r\n render: (row: T) => ReactNode\r\n): CustomColumnDef<T>;\r\nfunction custom<T>(options: {\r\n /** Unique column identifier */\r\n id: string;\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Optional field name for sorting/filtering */\r\n field?: keyof T & string;\r\n /** Render function for cell content */\r\n render: (row: T) => ReactNode;\r\n}): CustomColumnDef<T>;\r\nfunction custom<T>(\r\n arg1:\r\n | (keyof T & string)\r\n | {\r\n id: string;\r\n header?: string;\r\n field?: keyof T & string;\r\n render: (row: T) => ReactNode;\r\n },\r\n arg2?: (row: T) => ReactNode\r\n): CustomColumnDef<T> {\r\n if (typeof arg1 === 'string') {\r\n if (typeof arg2 !== 'function') {\r\n throw new Error('col.custom(field, render): render must be a function');\r\n }\r\n\r\n return {\r\n id: arg1,\r\n kind: 'custom',\r\n field: arg1,\r\n render: arg2,\r\n };\r\n }\r\n\r\n return {\r\n id: arg1.id,\r\n kind: 'custom',\r\n header: arg1.header,\r\n field: arg1.field,\r\n render: arg1.render,\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// EXPORTS\r\n// ============================================================================\r\n\r\n/**\r\n * Column helper factory object.\r\n *\r\n * Provides convenient helper functions for creating column definitions.\r\n *\r\n * @example\r\n * ```tsx\r\n * import { col } from '@rowakit/table';\r\n *\r\n * const columns = [\r\n * col.text('name', { sortable: true }),\r\n * col.date('createdAt'),\r\n * col.boolean('active'),\r\n * col.actions([\r\n * { id: 'edit', label: 'Edit', onClick: (row) => {} }\r\n * ]),\r\n * col.custom({ id: 'badge', render: (row) => <Badge>{row.status}</Badge> })\r\n * ];\r\n * ```\r\n */\r\nexport const col = {\r\n text,\r\n date,\r\n boolean,\r\n badge,\r\n number,\r\n actions,\r\n custom,\r\n} as const;\r\n","/**\r\n * RowaKit Table Component\r\n *\r\n * Core table rendering component that maps columns to table cells.\r\n * Handles all column types: text, date, boolean, actions, and custom.\r\n * Includes data fetching state machine with loading/error/empty states.\r\n *\r\n * @packageDocumentation\r\n */\r\n\r\nimport { useState, useEffect, useRef } from 'react';\r\nimport type { ReactNode } from 'react';\r\nimport type { Fetcher, ColumnDef, FetcherQuery, ActionDef, FilterValue } from '../types';\r\n\r\n// ============================================================================\r\n// COMPONENT PROPS\r\n// ============================================================================\r\n\r\nexport interface SmartTableProps<T> {\r\n /** Server-side data fetcher function */\r\n fetcher: Fetcher<T>;\r\n\r\n /** Array of column definitions */\r\n columns: ColumnDef<T>[];\r\n\r\n /** Available page size options (default: [10, 20, 50]) */\r\n pageSizeOptions?: number[];\r\n\r\n /** Initial page size (default: 20) */\r\n defaultPageSize?: number;\r\n\r\n /** Function or field name to extract row key (default: uses 'id' field) */\r\n rowKey?: keyof T | ((row: T) => string | number);\r\n\r\n /** Optional CSS class name for the table container */\r\n className?: string;\r\n\r\n /** Enable filters (default: false) */\r\n enableFilters?: boolean;\r\n}\r\n\r\n// ============================================================================\r\n// STATE MANAGEMENT\r\n// ============================================================================\r\n\r\ntype FetchState = 'idle' | 'loading' | 'success' | 'empty' | 'error';\r\n\r\ninterface DataState<T> {\r\n state: FetchState;\r\n items: T[];\r\n total: number;\r\n error?: string;\r\n}\r\n\r\n/**\r\n * Confirmation state for actions that require confirmation.\r\n */\r\ninterface ConfirmState<T> {\r\n action: ActionDef<T>;\r\n row: T;\r\n}\r\n\r\n// ============================================================================\r\n// HELPER FUNCTIONS\r\n// ============================================================================\r\n\r\n/**\r\n * Extract unique key from a row.\r\n */\r\nfunction getRowKey<T>(row: T, rowKey?: keyof T | ((row: T) => string | number)): string | number {\r\n if (typeof rowKey === 'function') {\r\n return rowKey(row);\r\n }\r\n if (rowKey) {\r\n return String(row[rowKey]);\r\n }\r\n // Fallback to 'id' field if available\r\n if (row && typeof row === 'object' && 'id' in row) {\r\n return String(row.id);\r\n }\r\n // Last resort: use object reference (not ideal but safe)\r\n return String(row);\r\n}\r\n\r\n/**\r\n * Get header label for a column.\r\n */\r\nfunction getHeaderLabel<T>(column: ColumnDef<T>): string {\r\n return column.header ?? column.id;\r\n}\r\n\r\n/**\r\n * Render cell content based on column kind.\r\n */\r\nfunction renderCell<T>(\r\n column: ColumnDef<T>,\r\n row: T,\r\n isLoading: boolean,\r\n setConfirmState: (state: ConfirmState<T> | null) => void\r\n): ReactNode {\r\n switch (column.kind) {\r\n case 'text': {\r\n const value = row[column.field];\r\n if (column.format) {\r\n return column.format(value);\r\n }\r\n return String(value ?? '');\r\n }\r\n\r\n case 'date': {\r\n const value = row[column.field];\r\n if (column.format) {\r\n return column.format(value as Date | string | number);\r\n }\r\n // Default date formatting\r\n if (value instanceof Date) {\r\n return value.toLocaleDateString();\r\n }\r\n if (typeof value === 'string' || typeof value === 'number') {\r\n return new Date(value).toLocaleDateString();\r\n }\r\n return '';\r\n }\r\n\r\n case 'boolean': {\r\n const value = row[column.field];\r\n if (column.format) {\r\n return column.format(Boolean(value));\r\n }\r\n // Default boolean formatting\r\n return value ? 'Yes' : 'No';\r\n }\r\n\r\n case 'badge': {\r\n const value = row[column.field];\r\n const valueStr = String(value ?? '');\r\n \r\n // Look up mapping\r\n const mapped = column.map?.[valueStr];\r\n const label = mapped?.label ?? valueStr;\r\n const tone = mapped?.tone ?? 'neutral';\r\n \r\n return (\r\n <span className={`rowakit-badge rowakit-badge-${tone}`}>\r\n {label}\r\n </span>\r\n );\r\n }\r\n\r\n case 'number': {\r\n const value = row[column.field];\r\n const numValue = Number(value ?? 0);\r\n \r\n if (column.format) {\r\n if (typeof column.format === 'function') {\r\n return column.format(numValue, row);\r\n }\r\n // Intl.NumberFormatOptions\r\n return new Intl.NumberFormat(undefined, column.format).format(numValue);\r\n }\r\n \r\n // Default number formatting\r\n return numValue.toLocaleString();\r\n }\r\n\r\n case 'actions': {\r\n return (\r\n <div className=\"rowakit-table-actions\">\r\n {column.actions.map((action) => {\r\n const isDisabled =\r\n isLoading ||\r\n action.disabled === true ||\r\n (typeof action.disabled === 'function' && action.disabled(row));\r\n\r\n const handleClick = () => {\r\n if (isDisabled || action.loading) {\r\n return;\r\n }\r\n\r\n // If action requires confirmation, show modal\r\n if (action.confirm) {\r\n setConfirmState({ action, row });\r\n } else {\r\n // Execute action directly\r\n void action.onClick(row);\r\n }\r\n };\r\n\r\n return (\r\n <button\r\n key={action.id}\r\n onClick={handleClick}\r\n disabled={isDisabled || action.loading}\r\n type=\"button\"\r\n className=\"rowakit-button rowakit-button-secondary\"\r\n >\r\n {action.icon && typeof action.icon === 'string' ? (\r\n <span>{action.icon}</span>\r\n ) : (\r\n action.icon\r\n )}\r\n {action.label}\r\n </button>\r\n );\r\n })}\r\n </div>\r\n );\r\n }\r\n\r\n case 'custom': {\r\n return column.render(row);\r\n }\r\n\r\n default: {\r\n // Exhaustive check\r\n const _exhaustive: never = column;\r\n return _exhaustive;\r\n }\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// MAIN COMPONENT\r\n// ============================================================================\r\n\r\n/**\r\n * RowaKitTable - Server-side table component for internal/business apps.\r\n *\r\n * This component renders a table with headers and body based on column definitions.\r\n * It handles all column types (text, date, boolean, actions, custom) and provides\r\n * a clean API for defining table structure.\r\n *\r\n * Features:\r\n * - Automatic data fetching on mount and query changes\r\n * - Loading, error, and empty states\r\n * - Stale request handling\r\n * - Retry on error\r\n *\r\n * @example\r\n * ```tsx\r\n * import { RowaKitTable, col } from '@rowakit/table';\r\n *\r\n * interface User {\r\n * id: string;\r\n * name: string;\r\n * email: string;\r\n * createdAt: Date;\r\n * active: boolean;\r\n * }\r\n *\r\n * const fetchUsers: Fetcher<User> = async (query) => {\r\n * const response = await fetch(`/api/users?page=${query.page}&pageSize=${query.pageSize}`);\r\n * return response.json();\r\n * };\r\n *\r\n * function UsersTable() {\r\n * return (\r\n * <RowaKitTable\r\n * fetcher={fetchUsers}\r\n * columns={[\r\n * col.text('name', { header: 'Name', sortable: true }),\r\n * col.text('email', { header: 'Email' }),\r\n * col.date('createdAt', { header: 'Created' }),\r\n * col.boolean('active', { header: 'Active' }),\r\n * col.actions([\r\n * { id: 'edit', label: 'Edit', onClick: (user) => editUser(user) },\r\n * { id: 'delete', label: 'Delete', confirm: true, onClick: (user) => deleteUser(user) }\r\n * ])\r\n * ]}\r\n * defaultPageSize={20}\r\n * rowKey=\"id\"\r\n * />\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport function RowaKitTable<T>({\r\n fetcher,\r\n columns,\r\n defaultPageSize = 20,\r\n pageSizeOptions = [10, 20, 50],\r\n rowKey,\r\n className = '',\r\n enableFilters = false,\r\n}: SmartTableProps<T>) {\r\n // State management\r\n const [dataState, setDataState] = useState<DataState<T>>({\r\n state: 'idle',\r\n items: [],\r\n total: 0,\r\n });\r\n\r\n const [query, setQuery] = useState<FetcherQuery>({\r\n page: 1,\r\n pageSize: defaultPageSize,\r\n });\r\n\r\n // Filter state (field -> FilterValue)\r\n const [filters, setFilters] = useState<Record<string, FilterValue | undefined>>({});\r\n\r\n // Confirmation state for actions that require confirmation\r\n const [confirmState, setConfirmState] = useState<ConfirmState<T> | null>(null);\r\n\r\n // Request tracking to ignore stale responses\r\n const requestIdRef = useRef(0);\r\n\r\n // Sync filters to query (and reset page to 1 when filters change)\r\n useEffect(() => {\r\n if (!enableFilters) return;\r\n\r\n // Build filters object, excluding undefined values\r\n const activeFilters: Record<string, FilterValue> = {};\r\n let hasFilters = false;\r\n \r\n for (const [field, value] of Object.entries(filters)) {\r\n if (value !== undefined) {\r\n activeFilters[field] = value;\r\n hasFilters = true;\r\n }\r\n }\r\n\r\n // Per spec: filters must be undefined when empty (not {})\r\n const filtersToSend = hasFilters ? activeFilters : undefined;\r\n\r\n setQuery((prev) => ({\r\n ...prev,\r\n filters: filtersToSend,\r\n page: 1, // Reset page to 1 when filters change\r\n }));\r\n }, [filters, enableFilters]);\r\n\r\n // Fetch data effect\r\n useEffect(() => {\r\n const currentRequestId = ++requestIdRef.current;\r\n\r\n setDataState((prev) => ({ ...prev, state: 'loading' }));\r\n\r\n fetcher(query)\r\n .then((result) => {\r\n // Ignore stale responses\r\n if (currentRequestId !== requestIdRef.current) {\r\n return;\r\n }\r\n\r\n if (result.items.length === 0) {\r\n setDataState({\r\n state: 'empty',\r\n items: [],\r\n total: result.total,\r\n });\r\n } else {\r\n setDataState({\r\n state: 'success',\r\n items: result.items,\r\n total: result.total,\r\n });\r\n }\r\n })\r\n .catch((error: unknown) => {\r\n // Ignore stale responses\r\n if (currentRequestId !== requestIdRef.current) {\r\n return;\r\n }\r\n\r\n setDataState({\r\n state: 'error',\r\n items: [],\r\n total: 0,\r\n error: error instanceof Error ? error.message : 'Failed to load data',\r\n });\r\n });\r\n }, [fetcher, query]);\r\n\r\n // Retry handler\r\n const handleRetry = () => {\r\n // Force re-fetch by updating query reference\r\n setQuery({ ...query });\r\n };\r\n\r\n // Pagination handlers\r\n const handlePreviousPage = () => {\r\n if (query.page > 1) {\r\n setQuery((prev) => ({ ...prev, page: prev.page - 1 }));\r\n }\r\n };\r\n\r\n const handleNextPage = () => {\r\n const totalPages = Math.ceil(dataState.total / query.pageSize);\r\n if (query.page < totalPages) {\r\n setQuery((prev) => ({ ...prev, page: prev.page + 1 }));\r\n }\r\n };\r\n\r\n const handlePageSizeChange = (newPageSize: number) => {\r\n setQuery({ ...query, pageSize: newPageSize, page: 1 });\r\n };\r\n\r\n // Sorting handler\r\n const handleSort = (field: string) => {\r\n setQuery((prev) => {\r\n // If sorting by a different field, start with ascending\r\n if (prev.sort?.field !== field) {\r\n return { ...prev, sort: { field, direction: 'asc' }, page: 1 };\r\n }\r\n\r\n // Toggle sort direction for the same field\r\n if (prev.sort.direction === 'asc') {\r\n return { ...prev, sort: { field, direction: 'desc' }, page: 1 };\r\n }\r\n\r\n // Remove sort (back to unsorted)\r\n const { sort: _sort, ...rest } = prev;\r\n return { ...rest, page: 1 };\r\n });\r\n };\r\n\r\n // Get sort indicator for a column\r\n const getSortIndicator = (field: string): string => {\r\n if (!query.sort || query.sort.field !== field) {\r\n return '';\r\n }\r\n return query.sort.direction === 'asc' ? ' ↑' : ' ↓';\r\n };\r\n\r\n // Filter handlers\r\n const handleFilterChange = (field: string, value: FilterValue | undefined) => {\r\n setFilters((prev) => ({\r\n ...prev,\r\n [field]: value,\r\n }));\r\n };\r\n\r\n const handleClearFilter = (field: string) => {\r\n setFilters((prev) => {\r\n const newFilters = { ...prev };\r\n delete newFilters[field];\r\n return newFilters;\r\n });\r\n };\r\n\r\n const handleClearAllFilters = () => {\r\n setFilters({});\r\n };\r\n\r\n const isLoading = dataState.state === 'loading';\r\n const isError = dataState.state === 'error';\r\n const isEmpty = dataState.state === 'empty';\r\n const totalPages = Math.ceil(dataState.total / query.pageSize);\r\n const canGoPrevious = query.page > 1 && !isLoading;\r\n const canGoNext = query.page < totalPages && !isLoading;\r\n\r\n const hasActiveFilters = enableFilters && Object.values(filters).some(v => v !== undefined);\r\n\r\n return (\r\n <div className={`rowakit-table${className ? ` ${className}` : ''}`}>\r\n {hasActiveFilters && (\r\n <div className=\"rowakit-table-filter-controls\">\r\n <button\r\n onClick={handleClearAllFilters}\r\n className=\"rowakit-button rowakit-button-secondary\"\r\n type=\"button\"\r\n >\r\n Clear all filters\r\n </button>\r\n </div>\r\n )}\r\n <table>\r\n <thead>\r\n <tr>\r\n {columns.map((column) => {\r\n const isSortable = column.kind !== 'actions' && \r\n (column.kind === 'custom' ? false : column.sortable === true);\r\n const field = column.kind === 'actions' ? '' : \r\n column.kind === 'custom' ? column.field : \r\n column.field;\r\n\r\n return (\r\n <th\r\n key={column.id}\r\n onClick={isSortable ? () => handleSort(String(field)) : undefined}\r\n role={isSortable ? 'button' : undefined}\r\n tabIndex={isSortable ? 0 : undefined}\r\n onKeyDown={isSortable ? (e) => {\r\n if (e.key === 'Enter' || e.key === ' ') {\r\n e.preventDefault();\r\n handleSort(String(field));\r\n }\r\n } : undefined}\r\n aria-sort={\r\n isSortable && query.sort?.field === String(field)\r\n ? query.sort.direction === 'asc' ? 'ascending' : 'descending'\r\n : undefined\r\n }\r\n style={{\r\n width: column.width ? `${column.width}px` : undefined,\r\n textAlign: column.align,\r\n }}\r\n className={column.truncate ? 'rowakit-cell-truncate' : undefined}\r\n >\r\n {getHeaderLabel(column)}{isSortable && getSortIndicator(String(field))}\r\n </th>\r\n );\r\n })}\r\n </tr>\r\n {enableFilters && (\r\n <tr className=\"rowakit-table-filter-row\">\r\n {columns.map((column) => {\r\n const field = column.kind === 'actions' || column.kind === 'custom' ? '' : String(column.field);\r\n const canFilter = field && column.kind !== 'actions';\r\n \r\n if (!canFilter) {\r\n return <th key={column.id}></th>;\r\n }\r\n\r\n const filterValue = filters[field];\r\n\r\n // Badge column: select with options\r\n if (column.kind === 'badge') {\r\n const options = column.map ? Object.keys(column.map) : [];\r\n return (\r\n <th key={column.id}>\r\n <select\r\n className=\"rowakit-filter-select\"\r\n value={filterValue?.op === 'equals' ? String(filterValue.value ?? '') : ''}\r\n onChange={(e) => {\r\n const value = e.target.value;\r\n if (value === '') {\r\n handleClearFilter(field);\r\n } else {\r\n handleFilterChange(field, { op: 'equals', value });\r\n }\r\n }}\r\n >\r\n <option value=\"\">All</option>\r\n {options.map((opt) => (\r\n <option key={opt} value={opt}>\r\n {opt}\r\n </option>\r\n ))}\r\n </select>\r\n </th>\r\n );\r\n }\r\n\r\n // Boolean column: select with True/False/All\r\n if (column.kind === 'boolean') {\r\n return (\r\n <th key={column.id}>\r\n <select\r\n className=\"rowakit-filter-select\"\r\n value={\r\n filterValue?.op === 'equals' && typeof filterValue.value === 'boolean'\r\n ? String(filterValue.value)\r\n : ''\r\n }\r\n onChange={(e) => {\r\n const value = e.target.value;\r\n if (value === '') {\r\n handleClearFilter(field);\r\n } else {\r\n handleFilterChange(field, { op: 'equals', value: value === 'true' });\r\n }\r\n }}\r\n >\r\n <option value=\"\">All</option>\r\n <option value=\"true\">True</option>\r\n <option value=\"false\">False</option>\r\n </select>\r\n </th>\r\n );\r\n }\r\n\r\n // Date column: from/to inputs\r\n if (column.kind === 'date') {\r\n const fromValue = filterValue?.op === 'range' ? filterValue.value.from ?? '' : '';\r\n const toValue = filterValue?.op === 'range' ? filterValue.value.to ?? '' : '';\r\n \r\n return (\r\n <th key={column.id}>\r\n <div className=\"rowakit-filter-date-range\">\r\n <input\r\n type=\"date\"\r\n className=\"rowakit-filter-input\"\r\n placeholder=\"From\"\r\n value={fromValue}\r\n onChange={(e) => {\r\n const from = e.target.value || undefined;\r\n const to = toValue || undefined;\r\n if (!from && !to) {\r\n handleClearFilter(field);\r\n } else {\r\n handleFilterChange(field, { op: 'range', value: { from, to } });\r\n }\r\n }}\r\n />\r\n <input\r\n type=\"date\"\r\n className=\"rowakit-filter-input\"\r\n placeholder=\"To\"\r\n value={toValue}\r\n onChange={(e) => {\r\n const to = e.target.value || undefined;\r\n const from = fromValue || undefined;\r\n if (!from && !to) {\r\n handleClearFilter(field);\r\n } else {\r\n handleFilterChange(field, { op: 'range', value: { from, to } });\r\n }\r\n }}\r\n />\r\n </div>\r\n </th>\r\n );\r\n }\r\n\r\n // Text/Number column: text or number input\r\n const isNumberColumn = column.kind === 'number';\r\n return (\r\n <th key={column.id}>\r\n <input\r\n type={isNumberColumn ? 'number' : 'text'}\r\n className=\"rowakit-filter-input\"\r\n placeholder={`Filter ${getHeaderLabel(column)}...`}\r\n value={\r\n filterValue?.op === 'contains'\r\n ? filterValue.value\r\n : filterValue?.op === 'equals' && typeof filterValue.value === 'string'\r\n ? filterValue.value\r\n : filterValue?.op === 'equals' && typeof filterValue.value === 'number'\r\n ? String(filterValue.value)\r\n : ''\r\n }\r\n onChange={(e) => {\r\n const rawValue = e.target.value;\r\n if (rawValue === '') {\r\n handleClearFilter(field);\r\n } else if (isNumberColumn) {\r\n const numValue = Number(rawValue);\r\n if (!isNaN(numValue)) {\r\n handleFilterChange(field, { op: 'equals', value: numValue } as FilterValue);\r\n } else {\r\n // Invalid numeric input: clear the filter to avoid confusing UX\r\n handleClearFilter(field);\r\n }\r\n } else {\r\n // Text: use \"contains\"\r\n handleFilterChange(field, { op: 'contains', value: rawValue } as FilterValue);\r\n }\r\n }}\r\n />\r\n </th>\r\n );\r\n })}\r\n </tr>\r\n )}\r\n </thead>\r\n <tbody>\r\n {isLoading && (\r\n <tr>\r\n <td colSpan={columns.length} className=\"rowakit-table-loading\">\r\n <div className=\"rowakit-table-loading-spinner\"></div>\r\n <span>Loading...</span>\r\n </td>\r\n </tr>\r\n )}\r\n\r\n {isError && (\r\n <tr>\r\n <td colSpan={columns.length} className=\"rowakit-table-error\">\r\n <div className=\"rowakit-table-error-message\">\r\n {dataState.error ?? 'An error occurred'}\r\n </div>\r\n <button\r\n onClick={handleRetry}\r\n className=\"rowakit-button rowakit-button-primary\"\r\n type=\"button\"\r\n >\r\n Retry\r\n </button>\r\n </td>\r\n </tr>\r\n )}\r\n\r\n {isEmpty && (\r\n <tr>\r\n <td colSpan={columns.length} className=\"rowakit-table-empty\">\r\n No data\r\n </td>\r\n </tr>\r\n )}\r\n\r\n {dataState.state === 'success' &&\r\n dataState.items.map((row) => {\r\n const key = getRowKey(row, rowKey);\r\n return (\r\n <tr key={key}>\r\n {columns.map((column) => {\r\n const cellClass = [\r\n column.kind === 'number' ? 'rowakit-cell-number' : '',\r\n column.truncate ? 'rowakit-cell-truncate' : '',\r\n ].filter(Boolean).join(' ') || undefined;\r\n \r\n return (\r\n <td \r\n key={column.id}\r\n className={cellClass}\r\n style={{\r\n width: column.width ? `${column.width}px` : undefined,\r\n textAlign: column.align || (column.kind === 'number' ? 'right' : undefined),\r\n }}\r\n >\r\n {renderCell(column, row, isLoading, setConfirmState)}\r\n </td>\r\n );\r\n })}\r\n </tr>\r\n );\r\n })}\r\n </tbody>\r\n </table>\r\n\r\n {/* Pagination Controls */}\r\n {dataState.total > 0 && (\r\n <div className=\"rowakit-table-pagination\">\r\n {/* Left: Page size selector */}\r\n <div className=\"rowakit-table-pagination-left\">\r\n <label htmlFor=\"page-size\">\r\n Rows per page:\r\n </label>\r\n <select\r\n id=\"page-size\"\r\n value={query.pageSize}\r\n onChange={(e) => handlePageSizeChange(Number(e.target.value))}\r\n disabled={isLoading}\r\n >\r\n {pageSizeOptions.map((size) => (\r\n <option key={size} value={size}>\r\n {size}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n\r\n {/* Center: Page info */}\r\n <div className=\"rowakit-table-pagination-center\">\r\n Page {query.page} of {totalPages} ({dataState.total} total)\r\n </div>\r\n\r\n {/* Right: Previous/Next buttons */}\r\n <div className=\"rowakit-table-pagination-right\">\r\n <button\r\n onClick={handlePreviousPage}\r\n disabled={!canGoPrevious}\r\n className=\"rowakit-button rowakit-button-primary rowakit-button-pagination\"\r\n type=\"button\"\r\n aria-label=\"Previous page\"\r\n >\r\n Previous\r\n </button>\r\n <button\r\n onClick={handleNextPage}\r\n disabled={!canGoNext}\r\n className=\"rowakit-button rowakit-button-primary rowakit-button-pagination\"\r\n type=\"button\"\r\n aria-label=\"Next page\"\r\n >\r\n Next\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Confirmation Modal */}\r\n {confirmState && (\r\n <div\r\n className=\"rowakit-modal-backdrop\"\r\n onClick={() => setConfirmState(null)}\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n aria-labelledby=\"confirm-dialog-title\"\r\n >\r\n <div className=\"rowakit-modal\" onClick={(e) => e.stopPropagation()}>\r\n <h2 id=\"confirm-dialog-title\" className=\"rowakit-modal-title\">\r\n Confirm Action\r\n </h2>\r\n <p className=\"rowakit-modal-content\">\r\n Are you sure you want to {confirmState.action.label.toLowerCase()}? This action cannot be\r\n undone.\r\n </p>\r\n <div className=\"rowakit-modal-actions\">\r\n <button\r\n onClick={() => setConfirmState(null)}\r\n className=\"rowakit-button rowakit-button-secondary\"\r\n type=\"button\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n onClick={() => {\r\n void confirmState.action.onClick(confirmState.row);\r\n setConfirmState(null);\r\n }}\r\n className=\"rowakit-button rowakit-button-danger\"\r\n type=\"button\"\r\n >\r\n Confirm\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n/**\r\n * @deprecated Use RowaKitTable instead. SmartTable is kept as an alias for backward compatibility.\r\n */\r\nexport const SmartTable = RowaKitTable;\r\n","/**\r\n * @rowakit/table\r\n *\r\n * Opinionated, server-side-first table component for internal/business apps.\r\n *\r\n * @packageDocumentation\r\n */\r\n\r\n// Core types\r\nexport type {\r\n // Fetcher types\r\n Fetcher,\r\n FetcherQuery,\r\n FetcherResult,\r\n FilterValue,\r\n Filters,\r\n // Column types\r\n ColumnDef,\r\n ColumnKind,\r\n BaseColumnDef,\r\n TextColumnDef,\r\n DateColumnDef,\r\n BooleanColumnDef,\r\n BadgeColumnDef,\r\n NumberColumnDef,\r\n ActionsColumnDef,\r\n CustomColumnDef,\r\n BadgeTone,\r\n // Action types\r\n ActionDef,\r\n} from './types';\r\n\r\n// Column helper factory\r\nexport { col } from './column-helpers';\r\n\r\n// Components\r\nexport { RowaKitTable, SmartTable } from './components/SmartTable';\r\nexport type { SmartTableProps } from './components/SmartTable';\r\n\r\nexport const VERSION = '0.1.0';\r\n"]}
1
+ {"version":3,"sources":["../src/column-helpers.ts","../src/components/SmartTable.tsx","../src/index.ts"],"names":["actions","jsx","jsxs","useState","useRef","useEffect","totalPages"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\r\n * Column helper factory functions\r\n *\r\n * These helpers provide a clean, type-safe API for defining table columns.\r\n * They reduce boilerplate and enforce conventions while maintaining flexibility\r\n * through the `col.custom` escape hatch.\r\n *\r\n * @packageDocumentation\r\n */\r\n\r\nimport type { ReactNode } from 'react';\r\nimport type {\r\n TextColumnDef,\r\n DateColumnDef,\r\n BooleanColumnDef,\r\n BadgeColumnDef,\r\n NumberColumnDef,\r\n ActionsColumnDef,\r\n CustomColumnDef,\r\n ActionDef,\r\n BadgeTone,\r\n} from './types';\r\n\r\n// ============================================================================\r\n// HELPER OPTIONS\r\n// ============================================================================\r\n\r\ninterface TextOptions {\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Enable sorting for this column */\r\n sortable?: boolean;\r\n /** Optional formatter function */\r\n format?: (value: unknown) => string;\r\n /** Column width in pixels */\r\n width?: number;\r\n /** Text alignment */\r\n align?: 'left' | 'center' | 'right';\r\n /** Enable text truncation with ellipsis */\r\n truncate?: boolean;\r\n}\r\n\r\ninterface DateOptions {\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Enable sorting for this column */\r\n sortable?: boolean;\r\n /** Optional date formatter function */\r\n format?: (value: Date | string | number) => string;\r\n /** Column width in pixels */\r\n width?: number;\r\n /** Text alignment */\r\n align?: 'left' | 'center' | 'right';\r\n /** Enable text truncation with ellipsis */\r\n truncate?: boolean;\r\n}\r\n\r\ninterface BooleanOptions {\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Enable sorting for this column */\r\n sortable?: boolean;\r\n /** Optional boolean formatter function */\r\n format?: (value: boolean) => string;\r\n /** Column width in pixels */\r\n width?: number;\r\n /** Text alignment */\r\n align?: 'left' | 'center' | 'right';\r\n /** Enable text truncation with ellipsis */\r\n truncate?: boolean;\r\n}\r\n\r\ninterface BadgeOptions {\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Enable sorting for this column */\r\n sortable?: boolean;\r\n /** Value-to-badge mapping */\r\n map?: Record<string, { label: string; tone: BadgeTone }>;\r\n /** Column width in pixels */\r\n width?: number;\r\n /** Text alignment */\r\n align?: 'left' | 'center' | 'right';\r\n /** Enable text truncation with ellipsis */\r\n truncate?: boolean;\r\n}\r\n\r\ninterface NumberOptions<T = unknown> {\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Enable sorting for this column */\r\n sortable?: boolean;\r\n /** Formatting options: Intl.NumberFormatOptions or custom formatter */\r\n format?: Intl.NumberFormatOptions | ((value: number, row: T) => string);\r\n /** Column width in pixels */\r\n width?: number;\r\n /** Text alignment */\r\n align?: 'left' | 'center' | 'right';\r\n /** Enable text truncation with ellipsis */\r\n truncate?: boolean;\r\n}\r\n\r\n// ============================================================================\r\n// COLUMN HELPER FUNCTIONS\r\n// ============================================================================\r\n\r\n/**\r\n * Create a text column definition.\r\n *\r\n * @example\r\n * ```ts\r\n * col.text('name')\r\n * col.text('email', { header: 'Email Address', sortable: true })\r\n * col.text('status', { format: (val) => val.toUpperCase() })\r\n * ```\r\n */\r\nfunction text<T>(\r\n field: keyof T & string,\r\n options?: TextOptions\r\n): TextColumnDef<T> {\r\n return {\r\n id: field,\r\n kind: 'text',\r\n field,\r\n header: options?.header,\r\n sortable: options?.sortable ?? false,\r\n format: options?.format,\r\n width: options?.width,\r\n align: options?.align,\r\n truncate: options?.truncate,\r\n };\r\n}\r\n\r\n/**\r\n * Create a date column definition.\r\n *\r\n * @example\r\n * ```ts\r\n * col.date('createdAt')\r\n * col.date('updatedAt', { header: 'Last Modified', sortable: true })\r\n * col.date('birthday', {\r\n * format: (date) => new Date(date).toLocaleDateString()\r\n * })\r\n * ```\r\n */\r\nfunction date<T>(\r\n field: keyof T & string,\r\n options?: DateOptions\r\n): DateColumnDef<T> {\r\n return {\r\n id: field,\r\n kind: 'date',\r\n field,\r\n header: options?.header,\r\n sortable: options?.sortable ?? false,\r\n format: options?.format,\r\n width: options?.width,\r\n align: options?.align,\r\n truncate: options?.truncate,\r\n };\r\n}\r\n\r\n/**\r\n * Create a boolean column definition.\r\n *\r\n * @example\r\n * ```ts\r\n * col.boolean('active')\r\n * col.boolean('isPublished', { header: 'Published', sortable: true })\r\n * col.boolean('enabled', {\r\n * format: (val) => val ? 'Yes' : 'No'\r\n * })\r\n * ```\r\n */\r\nfunction boolean<T>(\r\n field: keyof T & string,\r\n options?: BooleanOptions\r\n): BooleanColumnDef<T> {\r\n return {\r\n id: field,\r\n kind: 'boolean',\r\n field,\r\n header: options?.header,\r\n sortable: options?.sortable ?? false,\r\n format: options?.format,\r\n width: options?.width,\r\n align: options?.align,\r\n truncate: options?.truncate,\r\n };\r\n}\r\n\r\n/**\r\n * Create a badge column definition for status/enum fields.\r\n *\r\n * @example\r\n * ```ts\r\n * col.badge('status')\r\n * col.badge('status', {\r\n * map: {\r\n * active: { label: 'Active', tone: 'success' },\r\n * paused: { label: 'Paused', tone: 'warning' },\r\n * disabled: { label: 'Disabled', tone: 'danger' }\r\n * }\r\n * })\r\n * ```\r\n */\r\nfunction badge<T>(\r\n field: keyof T & string,\r\n options?: BadgeOptions\r\n): BadgeColumnDef<T> {\r\n return {\r\n id: field,\r\n kind: 'badge',\r\n field,\r\n header: options?.header,\r\n sortable: options?.sortable ?? false,\r\n map: options?.map,\r\n width: options?.width,\r\n align: options?.align,\r\n truncate: options?.truncate,\r\n };\r\n}\r\n\r\n/**\r\n * Create a number column definition.\r\n *\r\n * @example\r\n * ```ts\r\n * col.number('amount')\r\n * col.number('price', {\r\n * format: { style: 'currency', currency: 'USD' }\r\n * })\r\n * col.number('count', {\r\n * format: (val, row) => `${val} items`\r\n * })\r\n * ```\r\n */\r\nfunction number<T>(\r\n field: keyof T & string,\r\n options?: NumberOptions<T>\r\n): NumberColumnDef<T> {\r\n return {\r\n id: field,\r\n kind: 'number',\r\n field,\r\n header: options?.header,\r\n sortable: options?.sortable ?? false,\r\n format: options?.format,\r\n width: options?.width,\r\n align: options?.align,\r\n truncate: options?.truncate,\r\n };\r\n}\r\n\r\n/**\r\n * Create an actions column definition.\r\n *\r\n * The actions column displays a set of actions (buttons/links) that can be\r\n * performed on each row.\r\n *\r\n * @example\r\n * ```ts\r\n * col.actions([\r\n * { id: 'edit', label: 'Edit', onClick: (row) => editUser(row) },\r\n * { id: 'delete', label: 'Delete', confirm: true, onClick: (row) => deleteUser(row) }\r\n * ])\r\n * ```\r\n */\r\nfunction actions<T>(actions: ActionDef<T>[]): ActionsColumnDef<T> {\r\n return {\r\n id: 'actions',\r\n kind: 'actions',\r\n actions,\r\n };\r\n}\r\n\r\n/**\r\n * Create a custom column definition with full rendering control.\r\n *\r\n * This is the escape hatch for any column that doesn't fit the standard types.\r\n * Use this for badges, avatars, complex formatting, or any custom UI.\r\n *\r\n * @example\r\n * ```ts\r\n * col.custom({\r\n * id: 'avatar',\r\n * header: 'User',\r\n * render: (row) => <img src={row.avatar} alt={row.name} />\r\n * })\r\n *\r\n * col.custom({\r\n * id: 'price',\r\n * field: 'price',\r\n * render: (row) => <Money amount={row.price} currency={row.currency} />\r\n * })\r\n *\r\n * col.custom({\r\n * id: 'status',\r\n * render: (row) => (\r\n * <Badge color={row.status === 'active' ? 'green' : 'gray'}>\r\n * {row.status}\r\n * </Badge>\r\n * )\r\n * })\r\n * ```\r\n */\r\nfunction custom<T>(\r\n field: keyof T & string,\r\n render: (row: T) => ReactNode\r\n): CustomColumnDef<T>;\r\nfunction custom<T>(options: {\r\n /** Unique column identifier */\r\n id: string;\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Optional field name for sorting/filtering */\r\n field?: keyof T & string;\r\n /** Render function for cell content */\r\n render: (row: T) => ReactNode;\r\n}): CustomColumnDef<T>;\r\nfunction custom<T>(\r\n arg1:\r\n | (keyof T & string)\r\n | {\r\n id: string;\r\n header?: string;\r\n field?: keyof T & string;\r\n render: (row: T) => ReactNode;\r\n },\r\n arg2?: (row: T) => ReactNode\r\n): CustomColumnDef<T> {\r\n if (typeof arg1 === 'string') {\r\n if (typeof arg2 !== 'function') {\r\n throw new Error('col.custom(field, render): render must be a function');\r\n }\r\n\r\n return {\r\n id: arg1,\r\n kind: 'custom',\r\n field: arg1,\r\n render: arg2,\r\n };\r\n }\r\n\r\n return {\r\n id: arg1.id,\r\n kind: 'custom',\r\n header: arg1.header,\r\n field: arg1.field,\r\n render: arg1.render,\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// EXPORTS\r\n// ============================================================================\r\n\r\n/**\r\n * Column helper factory object.\r\n *\r\n * Provides convenient helper functions for creating column definitions.\r\n *\r\n * @example\r\n * ```tsx\r\n * import { col } from '@rowakit/table';\r\n *\r\n * const columns = [\r\n * col.text('name', { sortable: true }),\r\n * col.date('createdAt'),\r\n * col.boolean('active'),\r\n * col.actions([\r\n * { id: 'edit', label: 'Edit', onClick: (row) => {} }\r\n * ]),\r\n * col.custom({ id: 'badge', render: (row) => <Badge>{row.status}</Badge> })\r\n * ];\r\n * ```\r\n */\r\nexport const col = {\r\n text,\r\n date,\r\n boolean,\r\n badge,\r\n number,\r\n actions,\r\n custom,\r\n} as const;\r\n","/**\r\n * RowaKit Table Component\r\n *\r\n * Core table rendering component that maps columns to table cells.\r\n * Handles all column types: text, date, boolean, actions, and custom.\r\n * Includes data fetching state machine with loading/error/empty states.\r\n *\r\n * @packageDocumentation\r\n */\r\n\r\nimport { useState, useEffect, useRef } from 'react';\r\nimport type { ReactNode } from 'react';\r\nimport type { Fetcher, ColumnDef, FetcherQuery, ActionDef, FilterValue } from '../types';\r\n\r\n// ============================================================================\r\n// COMPONENT PROPS\r\n// ============================================================================\r\n\r\nexport interface SmartTableProps<T> {\r\n /** Server-side data fetcher function */\r\n fetcher: Fetcher<T>;\r\n\r\n /** Array of column definitions */\r\n columns: ColumnDef<T>[];\r\n\r\n /** Available page size options (default: [10, 20, 50]) */\r\n pageSizeOptions?: number[];\r\n\r\n /** Initial page size (default: 20) */\r\n defaultPageSize?: number;\r\n\r\n /** Function or field name to extract row key (default: uses 'id' field) */\r\n rowKey?: keyof T | ((row: T) => string | number);\r\n\r\n /** Optional CSS class name for the table container */\r\n className?: string;\r\n\r\n /** Enable filters (default: false) */\r\n enableFilters?: boolean;\r\n}\r\n\r\n// ============================================================================\r\n// STATE MANAGEMENT\r\n// ============================================================================\r\n\r\ntype FetchState = 'idle' | 'loading' | 'success' | 'empty' | 'error';\r\n\r\ninterface DataState<T> {\r\n state: FetchState;\r\n items: T[];\r\n total: number;\r\n error?: string;\r\n}\r\n\r\n/**\r\n * Confirmation state for actions that require confirmation.\r\n */\r\ninterface ConfirmState<T> {\r\n action: ActionDef<T>;\r\n row: T;\r\n}\r\n\r\n// ============================================================================\r\n// HELPER FUNCTIONS\r\n// ============================================================================\r\n\r\n/**\r\n * Extract unique key from a row.\r\n */\r\nfunction getRowKey<T>(row: T, rowKey?: keyof T | ((row: T) => string | number)): string | number {\r\n if (typeof rowKey === 'function') {\r\n return rowKey(row);\r\n }\r\n if (rowKey) {\r\n return String(row[rowKey]);\r\n }\r\n // Fallback to 'id' field if available\r\n if (row && typeof row === 'object' && 'id' in row) {\r\n return String(row.id);\r\n }\r\n // Last resort: use object reference (not ideal but safe)\r\n return String(row);\r\n}\r\n\r\n/**\r\n * Get header label for a column.\r\n */\r\nfunction getHeaderLabel<T>(column: ColumnDef<T>): string {\r\n return column.header ?? column.id;\r\n}\r\n\r\n/**\r\n * Render cell content based on column kind.\r\n */\r\nfunction renderCell<T>(\r\n column: ColumnDef<T>,\r\n row: T,\r\n isLoading: boolean,\r\n setConfirmState: (state: ConfirmState<T> | null) => void\r\n): ReactNode {\r\n switch (column.kind) {\r\n case 'text': {\r\n const value = row[column.field];\r\n if (column.format) {\r\n return column.format(value);\r\n }\r\n return String(value ?? '');\r\n }\r\n\r\n case 'date': {\r\n const value = row[column.field];\r\n if (column.format) {\r\n return column.format(value as Date | string | number);\r\n }\r\n // Default date formatting\r\n if (value instanceof Date) {\r\n return value.toLocaleDateString();\r\n }\r\n if (typeof value === 'string' || typeof value === 'number') {\r\n return new Date(value).toLocaleDateString();\r\n }\r\n return '';\r\n }\r\n\r\n case 'boolean': {\r\n const value = row[column.field];\r\n if (column.format) {\r\n return column.format(Boolean(value));\r\n }\r\n // Default boolean formatting\r\n return value ? 'Yes' : 'No';\r\n }\r\n\r\n case 'badge': {\r\n const value = row[column.field];\r\n const valueStr = String(value ?? '');\r\n \r\n // Look up mapping\r\n const mapped = column.map?.[valueStr];\r\n const label = mapped?.label ?? valueStr;\r\n const tone = mapped?.tone ?? 'neutral';\r\n \r\n return (\r\n <span className={`rowakit-badge rowakit-badge-${tone}`}>\r\n {label}\r\n </span>\r\n );\r\n }\r\n\r\n case 'number': {\r\n const value = row[column.field];\r\n const numValue = Number(value ?? 0);\r\n \r\n if (column.format) {\r\n if (typeof column.format === 'function') {\r\n return column.format(numValue, row);\r\n }\r\n // Intl.NumberFormatOptions\r\n return new Intl.NumberFormat(undefined, column.format).format(numValue);\r\n }\r\n \r\n // Default number formatting\r\n return numValue.toLocaleString();\r\n }\r\n\r\n case 'actions': {\r\n return (\r\n <div className=\"rowakit-table-actions\">\r\n {column.actions.map((action) => {\r\n const isDisabled =\r\n isLoading ||\r\n action.disabled === true ||\r\n (typeof action.disabled === 'function' && action.disabled(row));\r\n\r\n const handleClick = () => {\r\n if (isDisabled || action.loading) {\r\n return;\r\n }\r\n\r\n // If action requires confirmation, show modal\r\n if (action.confirm) {\r\n setConfirmState({ action, row });\r\n } else {\r\n // Execute action directly\r\n void action.onClick(row);\r\n }\r\n };\r\n\r\n return (\r\n <button\r\n key={action.id}\r\n onClick={handleClick}\r\n disabled={isDisabled || action.loading}\r\n type=\"button\"\r\n className=\"rowakit-button rowakit-button-secondary\"\r\n >\r\n {action.icon && typeof action.icon === 'string' ? (\r\n <span>{action.icon}</span>\r\n ) : (\r\n action.icon\r\n )}\r\n {action.label}\r\n </button>\r\n );\r\n })}\r\n </div>\r\n );\r\n }\r\n\r\n case 'custom': {\r\n return column.render(row);\r\n }\r\n\r\n default: {\r\n // Exhaustive check\r\n const _exhaustive: never = column;\r\n return _exhaustive;\r\n }\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// MAIN COMPONENT\r\n// ============================================================================\r\n\r\n/**\r\n * RowaKitTable - Server-side table component for internal/business apps.\r\n *\r\n * This component renders a table with headers and body based on column definitions.\r\n * It handles all column types (text, date, boolean, actions, custom) and provides\r\n * a clean API for defining table structure.\r\n *\r\n * Features:\r\n * - Automatic data fetching on mount and query changes\r\n * - Loading, error, and empty states\r\n * - Stale request handling\r\n * - Retry on error\r\n *\r\n * @example\r\n * ```tsx\r\n * import { RowaKitTable, col } from '@rowakit/table';\r\n *\r\n * interface User {\r\n * id: string;\r\n * name: string;\r\n * email: string;\r\n * createdAt: Date;\r\n * active: boolean;\r\n * }\r\n *\r\n * const fetchUsers: Fetcher<User> = async (query) => {\r\n * const response = await fetch(`/api/users?page=${query.page}&pageSize=${query.pageSize}`);\r\n * return response.json();\r\n * };\r\n *\r\n * function UsersTable() {\r\n * return (\r\n * <RowaKitTable\r\n * fetcher={fetchUsers}\r\n * columns={[\r\n * col.text('name', { header: 'Name', sortable: true }),\r\n * col.text('email', { header: 'Email' }),\r\n * col.date('createdAt', { header: 'Created' }),\r\n * col.boolean('active', { header: 'Active' }),\r\n * col.actions([\r\n * { id: 'edit', label: 'Edit', onClick: (user) => editUser(user) },\r\n * { id: 'delete', label: 'Delete', confirm: true, onClick: (user) => deleteUser(user) }\r\n * ])\r\n * ]}\r\n * defaultPageSize={20}\r\n * rowKey=\"id\"\r\n * />\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport function RowaKitTable<T>({\r\n fetcher,\r\n columns,\r\n defaultPageSize = 20,\r\n pageSizeOptions = [10, 20, 50],\r\n rowKey,\r\n className = '',\r\n enableFilters = false,\r\n}: SmartTableProps<T>) {\r\n // State management\r\n const [dataState, setDataState] = useState<DataState<T>>({\r\n state: 'idle',\r\n items: [],\r\n total: 0,\r\n });\r\n\r\n const [query, setQuery] = useState<FetcherQuery>({\r\n page: 1,\r\n pageSize: defaultPageSize,\r\n });\r\n\r\n // Filter state (field -> FilterValue)\r\n const [filters, setFilters] = useState<Record<string, FilterValue | undefined>>({});\r\n\r\n // Confirmation state for actions that require confirmation\r\n const [confirmState, setConfirmState] = useState<ConfirmState<T> | null>(null);\r\n\r\n // Request tracking to ignore stale responses\r\n const requestIdRef = useRef(0);\r\n\r\n // Sync filters to query (and reset page to 1 when filters change)\r\n useEffect(() => {\r\n if (!enableFilters) return;\r\n\r\n // Build filters object, excluding undefined values\r\n const activeFilters: Record<string, FilterValue> = {};\r\n let hasFilters = false;\r\n \r\n for (const [field, value] of Object.entries(filters)) {\r\n if (value !== undefined) {\r\n activeFilters[field] = value;\r\n hasFilters = true;\r\n }\r\n }\r\n\r\n // Per spec: filters must be undefined when empty (not {})\r\n const filtersToSend = hasFilters ? activeFilters : undefined;\r\n\r\n setQuery((prev) => ({\r\n ...prev,\r\n filters: filtersToSend,\r\n page: 1, // Reset page to 1 when filters change\r\n }));\r\n }, [filters, enableFilters]);\r\n\r\n // Fetch data effect\r\n useEffect(() => {\r\n const currentRequestId = ++requestIdRef.current;\r\n\r\n setDataState((prev) => ({ ...prev, state: 'loading' }));\r\n\r\n fetcher(query)\r\n .then((result) => {\r\n // Ignore stale responses\r\n if (currentRequestId !== requestIdRef.current) {\r\n return;\r\n }\r\n\r\n if (result.items.length === 0) {\r\n setDataState({\r\n state: 'empty',\r\n items: [],\r\n total: result.total,\r\n });\r\n } else {\r\n setDataState({\r\n state: 'success',\r\n items: result.items,\r\n total: result.total,\r\n });\r\n }\r\n })\r\n .catch((error: unknown) => {\r\n // Ignore stale responses\r\n if (currentRequestId !== requestIdRef.current) {\r\n return;\r\n }\r\n\r\n setDataState({\r\n state: 'error',\r\n items: [],\r\n total: 0,\r\n error: error instanceof Error ? error.message : 'Failed to load data',\r\n });\r\n });\r\n }, [fetcher, query]);\r\n\r\n // Retry handler\r\n const handleRetry = () => {\r\n // Force re-fetch by updating query reference\r\n setQuery({ ...query });\r\n };\r\n\r\n // Pagination handlers\r\n const handlePreviousPage = () => {\r\n if (query.page > 1) {\r\n setQuery((prev) => ({ ...prev, page: prev.page - 1 }));\r\n }\r\n };\r\n\r\n const handleNextPage = () => {\r\n const totalPages = Math.ceil(dataState.total / query.pageSize);\r\n if (query.page < totalPages) {\r\n setQuery((prev) => ({ ...prev, page: prev.page + 1 }));\r\n }\r\n };\r\n\r\n const handlePageSizeChange = (newPageSize: number) => {\r\n setQuery({ ...query, pageSize: newPageSize, page: 1 });\r\n };\r\n\r\n // Sorting handler\r\n const handleSort = (field: string) => {\r\n setQuery((prev) => {\r\n // If sorting by a different field, start with ascending\r\n if (prev.sort?.field !== field) {\r\n return { ...prev, sort: { field, direction: 'asc' }, page: 1 };\r\n }\r\n\r\n // Toggle sort direction for the same field\r\n if (prev.sort.direction === 'asc') {\r\n return { ...prev, sort: { field, direction: 'desc' }, page: 1 };\r\n }\r\n\r\n // Remove sort (back to unsorted)\r\n const { sort: _sort, ...rest } = prev;\r\n return { ...rest, page: 1 };\r\n });\r\n };\r\n\r\n // Get sort indicator for a column\r\n const getSortIndicator = (field: string): string => {\r\n if (!query.sort || query.sort.field !== field) {\r\n return '';\r\n }\r\n return query.sort.direction === 'asc' ? ' ↑' : ' ↓';\r\n };\r\n\r\n // Filter handlers\r\n const handleFilterChange = (field: string, value: FilterValue | undefined) => {\r\n setFilters((prev) => ({\r\n ...prev,\r\n [field]: value,\r\n }));\r\n };\r\n\r\n const handleClearFilter = (field: string) => {\r\n setFilters((prev) => {\r\n const newFilters = { ...prev };\r\n delete newFilters[field];\r\n return newFilters;\r\n });\r\n };\r\n\r\n const handleClearAllFilters = () => {\r\n setFilters({});\r\n };\r\n\r\n const isLoading = dataState.state === 'loading';\r\n const isError = dataState.state === 'error';\r\n const isEmpty = dataState.state === 'empty';\r\n const totalPages = Math.ceil(dataState.total / query.pageSize);\r\n const canGoPrevious = query.page > 1 && !isLoading;\r\n const canGoNext = query.page < totalPages && !isLoading;\r\n\r\n const hasActiveFilters = enableFilters && Object.values(filters).some(v => v !== undefined);\r\n\r\n return (\r\n <div className={`rowakit-table${className ? ` ${className}` : ''}`}>\r\n {hasActiveFilters && (\r\n <div className=\"rowakit-table-filter-controls\">\r\n <button\r\n onClick={handleClearAllFilters}\r\n className=\"rowakit-button rowakit-button-secondary\"\r\n type=\"button\"\r\n >\r\n Clear all filters\r\n </button>\r\n </div>\r\n )}\r\n <table>\r\n <thead>\r\n <tr>\r\n {columns.map((column) => {\r\n const isSortable = column.kind !== 'actions' && \r\n (column.kind === 'custom' ? false : column.sortable === true);\r\n const field = column.kind === 'actions' ? '' : \r\n column.kind === 'custom' ? column.field : \r\n column.field;\r\n\r\n return (\r\n <th\r\n key={column.id}\r\n onClick={isSortable ? () => handleSort(String(field)) : undefined}\r\n role={isSortable ? 'button' : undefined}\r\n tabIndex={isSortable ? 0 : undefined}\r\n onKeyDown={isSortable ? (e) => {\r\n if (e.key === 'Enter' || e.key === ' ') {\r\n e.preventDefault();\r\n handleSort(String(field));\r\n }\r\n } : undefined}\r\n aria-sort={\r\n isSortable && query.sort?.field === String(field)\r\n ? query.sort.direction === 'asc' ? 'ascending' : 'descending'\r\n : undefined\r\n }\r\n style={{\r\n width: column.width ? `${column.width}px` : undefined,\r\n textAlign: column.align,\r\n }}\r\n className={column.truncate ? 'rowakit-cell-truncate' : undefined}\r\n >\r\n {getHeaderLabel(column)}{isSortable && getSortIndicator(String(field))}\r\n </th>\r\n );\r\n })}\r\n </tr>\r\n {enableFilters && (\r\n <tr className=\"rowakit-table-filter-row\">\r\n {columns.map((column) => {\r\n const field = column.kind === 'actions' || column.kind === 'custom' ? '' : String(column.field);\r\n const canFilter = field && column.kind !== 'actions';\r\n \r\n if (!canFilter) {\r\n return <th key={column.id}></th>;\r\n }\r\n\r\n const filterValue = filters[field];\r\n\r\n // Badge column: select with options\r\n if (column.kind === 'badge') {\r\n const options = column.map ? Object.keys(column.map) : [];\r\n return (\r\n <th key={column.id}>\r\n <select\r\n className=\"rowakit-filter-select\"\r\n value={filterValue?.op === 'equals' ? String(filterValue.value ?? '') : ''}\r\n onChange={(e) => {\r\n const value = e.target.value;\r\n if (value === '') {\r\n handleClearFilter(field);\r\n } else {\r\n handleFilterChange(field, { op: 'equals', value });\r\n }\r\n }}\r\n >\r\n <option value=\"\">All</option>\r\n {options.map((opt) => (\r\n <option key={opt} value={opt}>\r\n {opt}\r\n </option>\r\n ))}\r\n </select>\r\n </th>\r\n );\r\n }\r\n\r\n // Boolean column: select with True/False/All\r\n if (column.kind === 'boolean') {\r\n return (\r\n <th key={column.id}>\r\n <select\r\n className=\"rowakit-filter-select\"\r\n value={\r\n filterValue?.op === 'equals' && typeof filterValue.value === 'boolean'\r\n ? String(filterValue.value)\r\n : ''\r\n }\r\n onChange={(e) => {\r\n const value = e.target.value;\r\n if (value === '') {\r\n handleClearFilter(field);\r\n } else {\r\n handleFilterChange(field, { op: 'equals', value: value === 'true' });\r\n }\r\n }}\r\n >\r\n <option value=\"\">All</option>\r\n <option value=\"true\">True</option>\r\n <option value=\"false\">False</option>\r\n </select>\r\n </th>\r\n );\r\n }\r\n\r\n // Date column: from/to inputs\r\n if (column.kind === 'date') {\r\n const fromValue = filterValue?.op === 'range' ? filterValue.value.from ?? '' : '';\r\n const toValue = filterValue?.op === 'range' ? filterValue.value.to ?? '' : '';\r\n \r\n return (\r\n <th key={column.id}>\r\n <div className=\"rowakit-filter-date-range\">\r\n <input\r\n type=\"date\"\r\n className=\"rowakit-filter-input\"\r\n placeholder=\"From\"\r\n value={fromValue}\r\n onChange={(e) => {\r\n const from = e.target.value || undefined;\r\n const to = toValue || undefined;\r\n if (!from && !to) {\r\n handleClearFilter(field);\r\n } else {\r\n handleFilterChange(field, { op: 'range', value: { from, to } });\r\n }\r\n }}\r\n />\r\n <input\r\n type=\"date\"\r\n className=\"rowakit-filter-input\"\r\n placeholder=\"To\"\r\n value={toValue}\r\n onChange={(e) => {\r\n const to = e.target.value || undefined;\r\n const from = fromValue || undefined;\r\n if (!from && !to) {\r\n handleClearFilter(field);\r\n } else {\r\n handleFilterChange(field, { op: 'range', value: { from, to } });\r\n }\r\n }}\r\n />\r\n </div>\r\n </th>\r\n );\r\n }\r\n\r\n // Text/Number column: text or number input\r\n const isNumberColumn = column.kind === 'number';\r\n return (\r\n <th key={column.id}>\r\n <input\r\n type={isNumberColumn ? 'number' : 'text'}\r\n className=\"rowakit-filter-input\"\r\n placeholder={`Filter ${getHeaderLabel(column)}...`}\r\n value={\r\n filterValue?.op === 'contains'\r\n ? filterValue.value\r\n : filterValue?.op === 'equals' && typeof filterValue.value === 'string'\r\n ? filterValue.value\r\n : filterValue?.op === 'equals' && typeof filterValue.value === 'number'\r\n ? String(filterValue.value)\r\n : ''\r\n }\r\n onChange={(e) => {\r\n const rawValue = e.target.value;\r\n if (rawValue === '') {\r\n handleClearFilter(field);\r\n } else if (isNumberColumn) {\r\n const numValue = Number(rawValue);\r\n if (!isNaN(numValue)) {\r\n handleFilterChange(field, { op: 'equals', value: rawValue } as FilterValue);\r\n } else {\r\n // Invalid numeric input: clear the filter to avoid confusing UX\r\n handleClearFilter(field);\r\n }\r\n } else {\r\n // Text: use \"contains\"\r\n handleFilterChange(field, { op: 'contains', value: rawValue } as FilterValue);\r\n }\r\n }}\r\n />\r\n </th>\r\n );\r\n })}\r\n </tr>\r\n )}\r\n </thead>\r\n <tbody>\r\n {isLoading && (\r\n <tr>\r\n <td colSpan={columns.length} className=\"rowakit-table-loading\">\r\n <div className=\"rowakit-table-loading-spinner\"></div>\r\n <span>Loading...</span>\r\n </td>\r\n </tr>\r\n )}\r\n\r\n {isError && (\r\n <tr>\r\n <td colSpan={columns.length} className=\"rowakit-table-error\">\r\n <div className=\"rowakit-table-error-message\">\r\n {dataState.error ?? 'An error occurred'}\r\n </div>\r\n <button\r\n onClick={handleRetry}\r\n className=\"rowakit-button rowakit-button-primary\"\r\n type=\"button\"\r\n >\r\n Retry\r\n </button>\r\n </td>\r\n </tr>\r\n )}\r\n\r\n {isEmpty && (\r\n <tr>\r\n <td colSpan={columns.length} className=\"rowakit-table-empty\">\r\n No data\r\n </td>\r\n </tr>\r\n )}\r\n\r\n {dataState.state === 'success' &&\r\n dataState.items.map((row) => {\r\n const key = getRowKey(row, rowKey);\r\n return (\r\n <tr key={key}>\r\n {columns.map((column) => {\r\n const cellClass = [\r\n column.kind === 'number' ? 'rowakit-cell-number' : '',\r\n column.truncate ? 'rowakit-cell-truncate' : '',\r\n ].filter(Boolean).join(' ') || undefined;\r\n \r\n return (\r\n <td \r\n key={column.id}\r\n className={cellClass}\r\n style={{\r\n width: column.width ? `${column.width}px` : undefined,\r\n textAlign: column.align || (column.kind === 'number' ? 'right' : undefined),\r\n }}\r\n >\r\n {renderCell(column, row, isLoading, setConfirmState)}\r\n </td>\r\n );\r\n })}\r\n </tr>\r\n );\r\n })}\r\n </tbody>\r\n </table>\r\n\r\n {/* Pagination Controls */}\r\n {dataState.total > 0 && (\r\n <div className=\"rowakit-table-pagination\">\r\n {/* Left: Page size selector */}\r\n <div className=\"rowakit-table-pagination-left\">\r\n <label htmlFor=\"page-size\">\r\n Rows per page:\r\n </label>\r\n <select\r\n id=\"page-size\"\r\n value={query.pageSize}\r\n onChange={(e) => handlePageSizeChange(Number(e.target.value))}\r\n disabled={isLoading}\r\n >\r\n {pageSizeOptions.map((size) => (\r\n <option key={size} value={size}>\r\n {size}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n\r\n {/* Center: Page info */}\r\n <div className=\"rowakit-table-pagination-center\">\r\n Page {query.page} of {totalPages} ({dataState.total} total)\r\n </div>\r\n\r\n {/* Right: Previous/Next buttons */}\r\n <div className=\"rowakit-table-pagination-right\">\r\n <button\r\n onClick={handlePreviousPage}\r\n disabled={!canGoPrevious}\r\n className=\"rowakit-button rowakit-button-primary rowakit-button-pagination\"\r\n type=\"button\"\r\n aria-label=\"Previous page\"\r\n >\r\n Previous\r\n </button>\r\n <button\r\n onClick={handleNextPage}\r\n disabled={!canGoNext}\r\n className=\"rowakit-button rowakit-button-primary rowakit-button-pagination\"\r\n type=\"button\"\r\n aria-label=\"Next page\"\r\n >\r\n Next\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Confirmation Modal */}\r\n {confirmState && (\r\n <div\r\n className=\"rowakit-modal-backdrop\"\r\n onClick={() => setConfirmState(null)}\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n aria-labelledby=\"confirm-dialog-title\"\r\n >\r\n <div className=\"rowakit-modal\" onClick={(e) => e.stopPropagation()}>\r\n <h2 id=\"confirm-dialog-title\" className=\"rowakit-modal-title\">\r\n Confirm Action\r\n </h2>\r\n <p className=\"rowakit-modal-content\">\r\n Are you sure you want to {confirmState.action.label.toLowerCase()}? This action cannot be\r\n undone.\r\n </p>\r\n <div className=\"rowakit-modal-actions\">\r\n <button\r\n onClick={() => setConfirmState(null)}\r\n className=\"rowakit-button rowakit-button-secondary\"\r\n type=\"button\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n onClick={() => {\r\n void confirmState.action.onClick(confirmState.row);\r\n setConfirmState(null);\r\n }}\r\n className=\"rowakit-button rowakit-button-danger\"\r\n type=\"button\"\r\n >\r\n Confirm\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n/**\r\n * @deprecated Use RowaKitTable instead. SmartTable is kept as an alias for backward compatibility.\r\n */\r\nexport const SmartTable = RowaKitTable;\r\n","/**\r\n * @rowakit/table\r\n *\r\n * Opinionated, server-side-first table component for internal/business apps.\r\n *\r\n * @packageDocumentation\r\n */\r\n\r\n// Core types\r\nexport type {\r\n // Fetcher types\r\n Fetcher,\r\n FetcherQuery,\r\n FetcherResult,\r\n FilterValue,\r\n Filters,\r\n // Column types\r\n ColumnDef,\r\n ColumnKind,\r\n BaseColumnDef,\r\n TextColumnDef,\r\n DateColumnDef,\r\n BooleanColumnDef,\r\n BadgeColumnDef,\r\n NumberColumnDef,\r\n ActionsColumnDef,\r\n CustomColumnDef,\r\n BadgeTone,\r\n // Action types\r\n ActionDef,\r\n} from './types';\r\n\r\n// Column helper factory\r\nexport { col } from './column-helpers';\r\n\r\n// Components\r\nexport { RowaKitTable, SmartTable } from './components/SmartTable';\r\nexport type { SmartTableProps } from './components/SmartTable';\r\n\r\nexport const VERSION = '0.1.0';\r\n"]}
package/dist/index.js CHANGED
@@ -482,7 +482,7 @@ function RowaKitTable({
482
482
  } else if (isNumberColumn) {
483
483
  const numValue = Number(rawValue);
484
484
  if (!isNaN(numValue)) {
485
- handleFilterChange(field, { op: "equals", value: numValue });
485
+ handleFilterChange(field, { op: "equals", value: rawValue });
486
486
  } else {
487
487
  handleClearFilter(field);
488
488
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/column-helpers.ts","../src/components/SmartTable.tsx","../src/index.ts"],"names":["actions","totalPages"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Column helper factory functions\r\n *\r\n * These helpers provide a clean, type-safe API for defining table columns.\r\n * They reduce boilerplate and enforce conventions while maintaining flexibility\r\n * through the `col.custom` escape hatch.\r\n *\r\n * @packageDocumentation\r\n */\r\n\r\nimport type { ReactNode } from 'react';\r\nimport type {\r\n TextColumnDef,\r\n DateColumnDef,\r\n BooleanColumnDef,\r\n BadgeColumnDef,\r\n NumberColumnDef,\r\n ActionsColumnDef,\r\n CustomColumnDef,\r\n ActionDef,\r\n BadgeTone,\r\n} from './types';\r\n\r\n// ============================================================================\r\n// HELPER OPTIONS\r\n// ============================================================================\r\n\r\ninterface TextOptions {\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Enable sorting for this column */\r\n sortable?: boolean;\r\n /** Optional formatter function */\r\n format?: (value: unknown) => string;\r\n /** Column width in pixels */\r\n width?: number;\r\n /** Text alignment */\r\n align?: 'left' | 'center' | 'right';\r\n /** Enable text truncation with ellipsis */\r\n truncate?: boolean;\r\n}\r\n\r\ninterface DateOptions {\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Enable sorting for this column */\r\n sortable?: boolean;\r\n /** Optional date formatter function */\r\n format?: (value: Date | string | number) => string;\r\n /** Column width in pixels */\r\n width?: number;\r\n /** Text alignment */\r\n align?: 'left' | 'center' | 'right';\r\n /** Enable text truncation with ellipsis */\r\n truncate?: boolean;\r\n}\r\n\r\ninterface BooleanOptions {\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Enable sorting for this column */\r\n sortable?: boolean;\r\n /** Optional boolean formatter function */\r\n format?: (value: boolean) => string;\r\n /** Column width in pixels */\r\n width?: number;\r\n /** Text alignment */\r\n align?: 'left' | 'center' | 'right';\r\n /** Enable text truncation with ellipsis */\r\n truncate?: boolean;\r\n}\r\n\r\ninterface BadgeOptions {\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Enable sorting for this column */\r\n sortable?: boolean;\r\n /** Value-to-badge mapping */\r\n map?: Record<string, { label: string; tone: BadgeTone }>;\r\n /** Column width in pixels */\r\n width?: number;\r\n /** Text alignment */\r\n align?: 'left' | 'center' | 'right';\r\n /** Enable text truncation with ellipsis */\r\n truncate?: boolean;\r\n}\r\n\r\ninterface NumberOptions<T = unknown> {\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Enable sorting for this column */\r\n sortable?: boolean;\r\n /** Formatting options: Intl.NumberFormatOptions or custom formatter */\r\n format?: Intl.NumberFormatOptions | ((value: number, row: T) => string);\r\n /** Column width in pixels */\r\n width?: number;\r\n /** Text alignment */\r\n align?: 'left' | 'center' | 'right';\r\n /** Enable text truncation with ellipsis */\r\n truncate?: boolean;\r\n}\r\n\r\n// ============================================================================\r\n// COLUMN HELPER FUNCTIONS\r\n// ============================================================================\r\n\r\n/**\r\n * Create a text column definition.\r\n *\r\n * @example\r\n * ```ts\r\n * col.text('name')\r\n * col.text('email', { header: 'Email Address', sortable: true })\r\n * col.text('status', { format: (val) => val.toUpperCase() })\r\n * ```\r\n */\r\nfunction text<T>(\r\n field: keyof T & string,\r\n options?: TextOptions\r\n): TextColumnDef<T> {\r\n return {\r\n id: field,\r\n kind: 'text',\r\n field,\r\n header: options?.header,\r\n sortable: options?.sortable ?? false,\r\n format: options?.format,\r\n width: options?.width,\r\n align: options?.align,\r\n truncate: options?.truncate,\r\n };\r\n}\r\n\r\n/**\r\n * Create a date column definition.\r\n *\r\n * @example\r\n * ```ts\r\n * col.date('createdAt')\r\n * col.date('updatedAt', { header: 'Last Modified', sortable: true })\r\n * col.date('birthday', {\r\n * format: (date) => new Date(date).toLocaleDateString()\r\n * })\r\n * ```\r\n */\r\nfunction date<T>(\r\n field: keyof T & string,\r\n options?: DateOptions\r\n): DateColumnDef<T> {\r\n return {\r\n id: field,\r\n kind: 'date',\r\n field,\r\n header: options?.header,\r\n sortable: options?.sortable ?? false,\r\n format: options?.format,\r\n width: options?.width,\r\n align: options?.align,\r\n truncate: options?.truncate,\r\n };\r\n}\r\n\r\n/**\r\n * Create a boolean column definition.\r\n *\r\n * @example\r\n * ```ts\r\n * col.boolean('active')\r\n * col.boolean('isPublished', { header: 'Published', sortable: true })\r\n * col.boolean('enabled', {\r\n * format: (val) => val ? 'Yes' : 'No'\r\n * })\r\n * ```\r\n */\r\nfunction boolean<T>(\r\n field: keyof T & string,\r\n options?: BooleanOptions\r\n): BooleanColumnDef<T> {\r\n return {\r\n id: field,\r\n kind: 'boolean',\r\n field,\r\n header: options?.header,\r\n sortable: options?.sortable ?? false,\r\n format: options?.format,\r\n width: options?.width,\r\n align: options?.align,\r\n truncate: options?.truncate,\r\n };\r\n}\r\n\r\n/**\r\n * Create a badge column definition for status/enum fields.\r\n *\r\n * @example\r\n * ```ts\r\n * col.badge('status')\r\n * col.badge('status', {\r\n * map: {\r\n * active: { label: 'Active', tone: 'success' },\r\n * paused: { label: 'Paused', tone: 'warning' },\r\n * disabled: { label: 'Disabled', tone: 'danger' }\r\n * }\r\n * })\r\n * ```\r\n */\r\nfunction badge<T>(\r\n field: keyof T & string,\r\n options?: BadgeOptions\r\n): BadgeColumnDef<T> {\r\n return {\r\n id: field,\r\n kind: 'badge',\r\n field,\r\n header: options?.header,\r\n sortable: options?.sortable ?? false,\r\n map: options?.map,\r\n width: options?.width,\r\n align: options?.align,\r\n truncate: options?.truncate,\r\n };\r\n}\r\n\r\n/**\r\n * Create a number column definition.\r\n *\r\n * @example\r\n * ```ts\r\n * col.number('amount')\r\n * col.number('price', {\r\n * format: { style: 'currency', currency: 'USD' }\r\n * })\r\n * col.number('count', {\r\n * format: (val, row) => `${val} items`\r\n * })\r\n * ```\r\n */\r\nfunction number<T>(\r\n field: keyof T & string,\r\n options?: NumberOptions<T>\r\n): NumberColumnDef<T> {\r\n return {\r\n id: field,\r\n kind: 'number',\r\n field,\r\n header: options?.header,\r\n sortable: options?.sortable ?? false,\r\n format: options?.format,\r\n width: options?.width,\r\n align: options?.align,\r\n truncate: options?.truncate,\r\n };\r\n}\r\n\r\n/**\r\n * Create an actions column definition.\r\n *\r\n * The actions column displays a set of actions (buttons/links) that can be\r\n * performed on each row.\r\n *\r\n * @example\r\n * ```ts\r\n * col.actions([\r\n * { id: 'edit', label: 'Edit', onClick: (row) => editUser(row) },\r\n * { id: 'delete', label: 'Delete', confirm: true, onClick: (row) => deleteUser(row) }\r\n * ])\r\n * ```\r\n */\r\nfunction actions<T>(actions: ActionDef<T>[]): ActionsColumnDef<T> {\r\n return {\r\n id: 'actions',\r\n kind: 'actions',\r\n actions,\r\n };\r\n}\r\n\r\n/**\r\n * Create a custom column definition with full rendering control.\r\n *\r\n * This is the escape hatch for any column that doesn't fit the standard types.\r\n * Use this for badges, avatars, complex formatting, or any custom UI.\r\n *\r\n * @example\r\n * ```ts\r\n * col.custom({\r\n * id: 'avatar',\r\n * header: 'User',\r\n * render: (row) => <img src={row.avatar} alt={row.name} />\r\n * })\r\n *\r\n * col.custom({\r\n * id: 'price',\r\n * field: 'price',\r\n * render: (row) => <Money amount={row.price} currency={row.currency} />\r\n * })\r\n *\r\n * col.custom({\r\n * id: 'status',\r\n * render: (row) => (\r\n * <Badge color={row.status === 'active' ? 'green' : 'gray'}>\r\n * {row.status}\r\n * </Badge>\r\n * )\r\n * })\r\n * ```\r\n */\r\nfunction custom<T>(\r\n field: keyof T & string,\r\n render: (row: T) => ReactNode\r\n): CustomColumnDef<T>;\r\nfunction custom<T>(options: {\r\n /** Unique column identifier */\r\n id: string;\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Optional field name for sorting/filtering */\r\n field?: keyof T & string;\r\n /** Render function for cell content */\r\n render: (row: T) => ReactNode;\r\n}): CustomColumnDef<T>;\r\nfunction custom<T>(\r\n arg1:\r\n | (keyof T & string)\r\n | {\r\n id: string;\r\n header?: string;\r\n field?: keyof T & string;\r\n render: (row: T) => ReactNode;\r\n },\r\n arg2?: (row: T) => ReactNode\r\n): CustomColumnDef<T> {\r\n if (typeof arg1 === 'string') {\r\n if (typeof arg2 !== 'function') {\r\n throw new Error('col.custom(field, render): render must be a function');\r\n }\r\n\r\n return {\r\n id: arg1,\r\n kind: 'custom',\r\n field: arg1,\r\n render: arg2,\r\n };\r\n }\r\n\r\n return {\r\n id: arg1.id,\r\n kind: 'custom',\r\n header: arg1.header,\r\n field: arg1.field,\r\n render: arg1.render,\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// EXPORTS\r\n// ============================================================================\r\n\r\n/**\r\n * Column helper factory object.\r\n *\r\n * Provides convenient helper functions for creating column definitions.\r\n *\r\n * @example\r\n * ```tsx\r\n * import { col } from '@rowakit/table';\r\n *\r\n * const columns = [\r\n * col.text('name', { sortable: true }),\r\n * col.date('createdAt'),\r\n * col.boolean('active'),\r\n * col.actions([\r\n * { id: 'edit', label: 'Edit', onClick: (row) => {} }\r\n * ]),\r\n * col.custom({ id: 'badge', render: (row) => <Badge>{row.status}</Badge> })\r\n * ];\r\n * ```\r\n */\r\nexport const col = {\r\n text,\r\n date,\r\n boolean,\r\n badge,\r\n number,\r\n actions,\r\n custom,\r\n} as const;\r\n","/**\r\n * RowaKit Table Component\r\n *\r\n * Core table rendering component that maps columns to table cells.\r\n * Handles all column types: text, date, boolean, actions, and custom.\r\n * Includes data fetching state machine with loading/error/empty states.\r\n *\r\n * @packageDocumentation\r\n */\r\n\r\nimport { useState, useEffect, useRef } from 'react';\r\nimport type { ReactNode } from 'react';\r\nimport type { Fetcher, ColumnDef, FetcherQuery, ActionDef, FilterValue } from '../types';\r\n\r\n// ============================================================================\r\n// COMPONENT PROPS\r\n// ============================================================================\r\n\r\nexport interface SmartTableProps<T> {\r\n /** Server-side data fetcher function */\r\n fetcher: Fetcher<T>;\r\n\r\n /** Array of column definitions */\r\n columns: ColumnDef<T>[];\r\n\r\n /** Available page size options (default: [10, 20, 50]) */\r\n pageSizeOptions?: number[];\r\n\r\n /** Initial page size (default: 20) */\r\n defaultPageSize?: number;\r\n\r\n /** Function or field name to extract row key (default: uses 'id' field) */\r\n rowKey?: keyof T | ((row: T) => string | number);\r\n\r\n /** Optional CSS class name for the table container */\r\n className?: string;\r\n\r\n /** Enable filters (default: false) */\r\n enableFilters?: boolean;\r\n}\r\n\r\n// ============================================================================\r\n// STATE MANAGEMENT\r\n// ============================================================================\r\n\r\ntype FetchState = 'idle' | 'loading' | 'success' | 'empty' | 'error';\r\n\r\ninterface DataState<T> {\r\n state: FetchState;\r\n items: T[];\r\n total: number;\r\n error?: string;\r\n}\r\n\r\n/**\r\n * Confirmation state for actions that require confirmation.\r\n */\r\ninterface ConfirmState<T> {\r\n action: ActionDef<T>;\r\n row: T;\r\n}\r\n\r\n// ============================================================================\r\n// HELPER FUNCTIONS\r\n// ============================================================================\r\n\r\n/**\r\n * Extract unique key from a row.\r\n */\r\nfunction getRowKey<T>(row: T, rowKey?: keyof T | ((row: T) => string | number)): string | number {\r\n if (typeof rowKey === 'function') {\r\n return rowKey(row);\r\n }\r\n if (rowKey) {\r\n return String(row[rowKey]);\r\n }\r\n // Fallback to 'id' field if available\r\n if (row && typeof row === 'object' && 'id' in row) {\r\n return String(row.id);\r\n }\r\n // Last resort: use object reference (not ideal but safe)\r\n return String(row);\r\n}\r\n\r\n/**\r\n * Get header label for a column.\r\n */\r\nfunction getHeaderLabel<T>(column: ColumnDef<T>): string {\r\n return column.header ?? column.id;\r\n}\r\n\r\n/**\r\n * Render cell content based on column kind.\r\n */\r\nfunction renderCell<T>(\r\n column: ColumnDef<T>,\r\n row: T,\r\n isLoading: boolean,\r\n setConfirmState: (state: ConfirmState<T> | null) => void\r\n): ReactNode {\r\n switch (column.kind) {\r\n case 'text': {\r\n const value = row[column.field];\r\n if (column.format) {\r\n return column.format(value);\r\n }\r\n return String(value ?? '');\r\n }\r\n\r\n case 'date': {\r\n const value = row[column.field];\r\n if (column.format) {\r\n return column.format(value as Date | string | number);\r\n }\r\n // Default date formatting\r\n if (value instanceof Date) {\r\n return value.toLocaleDateString();\r\n }\r\n if (typeof value === 'string' || typeof value === 'number') {\r\n return new Date(value).toLocaleDateString();\r\n }\r\n return '';\r\n }\r\n\r\n case 'boolean': {\r\n const value = row[column.field];\r\n if (column.format) {\r\n return column.format(Boolean(value));\r\n }\r\n // Default boolean formatting\r\n return value ? 'Yes' : 'No';\r\n }\r\n\r\n case 'badge': {\r\n const value = row[column.field];\r\n const valueStr = String(value ?? '');\r\n \r\n // Look up mapping\r\n const mapped = column.map?.[valueStr];\r\n const label = mapped?.label ?? valueStr;\r\n const tone = mapped?.tone ?? 'neutral';\r\n \r\n return (\r\n <span className={`rowakit-badge rowakit-badge-${tone}`}>\r\n {label}\r\n </span>\r\n );\r\n }\r\n\r\n case 'number': {\r\n const value = row[column.field];\r\n const numValue = Number(value ?? 0);\r\n \r\n if (column.format) {\r\n if (typeof column.format === 'function') {\r\n return column.format(numValue, row);\r\n }\r\n // Intl.NumberFormatOptions\r\n return new Intl.NumberFormat(undefined, column.format).format(numValue);\r\n }\r\n \r\n // Default number formatting\r\n return numValue.toLocaleString();\r\n }\r\n\r\n case 'actions': {\r\n return (\r\n <div className=\"rowakit-table-actions\">\r\n {column.actions.map((action) => {\r\n const isDisabled =\r\n isLoading ||\r\n action.disabled === true ||\r\n (typeof action.disabled === 'function' && action.disabled(row));\r\n\r\n const handleClick = () => {\r\n if (isDisabled || action.loading) {\r\n return;\r\n }\r\n\r\n // If action requires confirmation, show modal\r\n if (action.confirm) {\r\n setConfirmState({ action, row });\r\n } else {\r\n // Execute action directly\r\n void action.onClick(row);\r\n }\r\n };\r\n\r\n return (\r\n <button\r\n key={action.id}\r\n onClick={handleClick}\r\n disabled={isDisabled || action.loading}\r\n type=\"button\"\r\n className=\"rowakit-button rowakit-button-secondary\"\r\n >\r\n {action.icon && typeof action.icon === 'string' ? (\r\n <span>{action.icon}</span>\r\n ) : (\r\n action.icon\r\n )}\r\n {action.label}\r\n </button>\r\n );\r\n })}\r\n </div>\r\n );\r\n }\r\n\r\n case 'custom': {\r\n return column.render(row);\r\n }\r\n\r\n default: {\r\n // Exhaustive check\r\n const _exhaustive: never = column;\r\n return _exhaustive;\r\n }\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// MAIN COMPONENT\r\n// ============================================================================\r\n\r\n/**\r\n * RowaKitTable - Server-side table component for internal/business apps.\r\n *\r\n * This component renders a table with headers and body based on column definitions.\r\n * It handles all column types (text, date, boolean, actions, custom) and provides\r\n * a clean API for defining table structure.\r\n *\r\n * Features:\r\n * - Automatic data fetching on mount and query changes\r\n * - Loading, error, and empty states\r\n * - Stale request handling\r\n * - Retry on error\r\n *\r\n * @example\r\n * ```tsx\r\n * import { RowaKitTable, col } from '@rowakit/table';\r\n *\r\n * interface User {\r\n * id: string;\r\n * name: string;\r\n * email: string;\r\n * createdAt: Date;\r\n * active: boolean;\r\n * }\r\n *\r\n * const fetchUsers: Fetcher<User> = async (query) => {\r\n * const response = await fetch(`/api/users?page=${query.page}&pageSize=${query.pageSize}`);\r\n * return response.json();\r\n * };\r\n *\r\n * function UsersTable() {\r\n * return (\r\n * <RowaKitTable\r\n * fetcher={fetchUsers}\r\n * columns={[\r\n * col.text('name', { header: 'Name', sortable: true }),\r\n * col.text('email', { header: 'Email' }),\r\n * col.date('createdAt', { header: 'Created' }),\r\n * col.boolean('active', { header: 'Active' }),\r\n * col.actions([\r\n * { id: 'edit', label: 'Edit', onClick: (user) => editUser(user) },\r\n * { id: 'delete', label: 'Delete', confirm: true, onClick: (user) => deleteUser(user) }\r\n * ])\r\n * ]}\r\n * defaultPageSize={20}\r\n * rowKey=\"id\"\r\n * />\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport function RowaKitTable<T>({\r\n fetcher,\r\n columns,\r\n defaultPageSize = 20,\r\n pageSizeOptions = [10, 20, 50],\r\n rowKey,\r\n className = '',\r\n enableFilters = false,\r\n}: SmartTableProps<T>) {\r\n // State management\r\n const [dataState, setDataState] = useState<DataState<T>>({\r\n state: 'idle',\r\n items: [],\r\n total: 0,\r\n });\r\n\r\n const [query, setQuery] = useState<FetcherQuery>({\r\n page: 1,\r\n pageSize: defaultPageSize,\r\n });\r\n\r\n // Filter state (field -> FilterValue)\r\n const [filters, setFilters] = useState<Record<string, FilterValue | undefined>>({});\r\n\r\n // Confirmation state for actions that require confirmation\r\n const [confirmState, setConfirmState] = useState<ConfirmState<T> | null>(null);\r\n\r\n // Request tracking to ignore stale responses\r\n const requestIdRef = useRef(0);\r\n\r\n // Sync filters to query (and reset page to 1 when filters change)\r\n useEffect(() => {\r\n if (!enableFilters) return;\r\n\r\n // Build filters object, excluding undefined values\r\n const activeFilters: Record<string, FilterValue> = {};\r\n let hasFilters = false;\r\n \r\n for (const [field, value] of Object.entries(filters)) {\r\n if (value !== undefined) {\r\n activeFilters[field] = value;\r\n hasFilters = true;\r\n }\r\n }\r\n\r\n // Per spec: filters must be undefined when empty (not {})\r\n const filtersToSend = hasFilters ? activeFilters : undefined;\r\n\r\n setQuery((prev) => ({\r\n ...prev,\r\n filters: filtersToSend,\r\n page: 1, // Reset page to 1 when filters change\r\n }));\r\n }, [filters, enableFilters]);\r\n\r\n // Fetch data effect\r\n useEffect(() => {\r\n const currentRequestId = ++requestIdRef.current;\r\n\r\n setDataState((prev) => ({ ...prev, state: 'loading' }));\r\n\r\n fetcher(query)\r\n .then((result) => {\r\n // Ignore stale responses\r\n if (currentRequestId !== requestIdRef.current) {\r\n return;\r\n }\r\n\r\n if (result.items.length === 0) {\r\n setDataState({\r\n state: 'empty',\r\n items: [],\r\n total: result.total,\r\n });\r\n } else {\r\n setDataState({\r\n state: 'success',\r\n items: result.items,\r\n total: result.total,\r\n });\r\n }\r\n })\r\n .catch((error: unknown) => {\r\n // Ignore stale responses\r\n if (currentRequestId !== requestIdRef.current) {\r\n return;\r\n }\r\n\r\n setDataState({\r\n state: 'error',\r\n items: [],\r\n total: 0,\r\n error: error instanceof Error ? error.message : 'Failed to load data',\r\n });\r\n });\r\n }, [fetcher, query]);\r\n\r\n // Retry handler\r\n const handleRetry = () => {\r\n // Force re-fetch by updating query reference\r\n setQuery({ ...query });\r\n };\r\n\r\n // Pagination handlers\r\n const handlePreviousPage = () => {\r\n if (query.page > 1) {\r\n setQuery((prev) => ({ ...prev, page: prev.page - 1 }));\r\n }\r\n };\r\n\r\n const handleNextPage = () => {\r\n const totalPages = Math.ceil(dataState.total / query.pageSize);\r\n if (query.page < totalPages) {\r\n setQuery((prev) => ({ ...prev, page: prev.page + 1 }));\r\n }\r\n };\r\n\r\n const handlePageSizeChange = (newPageSize: number) => {\r\n setQuery({ ...query, pageSize: newPageSize, page: 1 });\r\n };\r\n\r\n // Sorting handler\r\n const handleSort = (field: string) => {\r\n setQuery((prev) => {\r\n // If sorting by a different field, start with ascending\r\n if (prev.sort?.field !== field) {\r\n return { ...prev, sort: { field, direction: 'asc' }, page: 1 };\r\n }\r\n\r\n // Toggle sort direction for the same field\r\n if (prev.sort.direction === 'asc') {\r\n return { ...prev, sort: { field, direction: 'desc' }, page: 1 };\r\n }\r\n\r\n // Remove sort (back to unsorted)\r\n const { sort: _sort, ...rest } = prev;\r\n return { ...rest, page: 1 };\r\n });\r\n };\r\n\r\n // Get sort indicator for a column\r\n const getSortIndicator = (field: string): string => {\r\n if (!query.sort || query.sort.field !== field) {\r\n return '';\r\n }\r\n return query.sort.direction === 'asc' ? ' ↑' : ' ↓';\r\n };\r\n\r\n // Filter handlers\r\n const handleFilterChange = (field: string, value: FilterValue | undefined) => {\r\n setFilters((prev) => ({\r\n ...prev,\r\n [field]: value,\r\n }));\r\n };\r\n\r\n const handleClearFilter = (field: string) => {\r\n setFilters((prev) => {\r\n const newFilters = { ...prev };\r\n delete newFilters[field];\r\n return newFilters;\r\n });\r\n };\r\n\r\n const handleClearAllFilters = () => {\r\n setFilters({});\r\n };\r\n\r\n const isLoading = dataState.state === 'loading';\r\n const isError = dataState.state === 'error';\r\n const isEmpty = dataState.state === 'empty';\r\n const totalPages = Math.ceil(dataState.total / query.pageSize);\r\n const canGoPrevious = query.page > 1 && !isLoading;\r\n const canGoNext = query.page < totalPages && !isLoading;\r\n\r\n const hasActiveFilters = enableFilters && Object.values(filters).some(v => v !== undefined);\r\n\r\n return (\r\n <div className={`rowakit-table${className ? ` ${className}` : ''}`}>\r\n {hasActiveFilters && (\r\n <div className=\"rowakit-table-filter-controls\">\r\n <button\r\n onClick={handleClearAllFilters}\r\n className=\"rowakit-button rowakit-button-secondary\"\r\n type=\"button\"\r\n >\r\n Clear all filters\r\n </button>\r\n </div>\r\n )}\r\n <table>\r\n <thead>\r\n <tr>\r\n {columns.map((column) => {\r\n const isSortable = column.kind !== 'actions' && \r\n (column.kind === 'custom' ? false : column.sortable === true);\r\n const field = column.kind === 'actions' ? '' : \r\n column.kind === 'custom' ? column.field : \r\n column.field;\r\n\r\n return (\r\n <th\r\n key={column.id}\r\n onClick={isSortable ? () => handleSort(String(field)) : undefined}\r\n role={isSortable ? 'button' : undefined}\r\n tabIndex={isSortable ? 0 : undefined}\r\n onKeyDown={isSortable ? (e) => {\r\n if (e.key === 'Enter' || e.key === ' ') {\r\n e.preventDefault();\r\n handleSort(String(field));\r\n }\r\n } : undefined}\r\n aria-sort={\r\n isSortable && query.sort?.field === String(field)\r\n ? query.sort.direction === 'asc' ? 'ascending' : 'descending'\r\n : undefined\r\n }\r\n style={{\r\n width: column.width ? `${column.width}px` : undefined,\r\n textAlign: column.align,\r\n }}\r\n className={column.truncate ? 'rowakit-cell-truncate' : undefined}\r\n >\r\n {getHeaderLabel(column)}{isSortable && getSortIndicator(String(field))}\r\n </th>\r\n );\r\n })}\r\n </tr>\r\n {enableFilters && (\r\n <tr className=\"rowakit-table-filter-row\">\r\n {columns.map((column) => {\r\n const field = column.kind === 'actions' || column.kind === 'custom' ? '' : String(column.field);\r\n const canFilter = field && column.kind !== 'actions';\r\n \r\n if (!canFilter) {\r\n return <th key={column.id}></th>;\r\n }\r\n\r\n const filterValue = filters[field];\r\n\r\n // Badge column: select with options\r\n if (column.kind === 'badge') {\r\n const options = column.map ? Object.keys(column.map) : [];\r\n return (\r\n <th key={column.id}>\r\n <select\r\n className=\"rowakit-filter-select\"\r\n value={filterValue?.op === 'equals' ? String(filterValue.value ?? '') : ''}\r\n onChange={(e) => {\r\n const value = e.target.value;\r\n if (value === '') {\r\n handleClearFilter(field);\r\n } else {\r\n handleFilterChange(field, { op: 'equals', value });\r\n }\r\n }}\r\n >\r\n <option value=\"\">All</option>\r\n {options.map((opt) => (\r\n <option key={opt} value={opt}>\r\n {opt}\r\n </option>\r\n ))}\r\n </select>\r\n </th>\r\n );\r\n }\r\n\r\n // Boolean column: select with True/False/All\r\n if (column.kind === 'boolean') {\r\n return (\r\n <th key={column.id}>\r\n <select\r\n className=\"rowakit-filter-select\"\r\n value={\r\n filterValue?.op === 'equals' && typeof filterValue.value === 'boolean'\r\n ? String(filterValue.value)\r\n : ''\r\n }\r\n onChange={(e) => {\r\n const value = e.target.value;\r\n if (value === '') {\r\n handleClearFilter(field);\r\n } else {\r\n handleFilterChange(field, { op: 'equals', value: value === 'true' });\r\n }\r\n }}\r\n >\r\n <option value=\"\">All</option>\r\n <option value=\"true\">True</option>\r\n <option value=\"false\">False</option>\r\n </select>\r\n </th>\r\n );\r\n }\r\n\r\n // Date column: from/to inputs\r\n if (column.kind === 'date') {\r\n const fromValue = filterValue?.op === 'range' ? filterValue.value.from ?? '' : '';\r\n const toValue = filterValue?.op === 'range' ? filterValue.value.to ?? '' : '';\r\n \r\n return (\r\n <th key={column.id}>\r\n <div className=\"rowakit-filter-date-range\">\r\n <input\r\n type=\"date\"\r\n className=\"rowakit-filter-input\"\r\n placeholder=\"From\"\r\n value={fromValue}\r\n onChange={(e) => {\r\n const from = e.target.value || undefined;\r\n const to = toValue || undefined;\r\n if (!from && !to) {\r\n handleClearFilter(field);\r\n } else {\r\n handleFilterChange(field, { op: 'range', value: { from, to } });\r\n }\r\n }}\r\n />\r\n <input\r\n type=\"date\"\r\n className=\"rowakit-filter-input\"\r\n placeholder=\"To\"\r\n value={toValue}\r\n onChange={(e) => {\r\n const to = e.target.value || undefined;\r\n const from = fromValue || undefined;\r\n if (!from && !to) {\r\n handleClearFilter(field);\r\n } else {\r\n handleFilterChange(field, { op: 'range', value: { from, to } });\r\n }\r\n }}\r\n />\r\n </div>\r\n </th>\r\n );\r\n }\r\n\r\n // Text/Number column: text or number input\r\n const isNumberColumn = column.kind === 'number';\r\n return (\r\n <th key={column.id}>\r\n <input\r\n type={isNumberColumn ? 'number' : 'text'}\r\n className=\"rowakit-filter-input\"\r\n placeholder={`Filter ${getHeaderLabel(column)}...`}\r\n value={\r\n filterValue?.op === 'contains'\r\n ? filterValue.value\r\n : filterValue?.op === 'equals' && typeof filterValue.value === 'string'\r\n ? filterValue.value\r\n : filterValue?.op === 'equals' && typeof filterValue.value === 'number'\r\n ? String(filterValue.value)\r\n : ''\r\n }\r\n onChange={(e) => {\r\n const rawValue = e.target.value;\r\n if (rawValue === '') {\r\n handleClearFilter(field);\r\n } else if (isNumberColumn) {\r\n const numValue = Number(rawValue);\r\n if (!isNaN(numValue)) {\r\n handleFilterChange(field, { op: 'equals', value: numValue } as FilterValue);\r\n } else {\r\n // Invalid numeric input: clear the filter to avoid confusing UX\r\n handleClearFilter(field);\r\n }\r\n } else {\r\n // Text: use \"contains\"\r\n handleFilterChange(field, { op: 'contains', value: rawValue } as FilterValue);\r\n }\r\n }}\r\n />\r\n </th>\r\n );\r\n })}\r\n </tr>\r\n )}\r\n </thead>\r\n <tbody>\r\n {isLoading && (\r\n <tr>\r\n <td colSpan={columns.length} className=\"rowakit-table-loading\">\r\n <div className=\"rowakit-table-loading-spinner\"></div>\r\n <span>Loading...</span>\r\n </td>\r\n </tr>\r\n )}\r\n\r\n {isError && (\r\n <tr>\r\n <td colSpan={columns.length} className=\"rowakit-table-error\">\r\n <div className=\"rowakit-table-error-message\">\r\n {dataState.error ?? 'An error occurred'}\r\n </div>\r\n <button\r\n onClick={handleRetry}\r\n className=\"rowakit-button rowakit-button-primary\"\r\n type=\"button\"\r\n >\r\n Retry\r\n </button>\r\n </td>\r\n </tr>\r\n )}\r\n\r\n {isEmpty && (\r\n <tr>\r\n <td colSpan={columns.length} className=\"rowakit-table-empty\">\r\n No data\r\n </td>\r\n </tr>\r\n )}\r\n\r\n {dataState.state === 'success' &&\r\n dataState.items.map((row) => {\r\n const key = getRowKey(row, rowKey);\r\n return (\r\n <tr key={key}>\r\n {columns.map((column) => {\r\n const cellClass = [\r\n column.kind === 'number' ? 'rowakit-cell-number' : '',\r\n column.truncate ? 'rowakit-cell-truncate' : '',\r\n ].filter(Boolean).join(' ') || undefined;\r\n \r\n return (\r\n <td \r\n key={column.id}\r\n className={cellClass}\r\n style={{\r\n width: column.width ? `${column.width}px` : undefined,\r\n textAlign: column.align || (column.kind === 'number' ? 'right' : undefined),\r\n }}\r\n >\r\n {renderCell(column, row, isLoading, setConfirmState)}\r\n </td>\r\n );\r\n })}\r\n </tr>\r\n );\r\n })}\r\n </tbody>\r\n </table>\r\n\r\n {/* Pagination Controls */}\r\n {dataState.total > 0 && (\r\n <div className=\"rowakit-table-pagination\">\r\n {/* Left: Page size selector */}\r\n <div className=\"rowakit-table-pagination-left\">\r\n <label htmlFor=\"page-size\">\r\n Rows per page:\r\n </label>\r\n <select\r\n id=\"page-size\"\r\n value={query.pageSize}\r\n onChange={(e) => handlePageSizeChange(Number(e.target.value))}\r\n disabled={isLoading}\r\n >\r\n {pageSizeOptions.map((size) => (\r\n <option key={size} value={size}>\r\n {size}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n\r\n {/* Center: Page info */}\r\n <div className=\"rowakit-table-pagination-center\">\r\n Page {query.page} of {totalPages} ({dataState.total} total)\r\n </div>\r\n\r\n {/* Right: Previous/Next buttons */}\r\n <div className=\"rowakit-table-pagination-right\">\r\n <button\r\n onClick={handlePreviousPage}\r\n disabled={!canGoPrevious}\r\n className=\"rowakit-button rowakit-button-primary rowakit-button-pagination\"\r\n type=\"button\"\r\n aria-label=\"Previous page\"\r\n >\r\n Previous\r\n </button>\r\n <button\r\n onClick={handleNextPage}\r\n disabled={!canGoNext}\r\n className=\"rowakit-button rowakit-button-primary rowakit-button-pagination\"\r\n type=\"button\"\r\n aria-label=\"Next page\"\r\n >\r\n Next\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Confirmation Modal */}\r\n {confirmState && (\r\n <div\r\n className=\"rowakit-modal-backdrop\"\r\n onClick={() => setConfirmState(null)}\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n aria-labelledby=\"confirm-dialog-title\"\r\n >\r\n <div className=\"rowakit-modal\" onClick={(e) => e.stopPropagation()}>\r\n <h2 id=\"confirm-dialog-title\" className=\"rowakit-modal-title\">\r\n Confirm Action\r\n </h2>\r\n <p className=\"rowakit-modal-content\">\r\n Are you sure you want to {confirmState.action.label.toLowerCase()}? This action cannot be\r\n undone.\r\n </p>\r\n <div className=\"rowakit-modal-actions\">\r\n <button\r\n onClick={() => setConfirmState(null)}\r\n className=\"rowakit-button rowakit-button-secondary\"\r\n type=\"button\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n onClick={() => {\r\n void confirmState.action.onClick(confirmState.row);\r\n setConfirmState(null);\r\n }}\r\n className=\"rowakit-button rowakit-button-danger\"\r\n type=\"button\"\r\n >\r\n Confirm\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n/**\r\n * @deprecated Use RowaKitTable instead. SmartTable is kept as an alias for backward compatibility.\r\n */\r\nexport const SmartTable = RowaKitTable;\r\n","/**\r\n * @rowakit/table\r\n *\r\n * Opinionated, server-side-first table component for internal/business apps.\r\n *\r\n * @packageDocumentation\r\n */\r\n\r\n// Core types\r\nexport type {\r\n // Fetcher types\r\n Fetcher,\r\n FetcherQuery,\r\n FetcherResult,\r\n FilterValue,\r\n Filters,\r\n // Column types\r\n ColumnDef,\r\n ColumnKind,\r\n BaseColumnDef,\r\n TextColumnDef,\r\n DateColumnDef,\r\n BooleanColumnDef,\r\n BadgeColumnDef,\r\n NumberColumnDef,\r\n ActionsColumnDef,\r\n CustomColumnDef,\r\n BadgeTone,\r\n // Action types\r\n ActionDef,\r\n} from './types';\r\n\r\n// Column helper factory\r\nexport { col } from './column-helpers';\r\n\r\n// Components\r\nexport { RowaKitTable, SmartTable } from './components/SmartTable';\r\nexport type { SmartTableProps } from './components/SmartTable';\r\n\r\nexport const VERSION = '0.1.0';\r\n"]}
1
+ {"version":3,"sources":["../src/column-helpers.ts","../src/components/SmartTable.tsx","../src/index.ts"],"names":["actions","totalPages"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Column helper factory functions\r\n *\r\n * These helpers provide a clean, type-safe API for defining table columns.\r\n * They reduce boilerplate and enforce conventions while maintaining flexibility\r\n * through the `col.custom` escape hatch.\r\n *\r\n * @packageDocumentation\r\n */\r\n\r\nimport type { ReactNode } from 'react';\r\nimport type {\r\n TextColumnDef,\r\n DateColumnDef,\r\n BooleanColumnDef,\r\n BadgeColumnDef,\r\n NumberColumnDef,\r\n ActionsColumnDef,\r\n CustomColumnDef,\r\n ActionDef,\r\n BadgeTone,\r\n} from './types';\r\n\r\n// ============================================================================\r\n// HELPER OPTIONS\r\n// ============================================================================\r\n\r\ninterface TextOptions {\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Enable sorting for this column */\r\n sortable?: boolean;\r\n /** Optional formatter function */\r\n format?: (value: unknown) => string;\r\n /** Column width in pixels */\r\n width?: number;\r\n /** Text alignment */\r\n align?: 'left' | 'center' | 'right';\r\n /** Enable text truncation with ellipsis */\r\n truncate?: boolean;\r\n}\r\n\r\ninterface DateOptions {\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Enable sorting for this column */\r\n sortable?: boolean;\r\n /** Optional date formatter function */\r\n format?: (value: Date | string | number) => string;\r\n /** Column width in pixels */\r\n width?: number;\r\n /** Text alignment */\r\n align?: 'left' | 'center' | 'right';\r\n /** Enable text truncation with ellipsis */\r\n truncate?: boolean;\r\n}\r\n\r\ninterface BooleanOptions {\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Enable sorting for this column */\r\n sortable?: boolean;\r\n /** Optional boolean formatter function */\r\n format?: (value: boolean) => string;\r\n /** Column width in pixels */\r\n width?: number;\r\n /** Text alignment */\r\n align?: 'left' | 'center' | 'right';\r\n /** Enable text truncation with ellipsis */\r\n truncate?: boolean;\r\n}\r\n\r\ninterface BadgeOptions {\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Enable sorting for this column */\r\n sortable?: boolean;\r\n /** Value-to-badge mapping */\r\n map?: Record<string, { label: string; tone: BadgeTone }>;\r\n /** Column width in pixels */\r\n width?: number;\r\n /** Text alignment */\r\n align?: 'left' | 'center' | 'right';\r\n /** Enable text truncation with ellipsis */\r\n truncate?: boolean;\r\n}\r\n\r\ninterface NumberOptions<T = unknown> {\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Enable sorting for this column */\r\n sortable?: boolean;\r\n /** Formatting options: Intl.NumberFormatOptions or custom formatter */\r\n format?: Intl.NumberFormatOptions | ((value: number, row: T) => string);\r\n /** Column width in pixels */\r\n width?: number;\r\n /** Text alignment */\r\n align?: 'left' | 'center' | 'right';\r\n /** Enable text truncation with ellipsis */\r\n truncate?: boolean;\r\n}\r\n\r\n// ============================================================================\r\n// COLUMN HELPER FUNCTIONS\r\n// ============================================================================\r\n\r\n/**\r\n * Create a text column definition.\r\n *\r\n * @example\r\n * ```ts\r\n * col.text('name')\r\n * col.text('email', { header: 'Email Address', sortable: true })\r\n * col.text('status', { format: (val) => val.toUpperCase() })\r\n * ```\r\n */\r\nfunction text<T>(\r\n field: keyof T & string,\r\n options?: TextOptions\r\n): TextColumnDef<T> {\r\n return {\r\n id: field,\r\n kind: 'text',\r\n field,\r\n header: options?.header,\r\n sortable: options?.sortable ?? false,\r\n format: options?.format,\r\n width: options?.width,\r\n align: options?.align,\r\n truncate: options?.truncate,\r\n };\r\n}\r\n\r\n/**\r\n * Create a date column definition.\r\n *\r\n * @example\r\n * ```ts\r\n * col.date('createdAt')\r\n * col.date('updatedAt', { header: 'Last Modified', sortable: true })\r\n * col.date('birthday', {\r\n * format: (date) => new Date(date).toLocaleDateString()\r\n * })\r\n * ```\r\n */\r\nfunction date<T>(\r\n field: keyof T & string,\r\n options?: DateOptions\r\n): DateColumnDef<T> {\r\n return {\r\n id: field,\r\n kind: 'date',\r\n field,\r\n header: options?.header,\r\n sortable: options?.sortable ?? false,\r\n format: options?.format,\r\n width: options?.width,\r\n align: options?.align,\r\n truncate: options?.truncate,\r\n };\r\n}\r\n\r\n/**\r\n * Create a boolean column definition.\r\n *\r\n * @example\r\n * ```ts\r\n * col.boolean('active')\r\n * col.boolean('isPublished', { header: 'Published', sortable: true })\r\n * col.boolean('enabled', {\r\n * format: (val) => val ? 'Yes' : 'No'\r\n * })\r\n * ```\r\n */\r\nfunction boolean<T>(\r\n field: keyof T & string,\r\n options?: BooleanOptions\r\n): BooleanColumnDef<T> {\r\n return {\r\n id: field,\r\n kind: 'boolean',\r\n field,\r\n header: options?.header,\r\n sortable: options?.sortable ?? false,\r\n format: options?.format,\r\n width: options?.width,\r\n align: options?.align,\r\n truncate: options?.truncate,\r\n };\r\n}\r\n\r\n/**\r\n * Create a badge column definition for status/enum fields.\r\n *\r\n * @example\r\n * ```ts\r\n * col.badge('status')\r\n * col.badge('status', {\r\n * map: {\r\n * active: { label: 'Active', tone: 'success' },\r\n * paused: { label: 'Paused', tone: 'warning' },\r\n * disabled: { label: 'Disabled', tone: 'danger' }\r\n * }\r\n * })\r\n * ```\r\n */\r\nfunction badge<T>(\r\n field: keyof T & string,\r\n options?: BadgeOptions\r\n): BadgeColumnDef<T> {\r\n return {\r\n id: field,\r\n kind: 'badge',\r\n field,\r\n header: options?.header,\r\n sortable: options?.sortable ?? false,\r\n map: options?.map,\r\n width: options?.width,\r\n align: options?.align,\r\n truncate: options?.truncate,\r\n };\r\n}\r\n\r\n/**\r\n * Create a number column definition.\r\n *\r\n * @example\r\n * ```ts\r\n * col.number('amount')\r\n * col.number('price', {\r\n * format: { style: 'currency', currency: 'USD' }\r\n * })\r\n * col.number('count', {\r\n * format: (val, row) => `${val} items`\r\n * })\r\n * ```\r\n */\r\nfunction number<T>(\r\n field: keyof T & string,\r\n options?: NumberOptions<T>\r\n): NumberColumnDef<T> {\r\n return {\r\n id: field,\r\n kind: 'number',\r\n field,\r\n header: options?.header,\r\n sortable: options?.sortable ?? false,\r\n format: options?.format,\r\n width: options?.width,\r\n align: options?.align,\r\n truncate: options?.truncate,\r\n };\r\n}\r\n\r\n/**\r\n * Create an actions column definition.\r\n *\r\n * The actions column displays a set of actions (buttons/links) that can be\r\n * performed on each row.\r\n *\r\n * @example\r\n * ```ts\r\n * col.actions([\r\n * { id: 'edit', label: 'Edit', onClick: (row) => editUser(row) },\r\n * { id: 'delete', label: 'Delete', confirm: true, onClick: (row) => deleteUser(row) }\r\n * ])\r\n * ```\r\n */\r\nfunction actions<T>(actions: ActionDef<T>[]): ActionsColumnDef<T> {\r\n return {\r\n id: 'actions',\r\n kind: 'actions',\r\n actions,\r\n };\r\n}\r\n\r\n/**\r\n * Create a custom column definition with full rendering control.\r\n *\r\n * This is the escape hatch for any column that doesn't fit the standard types.\r\n * Use this for badges, avatars, complex formatting, or any custom UI.\r\n *\r\n * @example\r\n * ```ts\r\n * col.custom({\r\n * id: 'avatar',\r\n * header: 'User',\r\n * render: (row) => <img src={row.avatar} alt={row.name} />\r\n * })\r\n *\r\n * col.custom({\r\n * id: 'price',\r\n * field: 'price',\r\n * render: (row) => <Money amount={row.price} currency={row.currency} />\r\n * })\r\n *\r\n * col.custom({\r\n * id: 'status',\r\n * render: (row) => (\r\n * <Badge color={row.status === 'active' ? 'green' : 'gray'}>\r\n * {row.status}\r\n * </Badge>\r\n * )\r\n * })\r\n * ```\r\n */\r\nfunction custom<T>(\r\n field: keyof T & string,\r\n render: (row: T) => ReactNode\r\n): CustomColumnDef<T>;\r\nfunction custom<T>(options: {\r\n /** Unique column identifier */\r\n id: string;\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Optional field name for sorting/filtering */\r\n field?: keyof T & string;\r\n /** Render function for cell content */\r\n render: (row: T) => ReactNode;\r\n}): CustomColumnDef<T>;\r\nfunction custom<T>(\r\n arg1:\r\n | (keyof T & string)\r\n | {\r\n id: string;\r\n header?: string;\r\n field?: keyof T & string;\r\n render: (row: T) => ReactNode;\r\n },\r\n arg2?: (row: T) => ReactNode\r\n): CustomColumnDef<T> {\r\n if (typeof arg1 === 'string') {\r\n if (typeof arg2 !== 'function') {\r\n throw new Error('col.custom(field, render): render must be a function');\r\n }\r\n\r\n return {\r\n id: arg1,\r\n kind: 'custom',\r\n field: arg1,\r\n render: arg2,\r\n };\r\n }\r\n\r\n return {\r\n id: arg1.id,\r\n kind: 'custom',\r\n header: arg1.header,\r\n field: arg1.field,\r\n render: arg1.render,\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// EXPORTS\r\n// ============================================================================\r\n\r\n/**\r\n * Column helper factory object.\r\n *\r\n * Provides convenient helper functions for creating column definitions.\r\n *\r\n * @example\r\n * ```tsx\r\n * import { col } from '@rowakit/table';\r\n *\r\n * const columns = [\r\n * col.text('name', { sortable: true }),\r\n * col.date('createdAt'),\r\n * col.boolean('active'),\r\n * col.actions([\r\n * { id: 'edit', label: 'Edit', onClick: (row) => {} }\r\n * ]),\r\n * col.custom({ id: 'badge', render: (row) => <Badge>{row.status}</Badge> })\r\n * ];\r\n * ```\r\n */\r\nexport const col = {\r\n text,\r\n date,\r\n boolean,\r\n badge,\r\n number,\r\n actions,\r\n custom,\r\n} as const;\r\n","/**\r\n * RowaKit Table Component\r\n *\r\n * Core table rendering component that maps columns to table cells.\r\n * Handles all column types: text, date, boolean, actions, and custom.\r\n * Includes data fetching state machine with loading/error/empty states.\r\n *\r\n * @packageDocumentation\r\n */\r\n\r\nimport { useState, useEffect, useRef } from 'react';\r\nimport type { ReactNode } from 'react';\r\nimport type { Fetcher, ColumnDef, FetcherQuery, ActionDef, FilterValue } from '../types';\r\n\r\n// ============================================================================\r\n// COMPONENT PROPS\r\n// ============================================================================\r\n\r\nexport interface SmartTableProps<T> {\r\n /** Server-side data fetcher function */\r\n fetcher: Fetcher<T>;\r\n\r\n /** Array of column definitions */\r\n columns: ColumnDef<T>[];\r\n\r\n /** Available page size options (default: [10, 20, 50]) */\r\n pageSizeOptions?: number[];\r\n\r\n /** Initial page size (default: 20) */\r\n defaultPageSize?: number;\r\n\r\n /** Function or field name to extract row key (default: uses 'id' field) */\r\n rowKey?: keyof T | ((row: T) => string | number);\r\n\r\n /** Optional CSS class name for the table container */\r\n className?: string;\r\n\r\n /** Enable filters (default: false) */\r\n enableFilters?: boolean;\r\n}\r\n\r\n// ============================================================================\r\n// STATE MANAGEMENT\r\n// ============================================================================\r\n\r\ntype FetchState = 'idle' | 'loading' | 'success' | 'empty' | 'error';\r\n\r\ninterface DataState<T> {\r\n state: FetchState;\r\n items: T[];\r\n total: number;\r\n error?: string;\r\n}\r\n\r\n/**\r\n * Confirmation state for actions that require confirmation.\r\n */\r\ninterface ConfirmState<T> {\r\n action: ActionDef<T>;\r\n row: T;\r\n}\r\n\r\n// ============================================================================\r\n// HELPER FUNCTIONS\r\n// ============================================================================\r\n\r\n/**\r\n * Extract unique key from a row.\r\n */\r\nfunction getRowKey<T>(row: T, rowKey?: keyof T | ((row: T) => string | number)): string | number {\r\n if (typeof rowKey === 'function') {\r\n return rowKey(row);\r\n }\r\n if (rowKey) {\r\n return String(row[rowKey]);\r\n }\r\n // Fallback to 'id' field if available\r\n if (row && typeof row === 'object' && 'id' in row) {\r\n return String(row.id);\r\n }\r\n // Last resort: use object reference (not ideal but safe)\r\n return String(row);\r\n}\r\n\r\n/**\r\n * Get header label for a column.\r\n */\r\nfunction getHeaderLabel<T>(column: ColumnDef<T>): string {\r\n return column.header ?? column.id;\r\n}\r\n\r\n/**\r\n * Render cell content based on column kind.\r\n */\r\nfunction renderCell<T>(\r\n column: ColumnDef<T>,\r\n row: T,\r\n isLoading: boolean,\r\n setConfirmState: (state: ConfirmState<T> | null) => void\r\n): ReactNode {\r\n switch (column.kind) {\r\n case 'text': {\r\n const value = row[column.field];\r\n if (column.format) {\r\n return column.format(value);\r\n }\r\n return String(value ?? '');\r\n }\r\n\r\n case 'date': {\r\n const value = row[column.field];\r\n if (column.format) {\r\n return column.format(value as Date | string | number);\r\n }\r\n // Default date formatting\r\n if (value instanceof Date) {\r\n return value.toLocaleDateString();\r\n }\r\n if (typeof value === 'string' || typeof value === 'number') {\r\n return new Date(value).toLocaleDateString();\r\n }\r\n return '';\r\n }\r\n\r\n case 'boolean': {\r\n const value = row[column.field];\r\n if (column.format) {\r\n return column.format(Boolean(value));\r\n }\r\n // Default boolean formatting\r\n return value ? 'Yes' : 'No';\r\n }\r\n\r\n case 'badge': {\r\n const value = row[column.field];\r\n const valueStr = String(value ?? '');\r\n \r\n // Look up mapping\r\n const mapped = column.map?.[valueStr];\r\n const label = mapped?.label ?? valueStr;\r\n const tone = mapped?.tone ?? 'neutral';\r\n \r\n return (\r\n <span className={`rowakit-badge rowakit-badge-${tone}`}>\r\n {label}\r\n </span>\r\n );\r\n }\r\n\r\n case 'number': {\r\n const value = row[column.field];\r\n const numValue = Number(value ?? 0);\r\n \r\n if (column.format) {\r\n if (typeof column.format === 'function') {\r\n return column.format(numValue, row);\r\n }\r\n // Intl.NumberFormatOptions\r\n return new Intl.NumberFormat(undefined, column.format).format(numValue);\r\n }\r\n \r\n // Default number formatting\r\n return numValue.toLocaleString();\r\n }\r\n\r\n case 'actions': {\r\n return (\r\n <div className=\"rowakit-table-actions\">\r\n {column.actions.map((action) => {\r\n const isDisabled =\r\n isLoading ||\r\n action.disabled === true ||\r\n (typeof action.disabled === 'function' && action.disabled(row));\r\n\r\n const handleClick = () => {\r\n if (isDisabled || action.loading) {\r\n return;\r\n }\r\n\r\n // If action requires confirmation, show modal\r\n if (action.confirm) {\r\n setConfirmState({ action, row });\r\n } else {\r\n // Execute action directly\r\n void action.onClick(row);\r\n }\r\n };\r\n\r\n return (\r\n <button\r\n key={action.id}\r\n onClick={handleClick}\r\n disabled={isDisabled || action.loading}\r\n type=\"button\"\r\n className=\"rowakit-button rowakit-button-secondary\"\r\n >\r\n {action.icon && typeof action.icon === 'string' ? (\r\n <span>{action.icon}</span>\r\n ) : (\r\n action.icon\r\n )}\r\n {action.label}\r\n </button>\r\n );\r\n })}\r\n </div>\r\n );\r\n }\r\n\r\n case 'custom': {\r\n return column.render(row);\r\n }\r\n\r\n default: {\r\n // Exhaustive check\r\n const _exhaustive: never = column;\r\n return _exhaustive;\r\n }\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// MAIN COMPONENT\r\n// ============================================================================\r\n\r\n/**\r\n * RowaKitTable - Server-side table component for internal/business apps.\r\n *\r\n * This component renders a table with headers and body based on column definitions.\r\n * It handles all column types (text, date, boolean, actions, custom) and provides\r\n * a clean API for defining table structure.\r\n *\r\n * Features:\r\n * - Automatic data fetching on mount and query changes\r\n * - Loading, error, and empty states\r\n * - Stale request handling\r\n * - Retry on error\r\n *\r\n * @example\r\n * ```tsx\r\n * import { RowaKitTable, col } from '@rowakit/table';\r\n *\r\n * interface User {\r\n * id: string;\r\n * name: string;\r\n * email: string;\r\n * createdAt: Date;\r\n * active: boolean;\r\n * }\r\n *\r\n * const fetchUsers: Fetcher<User> = async (query) => {\r\n * const response = await fetch(`/api/users?page=${query.page}&pageSize=${query.pageSize}`);\r\n * return response.json();\r\n * };\r\n *\r\n * function UsersTable() {\r\n * return (\r\n * <RowaKitTable\r\n * fetcher={fetchUsers}\r\n * columns={[\r\n * col.text('name', { header: 'Name', sortable: true }),\r\n * col.text('email', { header: 'Email' }),\r\n * col.date('createdAt', { header: 'Created' }),\r\n * col.boolean('active', { header: 'Active' }),\r\n * col.actions([\r\n * { id: 'edit', label: 'Edit', onClick: (user) => editUser(user) },\r\n * { id: 'delete', label: 'Delete', confirm: true, onClick: (user) => deleteUser(user) }\r\n * ])\r\n * ]}\r\n * defaultPageSize={20}\r\n * rowKey=\"id\"\r\n * />\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport function RowaKitTable<T>({\r\n fetcher,\r\n columns,\r\n defaultPageSize = 20,\r\n pageSizeOptions = [10, 20, 50],\r\n rowKey,\r\n className = '',\r\n enableFilters = false,\r\n}: SmartTableProps<T>) {\r\n // State management\r\n const [dataState, setDataState] = useState<DataState<T>>({\r\n state: 'idle',\r\n items: [],\r\n total: 0,\r\n });\r\n\r\n const [query, setQuery] = useState<FetcherQuery>({\r\n page: 1,\r\n pageSize: defaultPageSize,\r\n });\r\n\r\n // Filter state (field -> FilterValue)\r\n const [filters, setFilters] = useState<Record<string, FilterValue | undefined>>({});\r\n\r\n // Confirmation state for actions that require confirmation\r\n const [confirmState, setConfirmState] = useState<ConfirmState<T> | null>(null);\r\n\r\n // Request tracking to ignore stale responses\r\n const requestIdRef = useRef(0);\r\n\r\n // Sync filters to query (and reset page to 1 when filters change)\r\n useEffect(() => {\r\n if (!enableFilters) return;\r\n\r\n // Build filters object, excluding undefined values\r\n const activeFilters: Record<string, FilterValue> = {};\r\n let hasFilters = false;\r\n \r\n for (const [field, value] of Object.entries(filters)) {\r\n if (value !== undefined) {\r\n activeFilters[field] = value;\r\n hasFilters = true;\r\n }\r\n }\r\n\r\n // Per spec: filters must be undefined when empty (not {})\r\n const filtersToSend = hasFilters ? activeFilters : undefined;\r\n\r\n setQuery((prev) => ({\r\n ...prev,\r\n filters: filtersToSend,\r\n page: 1, // Reset page to 1 when filters change\r\n }));\r\n }, [filters, enableFilters]);\r\n\r\n // Fetch data effect\r\n useEffect(() => {\r\n const currentRequestId = ++requestIdRef.current;\r\n\r\n setDataState((prev) => ({ ...prev, state: 'loading' }));\r\n\r\n fetcher(query)\r\n .then((result) => {\r\n // Ignore stale responses\r\n if (currentRequestId !== requestIdRef.current) {\r\n return;\r\n }\r\n\r\n if (result.items.length === 0) {\r\n setDataState({\r\n state: 'empty',\r\n items: [],\r\n total: result.total,\r\n });\r\n } else {\r\n setDataState({\r\n state: 'success',\r\n items: result.items,\r\n total: result.total,\r\n });\r\n }\r\n })\r\n .catch((error: unknown) => {\r\n // Ignore stale responses\r\n if (currentRequestId !== requestIdRef.current) {\r\n return;\r\n }\r\n\r\n setDataState({\r\n state: 'error',\r\n items: [],\r\n total: 0,\r\n error: error instanceof Error ? error.message : 'Failed to load data',\r\n });\r\n });\r\n }, [fetcher, query]);\r\n\r\n // Retry handler\r\n const handleRetry = () => {\r\n // Force re-fetch by updating query reference\r\n setQuery({ ...query });\r\n };\r\n\r\n // Pagination handlers\r\n const handlePreviousPage = () => {\r\n if (query.page > 1) {\r\n setQuery((prev) => ({ ...prev, page: prev.page - 1 }));\r\n }\r\n };\r\n\r\n const handleNextPage = () => {\r\n const totalPages = Math.ceil(dataState.total / query.pageSize);\r\n if (query.page < totalPages) {\r\n setQuery((prev) => ({ ...prev, page: prev.page + 1 }));\r\n }\r\n };\r\n\r\n const handlePageSizeChange = (newPageSize: number) => {\r\n setQuery({ ...query, pageSize: newPageSize, page: 1 });\r\n };\r\n\r\n // Sorting handler\r\n const handleSort = (field: string) => {\r\n setQuery((prev) => {\r\n // If sorting by a different field, start with ascending\r\n if (prev.sort?.field !== field) {\r\n return { ...prev, sort: { field, direction: 'asc' }, page: 1 };\r\n }\r\n\r\n // Toggle sort direction for the same field\r\n if (prev.sort.direction === 'asc') {\r\n return { ...prev, sort: { field, direction: 'desc' }, page: 1 };\r\n }\r\n\r\n // Remove sort (back to unsorted)\r\n const { sort: _sort, ...rest } = prev;\r\n return { ...rest, page: 1 };\r\n });\r\n };\r\n\r\n // Get sort indicator for a column\r\n const getSortIndicator = (field: string): string => {\r\n if (!query.sort || query.sort.field !== field) {\r\n return '';\r\n }\r\n return query.sort.direction === 'asc' ? ' ↑' : ' ↓';\r\n };\r\n\r\n // Filter handlers\r\n const handleFilterChange = (field: string, value: FilterValue | undefined) => {\r\n setFilters((prev) => ({\r\n ...prev,\r\n [field]: value,\r\n }));\r\n };\r\n\r\n const handleClearFilter = (field: string) => {\r\n setFilters((prev) => {\r\n const newFilters = { ...prev };\r\n delete newFilters[field];\r\n return newFilters;\r\n });\r\n };\r\n\r\n const handleClearAllFilters = () => {\r\n setFilters({});\r\n };\r\n\r\n const isLoading = dataState.state === 'loading';\r\n const isError = dataState.state === 'error';\r\n const isEmpty = dataState.state === 'empty';\r\n const totalPages = Math.ceil(dataState.total / query.pageSize);\r\n const canGoPrevious = query.page > 1 && !isLoading;\r\n const canGoNext = query.page < totalPages && !isLoading;\r\n\r\n const hasActiveFilters = enableFilters && Object.values(filters).some(v => v !== undefined);\r\n\r\n return (\r\n <div className={`rowakit-table${className ? ` ${className}` : ''}`}>\r\n {hasActiveFilters && (\r\n <div className=\"rowakit-table-filter-controls\">\r\n <button\r\n onClick={handleClearAllFilters}\r\n className=\"rowakit-button rowakit-button-secondary\"\r\n type=\"button\"\r\n >\r\n Clear all filters\r\n </button>\r\n </div>\r\n )}\r\n <table>\r\n <thead>\r\n <tr>\r\n {columns.map((column) => {\r\n const isSortable = column.kind !== 'actions' && \r\n (column.kind === 'custom' ? false : column.sortable === true);\r\n const field = column.kind === 'actions' ? '' : \r\n column.kind === 'custom' ? column.field : \r\n column.field;\r\n\r\n return (\r\n <th\r\n key={column.id}\r\n onClick={isSortable ? () => handleSort(String(field)) : undefined}\r\n role={isSortable ? 'button' : undefined}\r\n tabIndex={isSortable ? 0 : undefined}\r\n onKeyDown={isSortable ? (e) => {\r\n if (e.key === 'Enter' || e.key === ' ') {\r\n e.preventDefault();\r\n handleSort(String(field));\r\n }\r\n } : undefined}\r\n aria-sort={\r\n isSortable && query.sort?.field === String(field)\r\n ? query.sort.direction === 'asc' ? 'ascending' : 'descending'\r\n : undefined\r\n }\r\n style={{\r\n width: column.width ? `${column.width}px` : undefined,\r\n textAlign: column.align,\r\n }}\r\n className={column.truncate ? 'rowakit-cell-truncate' : undefined}\r\n >\r\n {getHeaderLabel(column)}{isSortable && getSortIndicator(String(field))}\r\n </th>\r\n );\r\n })}\r\n </tr>\r\n {enableFilters && (\r\n <tr className=\"rowakit-table-filter-row\">\r\n {columns.map((column) => {\r\n const field = column.kind === 'actions' || column.kind === 'custom' ? '' : String(column.field);\r\n const canFilter = field && column.kind !== 'actions';\r\n \r\n if (!canFilter) {\r\n return <th key={column.id}></th>;\r\n }\r\n\r\n const filterValue = filters[field];\r\n\r\n // Badge column: select with options\r\n if (column.kind === 'badge') {\r\n const options = column.map ? Object.keys(column.map) : [];\r\n return (\r\n <th key={column.id}>\r\n <select\r\n className=\"rowakit-filter-select\"\r\n value={filterValue?.op === 'equals' ? String(filterValue.value ?? '') : ''}\r\n onChange={(e) => {\r\n const value = e.target.value;\r\n if (value === '') {\r\n handleClearFilter(field);\r\n } else {\r\n handleFilterChange(field, { op: 'equals', value });\r\n }\r\n }}\r\n >\r\n <option value=\"\">All</option>\r\n {options.map((opt) => (\r\n <option key={opt} value={opt}>\r\n {opt}\r\n </option>\r\n ))}\r\n </select>\r\n </th>\r\n );\r\n }\r\n\r\n // Boolean column: select with True/False/All\r\n if (column.kind === 'boolean') {\r\n return (\r\n <th key={column.id}>\r\n <select\r\n className=\"rowakit-filter-select\"\r\n value={\r\n filterValue?.op === 'equals' && typeof filterValue.value === 'boolean'\r\n ? String(filterValue.value)\r\n : ''\r\n }\r\n onChange={(e) => {\r\n const value = e.target.value;\r\n if (value === '') {\r\n handleClearFilter(field);\r\n } else {\r\n handleFilterChange(field, { op: 'equals', value: value === 'true' });\r\n }\r\n }}\r\n >\r\n <option value=\"\">All</option>\r\n <option value=\"true\">True</option>\r\n <option value=\"false\">False</option>\r\n </select>\r\n </th>\r\n );\r\n }\r\n\r\n // Date column: from/to inputs\r\n if (column.kind === 'date') {\r\n const fromValue = filterValue?.op === 'range' ? filterValue.value.from ?? '' : '';\r\n const toValue = filterValue?.op === 'range' ? filterValue.value.to ?? '' : '';\r\n \r\n return (\r\n <th key={column.id}>\r\n <div className=\"rowakit-filter-date-range\">\r\n <input\r\n type=\"date\"\r\n className=\"rowakit-filter-input\"\r\n placeholder=\"From\"\r\n value={fromValue}\r\n onChange={(e) => {\r\n const from = e.target.value || undefined;\r\n const to = toValue || undefined;\r\n if (!from && !to) {\r\n handleClearFilter(field);\r\n } else {\r\n handleFilterChange(field, { op: 'range', value: { from, to } });\r\n }\r\n }}\r\n />\r\n <input\r\n type=\"date\"\r\n className=\"rowakit-filter-input\"\r\n placeholder=\"To\"\r\n value={toValue}\r\n onChange={(e) => {\r\n const to = e.target.value || undefined;\r\n const from = fromValue || undefined;\r\n if (!from && !to) {\r\n handleClearFilter(field);\r\n } else {\r\n handleFilterChange(field, { op: 'range', value: { from, to } });\r\n }\r\n }}\r\n />\r\n </div>\r\n </th>\r\n );\r\n }\r\n\r\n // Text/Number column: text or number input\r\n const isNumberColumn = column.kind === 'number';\r\n return (\r\n <th key={column.id}>\r\n <input\r\n type={isNumberColumn ? 'number' : 'text'}\r\n className=\"rowakit-filter-input\"\r\n placeholder={`Filter ${getHeaderLabel(column)}...`}\r\n value={\r\n filterValue?.op === 'contains'\r\n ? filterValue.value\r\n : filterValue?.op === 'equals' && typeof filterValue.value === 'string'\r\n ? filterValue.value\r\n : filterValue?.op === 'equals' && typeof filterValue.value === 'number'\r\n ? String(filterValue.value)\r\n : ''\r\n }\r\n onChange={(e) => {\r\n const rawValue = e.target.value;\r\n if (rawValue === '') {\r\n handleClearFilter(field);\r\n } else if (isNumberColumn) {\r\n const numValue = Number(rawValue);\r\n if (!isNaN(numValue)) {\r\n handleFilterChange(field, { op: 'equals', value: rawValue } as FilterValue);\r\n } else {\r\n // Invalid numeric input: clear the filter to avoid confusing UX\r\n handleClearFilter(field);\r\n }\r\n } else {\r\n // Text: use \"contains\"\r\n handleFilterChange(field, { op: 'contains', value: rawValue } as FilterValue);\r\n }\r\n }}\r\n />\r\n </th>\r\n );\r\n })}\r\n </tr>\r\n )}\r\n </thead>\r\n <tbody>\r\n {isLoading && (\r\n <tr>\r\n <td colSpan={columns.length} className=\"rowakit-table-loading\">\r\n <div className=\"rowakit-table-loading-spinner\"></div>\r\n <span>Loading...</span>\r\n </td>\r\n </tr>\r\n )}\r\n\r\n {isError && (\r\n <tr>\r\n <td colSpan={columns.length} className=\"rowakit-table-error\">\r\n <div className=\"rowakit-table-error-message\">\r\n {dataState.error ?? 'An error occurred'}\r\n </div>\r\n <button\r\n onClick={handleRetry}\r\n className=\"rowakit-button rowakit-button-primary\"\r\n type=\"button\"\r\n >\r\n Retry\r\n </button>\r\n </td>\r\n </tr>\r\n )}\r\n\r\n {isEmpty && (\r\n <tr>\r\n <td colSpan={columns.length} className=\"rowakit-table-empty\">\r\n No data\r\n </td>\r\n </tr>\r\n )}\r\n\r\n {dataState.state === 'success' &&\r\n dataState.items.map((row) => {\r\n const key = getRowKey(row, rowKey);\r\n return (\r\n <tr key={key}>\r\n {columns.map((column) => {\r\n const cellClass = [\r\n column.kind === 'number' ? 'rowakit-cell-number' : '',\r\n column.truncate ? 'rowakit-cell-truncate' : '',\r\n ].filter(Boolean).join(' ') || undefined;\r\n \r\n return (\r\n <td \r\n key={column.id}\r\n className={cellClass}\r\n style={{\r\n width: column.width ? `${column.width}px` : undefined,\r\n textAlign: column.align || (column.kind === 'number' ? 'right' : undefined),\r\n }}\r\n >\r\n {renderCell(column, row, isLoading, setConfirmState)}\r\n </td>\r\n );\r\n })}\r\n </tr>\r\n );\r\n })}\r\n </tbody>\r\n </table>\r\n\r\n {/* Pagination Controls */}\r\n {dataState.total > 0 && (\r\n <div className=\"rowakit-table-pagination\">\r\n {/* Left: Page size selector */}\r\n <div className=\"rowakit-table-pagination-left\">\r\n <label htmlFor=\"page-size\">\r\n Rows per page:\r\n </label>\r\n <select\r\n id=\"page-size\"\r\n value={query.pageSize}\r\n onChange={(e) => handlePageSizeChange(Number(e.target.value))}\r\n disabled={isLoading}\r\n >\r\n {pageSizeOptions.map((size) => (\r\n <option key={size} value={size}>\r\n {size}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n\r\n {/* Center: Page info */}\r\n <div className=\"rowakit-table-pagination-center\">\r\n Page {query.page} of {totalPages} ({dataState.total} total)\r\n </div>\r\n\r\n {/* Right: Previous/Next buttons */}\r\n <div className=\"rowakit-table-pagination-right\">\r\n <button\r\n onClick={handlePreviousPage}\r\n disabled={!canGoPrevious}\r\n className=\"rowakit-button rowakit-button-primary rowakit-button-pagination\"\r\n type=\"button\"\r\n aria-label=\"Previous page\"\r\n >\r\n Previous\r\n </button>\r\n <button\r\n onClick={handleNextPage}\r\n disabled={!canGoNext}\r\n className=\"rowakit-button rowakit-button-primary rowakit-button-pagination\"\r\n type=\"button\"\r\n aria-label=\"Next page\"\r\n >\r\n Next\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Confirmation Modal */}\r\n {confirmState && (\r\n <div\r\n className=\"rowakit-modal-backdrop\"\r\n onClick={() => setConfirmState(null)}\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n aria-labelledby=\"confirm-dialog-title\"\r\n >\r\n <div className=\"rowakit-modal\" onClick={(e) => e.stopPropagation()}>\r\n <h2 id=\"confirm-dialog-title\" className=\"rowakit-modal-title\">\r\n Confirm Action\r\n </h2>\r\n <p className=\"rowakit-modal-content\">\r\n Are you sure you want to {confirmState.action.label.toLowerCase()}? This action cannot be\r\n undone.\r\n </p>\r\n <div className=\"rowakit-modal-actions\">\r\n <button\r\n onClick={() => setConfirmState(null)}\r\n className=\"rowakit-button rowakit-button-secondary\"\r\n type=\"button\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n onClick={() => {\r\n void confirmState.action.onClick(confirmState.row);\r\n setConfirmState(null);\r\n }}\r\n className=\"rowakit-button rowakit-button-danger\"\r\n type=\"button\"\r\n >\r\n Confirm\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n/**\r\n * @deprecated Use RowaKitTable instead. SmartTable is kept as an alias for backward compatibility.\r\n */\r\nexport const SmartTable = RowaKitTable;\r\n","/**\r\n * @rowakit/table\r\n *\r\n * Opinionated, server-side-first table component for internal/business apps.\r\n *\r\n * @packageDocumentation\r\n */\r\n\r\n// Core types\r\nexport type {\r\n // Fetcher types\r\n Fetcher,\r\n FetcherQuery,\r\n FetcherResult,\r\n FilterValue,\r\n Filters,\r\n // Column types\r\n ColumnDef,\r\n ColumnKind,\r\n BaseColumnDef,\r\n TextColumnDef,\r\n DateColumnDef,\r\n BooleanColumnDef,\r\n BadgeColumnDef,\r\n NumberColumnDef,\r\n ActionsColumnDef,\r\n CustomColumnDef,\r\n BadgeTone,\r\n // Action types\r\n ActionDef,\r\n} from './types';\r\n\r\n// Column helper factory\r\nexport { col } from './column-helpers';\r\n\r\n// Components\r\nexport { RowaKitTable, SmartTable } from './components/SmartTable';\r\nexport type { SmartTableProps } from './components/SmartTable';\r\n\r\nexport const VERSION = '0.1.0';\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rowakit/table",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Opinionated, server-side-first table component for internal/business apps",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -64,9 +64,5 @@
64
64
  },
65
65
  "directories": {
66
66
  "example": "examples"
67
- },
68
- "dependencies": {
69
- "react": "^18.0.0",
70
- "react-dom": "^18.0.0"
71
67
  }
72
68
  }